From aa7a6114be2859e8c69d1600b55c91a53e5b288c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Wed, 26 Jul 2023 11:23:48 +0100 Subject: [PATCH 01/24] renamed 'traits' module to 'contract_traits' --- clients/credential/src/client.rs | 2 +- clients/credential/src/commands.rs | 2 +- clients/credential/src/main.rs | 2 +- common/bandwidth-controller/src/acquire/mod.rs | 4 ++-- common/bandwidth-controller/src/lib.rs | 2 +- common/client-core/src/client/base_client/mod.rs | 2 +- common/client-core/src/client/mix_traffic.rs | 2 +- common/client-libs/gateway-client/src/client.rs | 2 +- .../validator-client/examples/query_name_service.rs | 2 +- .../examples/query_service_provider_directory.rs | 2 +- common/client-libs/validator-client/src/client.rs | 2 +- .../validator-client/src/connection_tester.rs | 2 +- .../coconut_bandwidth_query_client.rs | 0 .../coconut_bandwidth_signing_client.rs | 0 .../{traits => contract_traits}/dkg_query_client.rs | 0 .../{traits => contract_traits}/dkg_signing_client.rs | 0 .../{traits => contract_traits}/group_query_client.rs | 0 .../{traits => contract_traits}/mixnet_query_client.rs | 0 .../mixnet_signing_client.rs | 0 .../src/nyxd/{traits => contract_traits}/mod.rs | 0 .../multisig_query_client.rs | 0 .../multisig_signing_client.rs | 0 .../name_service_query_client.rs | 0 .../name_service_signing_client.rs | 0 .../sp_directory_query_client.rs | 0 .../sp_directory_signing_client.rs | 0 .../vesting_query_client.rs | 0 .../vesting_signing_client.rs | 0 common/client-libs/validator-client/src/nyxd/mod.rs | 2 +- .../validator/mixnet/delegators/delegate_to_mixnode.rs | 2 +- .../delegators/rewards/claim_delegator_reward.rs | 2 +- .../rewards/vesting_claim_delegator_reward.rs | 2 +- .../mixnet/delegators/undelegate_from_mixnode.rs | 2 +- .../mixnet/delegators/vesting_delegate_to_mixnode.rs | 4 ++-- .../delegators/vesting_undelegate_from_mixnode.rs | 4 ++-- .../validator/mixnet/operators/gateway/bond_gateway.rs | 2 +- .../operators/gateway/gateway_bonding_sign_payload.rs | 2 +- .../mixnet/operators/gateway/settings/update_config.rs | 2 +- .../gateway/settings/vesting_update_config.rs | 4 ++-- .../mixnet/operators/gateway/unbond_gateway.rs | 2 +- .../mixnet/operators/gateway/vesting_bond_gateway.rs | 2 +- .../mixnet/operators/gateway/vesting_unbond_gateway.rs | 2 +- .../validator/mixnet/operators/mixnode/bond_mixnode.rs | 2 +- .../mixnet/operators/mixnode/decrease_pledge.rs | 2 +- .../mixnet/operators/mixnode/families/create_family.rs | 4 ++-- .../families/create_family_join_permit_sign_payload.rs | 2 +- .../mixnet/operators/mixnode/families/join_family.rs | 4 ++-- .../operators/mixnode/families/kick_family_member.rs | 4 ++-- .../mixnet/operators/mixnode/families/leave_family.rs | 4 ++-- .../operators/mixnode/mixnode_bonding_sign_payload.rs | 2 +- .../validator/mixnet/operators/mixnode/pledge_more.rs | 2 +- .../operators/mixnode/rewards/claim_operator_reward.rs | 2 +- .../mixnode/rewards/vesting_claim_operator_reward.rs | 2 +- .../mixnet/operators/mixnode/settings/update_config.rs | 2 +- .../mixnode/settings/vesting_update_config.rs | 4 ++-- .../mixnet/operators/mixnode/unbond_mixnode.rs | 2 +- .../mixnet/operators/mixnode/vesting_bond_mixnode.rs | 2 +- .../operators/mixnode/vesting_decrease_pledge.rs | 2 +- .../mixnet/operators/mixnode/vesting_pledge_more.rs | 2 +- .../mixnet/operators/mixnode/vesting_unbond_mixnode.rs | 2 +- .../src/validator/mixnet/operators/name/delete.rs | 2 +- .../src/validator/mixnet/operators/name/register.rs | 2 +- .../src/validator/mixnet/operators/service/announce.rs | 2 +- .../mixnet/operators/service/announce_sign_payload.rs | 2 +- .../src/validator/mixnet/operators/service/delete.rs | 2 +- common/commands/src/validator/vesting/balance.rs | 2 +- .../src/validator/vesting/create_vesting_schedule.rs | 2 +- .../src/validator/vesting/query_vesting_schedule.rs | 2 +- .../commands/src/validator/vesting/withdraw_vested.rs | 2 +- .../websocket/connection_handler/coconut.rs | 6 ++++-- nym-api/src/nym_contract_cache/cache/refresher.rs | 2 +- nym-api/src/support/nyxd/mod.rs | 10 ++++------ nym-wallet/src-tauri/src/operations/helpers.rs | 2 +- nym-wallet/src-tauri/src/operations/mixnet/admin.rs | 2 +- nym-wallet/src-tauri/src/operations/mixnet/bond.rs | 2 +- nym-wallet/src-tauri/src/operations/mixnet/delegate.rs | 2 +- nym-wallet/src-tauri/src/operations/mixnet/interval.rs | 2 +- nym-wallet/src-tauri/src/operations/mixnet/rewards.rs | 2 +- nym-wallet/src-tauri/src/operations/vesting/bond.rs | 2 +- .../src-tauri/src/operations/vesting/delegate.rs | 2 +- nym-wallet/src-tauri/src/operations/vesting/queries.rs | 2 +- nym-wallet/src-tauri/src/operations/vesting/rewards.rs | 2 +- nym-wallet/src-tauri/src/utils.rs | 2 +- 83 files changed, 82 insertions(+), 82 deletions(-) rename common/client-libs/validator-client/src/nyxd/{traits => contract_traits}/coconut_bandwidth_query_client.rs (100%) rename common/client-libs/validator-client/src/nyxd/{traits => contract_traits}/coconut_bandwidth_signing_client.rs (100%) rename common/client-libs/validator-client/src/nyxd/{traits => contract_traits}/dkg_query_client.rs (100%) rename common/client-libs/validator-client/src/nyxd/{traits => contract_traits}/dkg_signing_client.rs (100%) rename common/client-libs/validator-client/src/nyxd/{traits => contract_traits}/group_query_client.rs (100%) rename common/client-libs/validator-client/src/nyxd/{traits => contract_traits}/mixnet_query_client.rs (100%) rename common/client-libs/validator-client/src/nyxd/{traits => contract_traits}/mixnet_signing_client.rs (100%) rename common/client-libs/validator-client/src/nyxd/{traits => contract_traits}/mod.rs (100%) rename common/client-libs/validator-client/src/nyxd/{traits => contract_traits}/multisig_query_client.rs (100%) rename common/client-libs/validator-client/src/nyxd/{traits => contract_traits}/multisig_signing_client.rs (100%) rename common/client-libs/validator-client/src/nyxd/{traits => contract_traits}/name_service_query_client.rs (100%) rename common/client-libs/validator-client/src/nyxd/{traits => contract_traits}/name_service_signing_client.rs (100%) rename common/client-libs/validator-client/src/nyxd/{traits => contract_traits}/sp_directory_query_client.rs (100%) rename common/client-libs/validator-client/src/nyxd/{traits => contract_traits}/sp_directory_signing_client.rs (100%) rename common/client-libs/validator-client/src/nyxd/{traits => contract_traits}/vesting_query_client.rs (100%) rename common/client-libs/validator-client/src/nyxd/{traits => contract_traits}/vesting_signing_client.rs (100%) diff --git a/clients/credential/src/client.rs b/clients/credential/src/client.rs index 2db71d8e5e..95b161fb4d 100644 --- a/clients/credential/src/client.rs +++ b/clients/credential/src/client.rs @@ -5,7 +5,7 @@ use crate::error::Result; use bip39::Mnemonic; use nym_network_defaults::{NymNetworkDetails, VOUCHER_INFO}; use nym_validator_client::nyxd; -use nym_validator_client::nyxd::traits::CoconutBandwidthSigningClient; +use nym_validator_client::nyxd::contract_traits::CoconutBandwidthSigningClient; use nym_validator_client::nyxd::{Coin, DirectSigningNyxdClient, Fee, NyxdClient}; use std::str::FromStr; use url::Url; diff --git a/clients/credential/src/commands.rs b/clients/credential/src/commands.rs index 64993d2d7d..da603eb84b 100644 --- a/clients/credential/src/commands.rs +++ b/clients/credential/src/commands.rs @@ -6,7 +6,7 @@ use log::*; use nym_bandwidth_controller::acquire::state::State; use nym_bin_common::completions::ArgShell; use nym_credential_storage::persistent_storage::PersistentStorage; -use nym_validator_client::nyxd::traits::DkgQueryClient; +use nym_validator_client::nyxd::contract_traits::DkgQueryClient; use crate::error::Result; use crate::recovery_storage::RecoveryStorage; diff --git a/clients/credential/src/main.rs b/clients/credential/src/main.rs index e37a825403..a3975c9166 100644 --- a/clients/credential/src/main.rs +++ b/clients/credential/src/main.rs @@ -17,7 +17,7 @@ use std::time::{Duration, SystemTime}; use clap::{CommandFactory, Parser}; use nym_bin_common::logging::setup_logging; use nym_client_core::config::disk_persistence::CommonClientPaths; -use nym_validator_client::nyxd::traits::DkgQueryClient; +use nym_validator_client::nyxd::contract_traits::DkgQueryClient; use nym_validator_client::nyxd::{Coin, CosmWasmClient}; use nym_validator_client::Config; diff --git a/common/bandwidth-controller/src/acquire/mod.rs b/common/bandwidth-controller/src/acquire/mod.rs index cdf72c3b00..04665967ac 100644 --- a/common/bandwidth-controller/src/acquire/mod.rs +++ b/common/bandwidth-controller/src/acquire/mod.rs @@ -8,8 +8,8 @@ use nym_credentials::coconut::bandwidth::{BandwidthVoucher, TOTAL_ATTRIBUTES}; use nym_credentials::coconut::utils::obtain_aggregate_signature; use nym_crypto::asymmetric::{encryption, identity}; use nym_network_defaults::VOUCHER_INFO; -use nym_validator_client::nyxd::traits::CoconutBandwidthSigningClient; -use nym_validator_client::nyxd::traits::DkgQueryClient; +use nym_validator_client::nyxd::contract_traits::CoconutBandwidthSigningClient; +use nym_validator_client::nyxd::contract_traits::DkgQueryClient; use nym_validator_client::nyxd::Coin; use nym_validator_client::nyxd::Hash; use nym_validator_client::CoconutApiClient; diff --git a/common/bandwidth-controller/src/lib.rs b/common/bandwidth-controller/src/lib.rs index 66a6f0a6d2..be4142c60a 100644 --- a/common/bandwidth-controller/src/lib.rs +++ b/common/bandwidth-controller/src/lib.rs @@ -15,7 +15,7 @@ use { }; #[cfg(not(target_arch = "wasm32"))] -use nym_validator_client::nyxd::traits::DkgQueryClient; +use nym_validator_client::nyxd::contract_traits::DkgQueryClient; #[cfg(target_arch = "wasm32")] use crate::wasm_mockups::DkgQueryClient; diff --git a/common/client-core/src/client/base_client/mod.rs b/common/client-core/src/client/base_client/mod.rs index c7e47cab0e..b5c87e2860 100644 --- a/common/client-core/src/client/base_client/mod.rs +++ b/common/client-core/src/client/base_client/mod.rs @@ -52,7 +52,7 @@ use nym_bandwidth_controller::wasm_mockups::DkgQueryClient; use crate::client::base_client::storage::gateway_details::GatewayDetailsStore; use crate::init::{setup_gateway, GatewaySetup, InitialisationDetails, InitialisationResult}; #[cfg(not(target_arch = "wasm32"))] -use nym_validator_client::nyxd::traits::DkgQueryClient; +use nym_validator_client::nyxd::contract_traits::DkgQueryClient; #[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))] pub mod non_wasm_helpers; diff --git a/common/client-core/src/client/mix_traffic.rs b/common/client-core/src/client/mix_traffic.rs index 8e7f7ce2fb..dedb31bc84 100644 --- a/common/client-core/src/client/mix_traffic.rs +++ b/common/client-core/src/client/mix_traffic.rs @@ -8,7 +8,7 @@ use nym_sphinx::forwarding::packet::MixPacket; use nym_credential_storage::storage::Storage; #[cfg(not(target_arch = "wasm32"))] -use nym_validator_client::nyxd::traits::DkgQueryClient; +use nym_validator_client::nyxd::contract_traits::DkgQueryClient; #[cfg(target_arch = "wasm32")] use nym_bandwidth_controller::wasm_mockups::DkgQueryClient; diff --git a/common/client-libs/gateway-client/src/client.rs b/common/client-libs/gateway-client/src/client.rs index b7d9a2c882..0816d26a39 100644 --- a/common/client-libs/gateway-client/src/client.rs +++ b/common/client-libs/gateway-client/src/client.rs @@ -29,7 +29,7 @@ use std::time::Duration; use tungstenite::protocol::Message; #[cfg(not(target_arch = "wasm32"))] -use nym_validator_client::nyxd::traits::DkgQueryClient; +use nym_validator_client::nyxd::contract_traits::DkgQueryClient; #[cfg(not(target_arch = "wasm32"))] use tokio::time::sleep; #[cfg(not(target_arch = "wasm32"))] diff --git a/common/client-libs/validator-client/examples/query_name_service.rs b/common/client-libs/validator-client/examples/query_name_service.rs index 8ea026ce05..5fe5a64c1d 100644 --- a/common/client-libs/validator-client/examples/query_name_service.rs +++ b/common/client-libs/validator-client/examples/query_name_service.rs @@ -3,7 +3,7 @@ use std::str::FromStr; use cosmrs::AccountId; use nym_name_service_common::Address; use nym_network_defaults::{setup_env, NymNetworkDetails}; -use nym_validator_client::nyxd::traits::NameServiceQueryClient; +use nym_validator_client::nyxd::contract_traits::NameServiceQueryClient; #[tokio::main] async fn main() { diff --git a/common/client-libs/validator-client/examples/query_service_provider_directory.rs b/common/client-libs/validator-client/examples/query_service_provider_directory.rs index 12369b2696..797aaae950 100644 --- a/common/client-libs/validator-client/examples/query_service_provider_directory.rs +++ b/common/client-libs/validator-client/examples/query_service_provider_directory.rs @@ -3,7 +3,7 @@ use std::str::FromStr; use cosmrs::AccountId; use nym_network_defaults::{setup_env, NymNetworkDetails}; use nym_service_provider_directory_common::NymAddress; -use nym_validator_client::nyxd::traits::SpDirectoryQueryClient; +use nym_validator_client::nyxd::contract_traits::SpDirectoryQueryClient; #[tokio::main] async fn main() { diff --git a/common/client-libs/validator-client/src/client.rs b/common/client-libs/validator-client/src/client.rs index 54539403fb..70511efe61 100644 --- a/common/client-libs/validator-client/src/client.rs +++ b/common/client-libs/validator-client/src/client.rs @@ -16,7 +16,7 @@ pub use nym_mixnet_contract_common::{ }; use url::Url; -use crate::nyxd::traits::{DkgQueryClient, MixnetQueryClient}; +use crate::nyxd::contract_traits::{DkgQueryClient, MixnetQueryClient}; #[cfg(feature = "http-client")] use crate::nyxd::QueryNyxdClient; use crate::nyxd::{self, CosmWasmClient, NyxdClient}; diff --git a/common/client-libs/validator-client/src/connection_tester.rs b/common/client-libs/validator-client/src/connection_tester.rs index 800399d415..b1d2293850 100644 --- a/common/client-libs/validator-client/src/connection_tester.rs +++ b/common/client-libs/validator-client/src/connection_tester.rs @@ -2,7 +2,7 @@ use crate::nyxd::error::NyxdError; use crate::nyxd::{Config as ClientConfig, NyxdClient, QueryNyxdClient}; use crate::{NymApiClient, ValidatorClientError}; -use crate::nyxd::traits::MixnetQueryClient; +use crate::nyxd::contract_traits::MixnetQueryClient; use colored::Colorize; use core::fmt; use itertools::Itertools; diff --git a/common/client-libs/validator-client/src/nyxd/traits/coconut_bandwidth_query_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/coconut_bandwidth_query_client.rs similarity index 100% rename from common/client-libs/validator-client/src/nyxd/traits/coconut_bandwidth_query_client.rs rename to common/client-libs/validator-client/src/nyxd/contract_traits/coconut_bandwidth_query_client.rs diff --git a/common/client-libs/validator-client/src/nyxd/traits/coconut_bandwidth_signing_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/coconut_bandwidth_signing_client.rs similarity index 100% rename from common/client-libs/validator-client/src/nyxd/traits/coconut_bandwidth_signing_client.rs rename to common/client-libs/validator-client/src/nyxd/contract_traits/coconut_bandwidth_signing_client.rs diff --git a/common/client-libs/validator-client/src/nyxd/traits/dkg_query_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/dkg_query_client.rs similarity index 100% rename from common/client-libs/validator-client/src/nyxd/traits/dkg_query_client.rs rename to common/client-libs/validator-client/src/nyxd/contract_traits/dkg_query_client.rs diff --git a/common/client-libs/validator-client/src/nyxd/traits/dkg_signing_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/dkg_signing_client.rs similarity index 100% rename from common/client-libs/validator-client/src/nyxd/traits/dkg_signing_client.rs rename to common/client-libs/validator-client/src/nyxd/contract_traits/dkg_signing_client.rs diff --git a/common/client-libs/validator-client/src/nyxd/traits/group_query_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/group_query_client.rs similarity index 100% rename from common/client-libs/validator-client/src/nyxd/traits/group_query_client.rs rename to common/client-libs/validator-client/src/nyxd/contract_traits/group_query_client.rs diff --git a/common/client-libs/validator-client/src/nyxd/traits/mixnet_query_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/mixnet_query_client.rs similarity index 100% rename from common/client-libs/validator-client/src/nyxd/traits/mixnet_query_client.rs rename to common/client-libs/validator-client/src/nyxd/contract_traits/mixnet_query_client.rs diff --git a/common/client-libs/validator-client/src/nyxd/traits/mixnet_signing_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/mixnet_signing_client.rs similarity index 100% rename from common/client-libs/validator-client/src/nyxd/traits/mixnet_signing_client.rs rename to common/client-libs/validator-client/src/nyxd/contract_traits/mixnet_signing_client.rs diff --git a/common/client-libs/validator-client/src/nyxd/traits/mod.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/mod.rs similarity index 100% rename from common/client-libs/validator-client/src/nyxd/traits/mod.rs rename to common/client-libs/validator-client/src/nyxd/contract_traits/mod.rs diff --git a/common/client-libs/validator-client/src/nyxd/traits/multisig_query_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/multisig_query_client.rs similarity index 100% rename from common/client-libs/validator-client/src/nyxd/traits/multisig_query_client.rs rename to common/client-libs/validator-client/src/nyxd/contract_traits/multisig_query_client.rs diff --git a/common/client-libs/validator-client/src/nyxd/traits/multisig_signing_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/multisig_signing_client.rs similarity index 100% rename from common/client-libs/validator-client/src/nyxd/traits/multisig_signing_client.rs rename to common/client-libs/validator-client/src/nyxd/contract_traits/multisig_signing_client.rs diff --git a/common/client-libs/validator-client/src/nyxd/traits/name_service_query_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/name_service_query_client.rs similarity index 100% rename from common/client-libs/validator-client/src/nyxd/traits/name_service_query_client.rs rename to common/client-libs/validator-client/src/nyxd/contract_traits/name_service_query_client.rs diff --git a/common/client-libs/validator-client/src/nyxd/traits/name_service_signing_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/name_service_signing_client.rs similarity index 100% rename from common/client-libs/validator-client/src/nyxd/traits/name_service_signing_client.rs rename to common/client-libs/validator-client/src/nyxd/contract_traits/name_service_signing_client.rs diff --git a/common/client-libs/validator-client/src/nyxd/traits/sp_directory_query_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/sp_directory_query_client.rs similarity index 100% rename from common/client-libs/validator-client/src/nyxd/traits/sp_directory_query_client.rs rename to common/client-libs/validator-client/src/nyxd/contract_traits/sp_directory_query_client.rs diff --git a/common/client-libs/validator-client/src/nyxd/traits/sp_directory_signing_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/sp_directory_signing_client.rs similarity index 100% rename from common/client-libs/validator-client/src/nyxd/traits/sp_directory_signing_client.rs rename to common/client-libs/validator-client/src/nyxd/contract_traits/sp_directory_signing_client.rs diff --git a/common/client-libs/validator-client/src/nyxd/traits/vesting_query_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/vesting_query_client.rs similarity index 100% rename from common/client-libs/validator-client/src/nyxd/traits/vesting_query_client.rs rename to common/client-libs/validator-client/src/nyxd/contract_traits/vesting_query_client.rs diff --git a/common/client-libs/validator-client/src/nyxd/traits/vesting_signing_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/vesting_signing_client.rs similarity index 100% rename from common/client-libs/validator-client/src/nyxd/traits/vesting_signing_client.rs rename to common/client-libs/validator-client/src/nyxd/contract_traits/vesting_signing_client.rs diff --git a/common/client-libs/validator-client/src/nyxd/mod.rs b/common/client-libs/validator-client/src/nyxd/mod.rs index 9a4ee1eba4..934aeec8b2 100644 --- a/common/client-libs/validator-client/src/nyxd/mod.rs +++ b/common/client-libs/validator-client/src/nyxd/mod.rs @@ -65,10 +65,10 @@ pub use signing_client::Client as SigningNyxdClient; pub type DirectSigningNyxdClient = SigningNyxdClient; pub mod coin; +pub mod contract_traits; pub mod cosmwasm_client; pub mod error; pub mod fee; -pub mod traits; #[derive(Debug, Clone)] pub struct Config { diff --git a/common/commands/src/validator/mixnet/delegators/delegate_to_mixnode.rs b/common/commands/src/validator/mixnet/delegators/delegate_to_mixnode.rs index f07cd21d5f..54b2516d6e 100644 --- a/common/commands/src/validator/mixnet/delegators/delegate_to_mixnode.rs +++ b/common/commands/src/validator/mixnet/delegators/delegate_to_mixnode.rs @@ -5,7 +5,7 @@ use crate::context::SigningClient; use clap::Parser; use log::info; use nym_mixnet_contract_common::{Coin, MixId}; -use nym_validator_client::nyxd::traits::{MixnetQueryClient, MixnetSigningClient}; +use nym_validator_client::nyxd::contract_traits::{MixnetQueryClient, MixnetSigningClient}; #[derive(Debug, Parser)] pub struct Args { diff --git a/common/commands/src/validator/mixnet/delegators/rewards/claim_delegator_reward.rs b/common/commands/src/validator/mixnet/delegators/rewards/claim_delegator_reward.rs index 61265c9ac5..327a3c0fd3 100644 --- a/common/commands/src/validator/mixnet/delegators/rewards/claim_delegator_reward.rs +++ b/common/commands/src/validator/mixnet/delegators/rewards/claim_delegator_reward.rs @@ -5,7 +5,7 @@ use crate::context::SigningClient; use clap::Parser; use log::info; use nym_mixnet_contract_common::MixId; -use nym_validator_client::nyxd::traits::{MixnetQueryClient, MixnetSigningClient}; +use nym_validator_client::nyxd::contract_traits::{MixnetQueryClient, MixnetSigningClient}; #[derive(Debug, Parser)] pub struct Args { diff --git a/common/commands/src/validator/mixnet/delegators/rewards/vesting_claim_delegator_reward.rs b/common/commands/src/validator/mixnet/delegators/rewards/vesting_claim_delegator_reward.rs index 6d9e0bcbf7..aa6b8dbe44 100644 --- a/common/commands/src/validator/mixnet/delegators/rewards/vesting_claim_delegator_reward.rs +++ b/common/commands/src/validator/mixnet/delegators/rewards/vesting_claim_delegator_reward.rs @@ -5,7 +5,7 @@ use crate::context::SigningClient; use clap::Parser; use log::info; use nym_mixnet_contract_common::MixId; -use nym_validator_client::nyxd::traits::{MixnetQueryClient, MixnetSigningClient}; +use nym_validator_client::nyxd::contract_traits::{MixnetQueryClient, MixnetSigningClient}; #[derive(Debug, Parser)] pub struct Args { diff --git a/common/commands/src/validator/mixnet/delegators/undelegate_from_mixnode.rs b/common/commands/src/validator/mixnet/delegators/undelegate_from_mixnode.rs index 790f518267..cadb6c272f 100644 --- a/common/commands/src/validator/mixnet/delegators/undelegate_from_mixnode.rs +++ b/common/commands/src/validator/mixnet/delegators/undelegate_from_mixnode.rs @@ -5,7 +5,7 @@ use crate::context::SigningClient; use clap::Parser; use log::info; use nym_mixnet_contract_common::MixId; -use nym_validator_client::nyxd::traits::{MixnetQueryClient, MixnetSigningClient}; +use nym_validator_client::nyxd::contract_traits::{MixnetQueryClient, MixnetSigningClient}; #[derive(Debug, Parser)] pub struct Args { diff --git a/common/commands/src/validator/mixnet/delegators/vesting_delegate_to_mixnode.rs b/common/commands/src/validator/mixnet/delegators/vesting_delegate_to_mixnode.rs index 41a992f0ed..45c4ffa5c3 100644 --- a/common/commands/src/validator/mixnet/delegators/vesting_delegate_to_mixnode.rs +++ b/common/commands/src/validator/mixnet/delegators/vesting_delegate_to_mixnode.rs @@ -5,8 +5,8 @@ use clap::Parser; use log::info; use nym_mixnet_contract_common::{Coin, MixId}; -use nym_validator_client::nyxd::traits::MixnetQueryClient; -use nym_validator_client::nyxd::traits::VestingSigningClient; +use nym_validator_client::nyxd::contract_traits::MixnetQueryClient; +use nym_validator_client::nyxd::contract_traits::VestingSigningClient; use crate::context::SigningClient; diff --git a/common/commands/src/validator/mixnet/delegators/vesting_undelegate_from_mixnode.rs b/common/commands/src/validator/mixnet/delegators/vesting_undelegate_from_mixnode.rs index 42493f493d..13bae0b7a0 100644 --- a/common/commands/src/validator/mixnet/delegators/vesting_undelegate_from_mixnode.rs +++ b/common/commands/src/validator/mixnet/delegators/vesting_undelegate_from_mixnode.rs @@ -4,8 +4,8 @@ use clap::Parser; use log::info; use nym_mixnet_contract_common::MixId; -use nym_validator_client::nyxd::traits::MixnetQueryClient; -use nym_validator_client::nyxd::traits::VestingSigningClient; +use nym_validator_client::nyxd::contract_traits::MixnetQueryClient; +use nym_validator_client::nyxd::contract_traits::VestingSigningClient; use crate::context::SigningClient; diff --git a/common/commands/src/validator/mixnet/operators/gateway/bond_gateway.rs b/common/commands/src/validator/mixnet/operators/gateway/bond_gateway.rs index 76b6e93fa0..28fe160070 100644 --- a/common/commands/src/validator/mixnet/operators/gateway/bond_gateway.rs +++ b/common/commands/src/validator/mixnet/operators/gateway/bond_gateway.rs @@ -7,7 +7,7 @@ use log::{info, warn}; use nym_contracts_common::signing::MessageSignature; use nym_mixnet_contract_common::Coin; use nym_network_defaults::{DEFAULT_CLIENT_LISTENING_PORT, DEFAULT_MIX_LISTENING_PORT}; -use nym_validator_client::nyxd::traits::MixnetSigningClient; +use nym_validator_client::nyxd::contract_traits::MixnetSigningClient; #[derive(Debug, Parser)] pub struct Args { diff --git a/common/commands/src/validator/mixnet/operators/gateway/gateway_bonding_sign_payload.rs b/common/commands/src/validator/mixnet/operators/gateway/gateway_bonding_sign_payload.rs index ff4f8eaf32..9bc24ea0e0 100644 --- a/common/commands/src/validator/mixnet/operators/gateway/gateway_bonding_sign_payload.rs +++ b/common/commands/src/validator/mixnet/operators/gateway/gateway_bonding_sign_payload.rs @@ -8,7 +8,7 @@ use cosmwasm_std::Coin; use nym_bin_common::output_format::OutputFormat; use nym_mixnet_contract_common::construct_gateway_bonding_sign_payload; use nym_network_defaults::{DEFAULT_CLIENT_LISTENING_PORT, DEFAULT_MIX_LISTENING_PORT}; -use nym_validator_client::nyxd::traits::MixnetQueryClient; +use nym_validator_client::nyxd::contract_traits::MixnetQueryClient; #[derive(Debug, Parser)] pub struct Args { diff --git a/common/commands/src/validator/mixnet/operators/gateway/settings/update_config.rs b/common/commands/src/validator/mixnet/operators/gateway/settings/update_config.rs index cce3d26dfe..9b6cd07da3 100644 --- a/common/commands/src/validator/mixnet/operators/gateway/settings/update_config.rs +++ b/common/commands/src/validator/mixnet/operators/gateway/settings/update_config.rs @@ -5,7 +5,7 @@ use crate::context::SigningClient; use clap::Parser; use log::info; use nym_mixnet_contract_common::GatewayConfigUpdate; -use nym_validator_client::nyxd::traits::{MixnetQueryClient, MixnetSigningClient}; +use nym_validator_client::nyxd::contract_traits::{MixnetQueryClient, MixnetSigningClient}; #[derive(Debug, Parser)] pub struct Args { diff --git a/common/commands/src/validator/mixnet/operators/gateway/settings/vesting_update_config.rs b/common/commands/src/validator/mixnet/operators/gateway/settings/vesting_update_config.rs index e734ddc97d..75aed1349d 100644 --- a/common/commands/src/validator/mixnet/operators/gateway/settings/vesting_update_config.rs +++ b/common/commands/src/validator/mixnet/operators/gateway/settings/vesting_update_config.rs @@ -5,8 +5,8 @@ use crate::context::SigningClient; use clap::Parser; use log::info; use nym_mixnet_contract_common::GatewayConfigUpdate; -use nym_validator_client::nyxd::traits::MixnetQueryClient; -use nym_validator_client::nyxd::traits::VestingSigningClient; +use nym_validator_client::nyxd::contract_traits::MixnetQueryClient; +use nym_validator_client::nyxd::contract_traits::VestingSigningClient; #[derive(Debug, Parser)] pub struct Args { diff --git a/common/commands/src/validator/mixnet/operators/gateway/unbond_gateway.rs b/common/commands/src/validator/mixnet/operators/gateway/unbond_gateway.rs index 7603db1a6e..af9c6c8bb4 100644 --- a/common/commands/src/validator/mixnet/operators/gateway/unbond_gateway.rs +++ b/common/commands/src/validator/mixnet/operators/gateway/unbond_gateway.rs @@ -4,7 +4,7 @@ use crate::context::SigningClient; use clap::Parser; use log::info; -use nym_validator_client::nyxd::traits::MixnetSigningClient; +use nym_validator_client::nyxd::contract_traits::MixnetSigningClient; #[derive(Debug, Parser)] pub struct Args {} diff --git a/common/commands/src/validator/mixnet/operators/gateway/vesting_bond_gateway.rs b/common/commands/src/validator/mixnet/operators/gateway/vesting_bond_gateway.rs index 21f771c0b3..91c2817be8 100644 --- a/common/commands/src/validator/mixnet/operators/gateway/vesting_bond_gateway.rs +++ b/common/commands/src/validator/mixnet/operators/gateway/vesting_bond_gateway.rs @@ -7,7 +7,7 @@ use log::{info, warn}; use nym_contracts_common::signing::MessageSignature; use nym_mixnet_contract_common::{Coin, Gateway}; use nym_network_defaults::{DEFAULT_CLIENT_LISTENING_PORT, DEFAULT_MIX_LISTENING_PORT}; -use nym_validator_client::nyxd::traits::VestingSigningClient; +use nym_validator_client::nyxd::contract_traits::VestingSigningClient; #[derive(Debug, Parser)] pub struct Args { diff --git a/common/commands/src/validator/mixnet/operators/gateway/vesting_unbond_gateway.rs b/common/commands/src/validator/mixnet/operators/gateway/vesting_unbond_gateway.rs index 8e79dd7bc7..1c4312424c 100644 --- a/common/commands/src/validator/mixnet/operators/gateway/vesting_unbond_gateway.rs +++ b/common/commands/src/validator/mixnet/operators/gateway/vesting_unbond_gateway.rs @@ -4,7 +4,7 @@ use crate::context::SigningClient; use clap::Parser; use log::info; -use nym_validator_client::nyxd::traits::MixnetSigningClient; +use nym_validator_client::nyxd::contract_traits::MixnetSigningClient; #[derive(Debug, Parser)] pub struct Args {} diff --git a/common/commands/src/validator/mixnet/operators/mixnode/bond_mixnode.rs b/common/commands/src/validator/mixnet/operators/mixnode/bond_mixnode.rs index 8fe6bb8040..862a797566 100644 --- a/common/commands/src/validator/mixnet/operators/mixnode/bond_mixnode.rs +++ b/common/commands/src/validator/mixnet/operators/mixnode/bond_mixnode.rs @@ -10,7 +10,7 @@ use nym_mixnet_contract_common::{Coin, MixNodeCostParams, Percent}; use nym_network_defaults::{ DEFAULT_HTTP_API_LISTENING_PORT, DEFAULT_MIX_LISTENING_PORT, DEFAULT_VERLOC_LISTENING_PORT, }; -use nym_validator_client::nyxd::traits::MixnetSigningClient; +use nym_validator_client::nyxd::contract_traits::MixnetSigningClient; use nym_validator_client::nyxd::CosmWasmCoin; use crate::context::SigningClient; diff --git a/common/commands/src/validator/mixnet/operators/mixnode/decrease_pledge.rs b/common/commands/src/validator/mixnet/operators/mixnode/decrease_pledge.rs index 969e40024a..556021dcf9 100644 --- a/common/commands/src/validator/mixnet/operators/mixnode/decrease_pledge.rs +++ b/common/commands/src/validator/mixnet/operators/mixnode/decrease_pledge.rs @@ -5,7 +5,7 @@ use crate::context::SigningClient; use clap::Parser; use log::info; use nym_mixnet_contract_common::Coin; -use nym_validator_client::nyxd::traits::MixnetSigningClient; +use nym_validator_client::nyxd::contract_traits::MixnetSigningClient; #[derive(Debug, Parser)] pub struct Args { diff --git a/common/commands/src/validator/mixnet/operators/mixnode/families/create_family.rs b/common/commands/src/validator/mixnet/operators/mixnode/families/create_family.rs index f5ff9e3419..6acaca80d2 100644 --- a/common/commands/src/validator/mixnet/operators/mixnode/families/create_family.rs +++ b/common/commands/src/validator/mixnet/operators/mixnode/families/create_family.rs @@ -4,8 +4,8 @@ use crate::context::SigningClient; use clap::Parser; use log::info; -use nym_validator_client::nyxd::traits::MixnetSigningClient; -use nym_validator_client::nyxd::traits::VestingSigningClient; +use nym_validator_client::nyxd::contract_traits::MixnetSigningClient; +use nym_validator_client::nyxd::contract_traits::VestingSigningClient; #[derive(Debug, Parser)] pub struct Args { diff --git a/common/commands/src/validator/mixnet/operators/mixnode/families/create_family_join_permit_sign_payload.rs b/common/commands/src/validator/mixnet/operators/mixnode/families/create_family_join_permit_sign_payload.rs index 7b02731b30..9293f7188f 100644 --- a/common/commands/src/validator/mixnet/operators/mixnode/families/create_family_join_permit_sign_payload.rs +++ b/common/commands/src/validator/mixnet/operators/mixnode/families/create_family_join_permit_sign_payload.rs @@ -10,7 +10,7 @@ use nym_bin_common::output_format::OutputFormat; use nym_crypto::asymmetric::identity; use nym_mixnet_contract_common::construct_family_join_permit; use nym_mixnet_contract_common::families::FamilyHead; -use nym_validator_client::nyxd::traits::MixnetQueryClient; +use nym_validator_client::nyxd::contract_traits::MixnetQueryClient; #[derive(Debug, Parser)] pub struct Args { diff --git a/common/commands/src/validator/mixnet/operators/mixnode/families/join_family.rs b/common/commands/src/validator/mixnet/operators/mixnode/families/join_family.rs index b69dd7a4b2..411a8412b7 100644 --- a/common/commands/src/validator/mixnet/operators/mixnode/families/join_family.rs +++ b/common/commands/src/validator/mixnet/operators/mixnode/families/join_family.rs @@ -7,8 +7,8 @@ use log::info; use nym_contracts_common::signing::MessageSignature; use nym_crypto::asymmetric::identity; use nym_mixnet_contract_common::families::FamilyHead; -use nym_validator_client::nyxd::traits::MixnetSigningClient; -use nym_validator_client::nyxd::traits::VestingSigningClient; +use nym_validator_client::nyxd::contract_traits::MixnetSigningClient; +use nym_validator_client::nyxd::contract_traits::VestingSigningClient; #[derive(Debug, Parser)] pub struct Args { diff --git a/common/commands/src/validator/mixnet/operators/mixnode/families/kick_family_member.rs b/common/commands/src/validator/mixnet/operators/mixnode/families/kick_family_member.rs index 9305c56918..27b5d71d7d 100644 --- a/common/commands/src/validator/mixnet/operators/mixnode/families/kick_family_member.rs +++ b/common/commands/src/validator/mixnet/operators/mixnode/families/kick_family_member.rs @@ -5,8 +5,8 @@ use crate::context::SigningClient; use clap::Parser; use log::info; use nym_crypto::asymmetric::identity; -use nym_validator_client::nyxd::traits::MixnetSigningClient; -use nym_validator_client::nyxd::traits::VestingSigningClient; +use nym_validator_client::nyxd::contract_traits::MixnetSigningClient; +use nym_validator_client::nyxd::contract_traits::VestingSigningClient; #[derive(Debug, Parser)] pub struct Args { diff --git a/common/commands/src/validator/mixnet/operators/mixnode/families/leave_family.rs b/common/commands/src/validator/mixnet/operators/mixnode/families/leave_family.rs index 193c003ab4..0673be508a 100644 --- a/common/commands/src/validator/mixnet/operators/mixnode/families/leave_family.rs +++ b/common/commands/src/validator/mixnet/operators/mixnode/families/leave_family.rs @@ -6,8 +6,8 @@ use clap::Parser; use log::info; use nym_crypto::asymmetric::identity; use nym_mixnet_contract_common::families::FamilyHead; -use nym_validator_client::nyxd::traits::MixnetSigningClient; -use nym_validator_client::nyxd::traits::VestingSigningClient; +use nym_validator_client::nyxd::contract_traits::MixnetSigningClient; +use nym_validator_client::nyxd::contract_traits::VestingSigningClient; #[derive(Debug, Parser)] pub struct Args { diff --git a/common/commands/src/validator/mixnet/operators/mixnode/mixnode_bonding_sign_payload.rs b/common/commands/src/validator/mixnet/operators/mixnode/mixnode_bonding_sign_payload.rs index b44d159398..4eacdcf4b4 100644 --- a/common/commands/src/validator/mixnet/operators/mixnode/mixnode_bonding_sign_payload.rs +++ b/common/commands/src/validator/mixnet/operators/mixnode/mixnode_bonding_sign_payload.rs @@ -11,7 +11,7 @@ use nym_mixnet_contract_common::{construct_mixnode_bonding_sign_payload, MixNode use nym_network_defaults::{ DEFAULT_HTTP_API_LISTENING_PORT, DEFAULT_MIX_LISTENING_PORT, DEFAULT_VERLOC_LISTENING_PORT, }; -use nym_validator_client::nyxd::traits::MixnetQueryClient; +use nym_validator_client::nyxd::contract_traits::MixnetQueryClient; use nym_validator_client::nyxd::CosmWasmCoin; #[derive(Debug, Parser)] diff --git a/common/commands/src/validator/mixnet/operators/mixnode/pledge_more.rs b/common/commands/src/validator/mixnet/operators/mixnode/pledge_more.rs index 1fbf38eb0c..1989725907 100644 --- a/common/commands/src/validator/mixnet/operators/mixnode/pledge_more.rs +++ b/common/commands/src/validator/mixnet/operators/mixnode/pledge_more.rs @@ -5,7 +5,7 @@ use crate::context::SigningClient; use clap::Parser; use log::info; use nym_mixnet_contract_common::Coin; -use nym_validator_client::nyxd::traits::MixnetSigningClient; +use nym_validator_client::nyxd::contract_traits::MixnetSigningClient; #[derive(Debug, Parser)] pub struct Args { diff --git a/common/commands/src/validator/mixnet/operators/mixnode/rewards/claim_operator_reward.rs b/common/commands/src/validator/mixnet/operators/mixnode/rewards/claim_operator_reward.rs index 729a5e8c03..a5f8d65236 100644 --- a/common/commands/src/validator/mixnet/operators/mixnode/rewards/claim_operator_reward.rs +++ b/common/commands/src/validator/mixnet/operators/mixnode/rewards/claim_operator_reward.rs @@ -4,7 +4,7 @@ use crate::context::SigningClient; use clap::Parser; use log::info; -use nym_validator_client::nyxd::traits::MixnetSigningClient; +use nym_validator_client::nyxd::contract_traits::MixnetSigningClient; #[derive(Debug, Parser)] pub struct Args {} diff --git a/common/commands/src/validator/mixnet/operators/mixnode/rewards/vesting_claim_operator_reward.rs b/common/commands/src/validator/mixnet/operators/mixnode/rewards/vesting_claim_operator_reward.rs index 8c1d43e091..3b88c6cf5c 100644 --- a/common/commands/src/validator/mixnet/operators/mixnode/rewards/vesting_claim_operator_reward.rs +++ b/common/commands/src/validator/mixnet/operators/mixnode/rewards/vesting_claim_operator_reward.rs @@ -4,7 +4,7 @@ use crate::context::SigningClient; use clap::Parser; use log::info; -use nym_validator_client::nyxd::traits::MixnetSigningClient; +use nym_validator_client::nyxd::contract_traits::MixnetSigningClient; #[derive(Debug, Parser)] pub struct Args { diff --git a/common/commands/src/validator/mixnet/operators/mixnode/settings/update_config.rs b/common/commands/src/validator/mixnet/operators/mixnode/settings/update_config.rs index 69fd8531be..dd7524bfdf 100644 --- a/common/commands/src/validator/mixnet/operators/mixnode/settings/update_config.rs +++ b/common/commands/src/validator/mixnet/operators/mixnode/settings/update_config.rs @@ -5,7 +5,7 @@ use crate::context::SigningClient; use clap::Parser; use log::info; use nym_mixnet_contract_common::MixNodeConfigUpdate; -use nym_validator_client::nyxd::traits::{MixnetQueryClient, MixnetSigningClient}; +use nym_validator_client::nyxd::contract_traits::{MixnetQueryClient, MixnetSigningClient}; #[derive(Debug, Parser)] pub struct Args { diff --git a/common/commands/src/validator/mixnet/operators/mixnode/settings/vesting_update_config.rs b/common/commands/src/validator/mixnet/operators/mixnode/settings/vesting_update_config.rs index 5b956b929f..c7d1c96c01 100644 --- a/common/commands/src/validator/mixnet/operators/mixnode/settings/vesting_update_config.rs +++ b/common/commands/src/validator/mixnet/operators/mixnode/settings/vesting_update_config.rs @@ -5,8 +5,8 @@ use crate::context::SigningClient; use clap::Parser; use log::info; use nym_mixnet_contract_common::MixNodeConfigUpdate; -use nym_validator_client::nyxd::traits::MixnetQueryClient; -use nym_validator_client::nyxd::traits::VestingSigningClient; +use nym_validator_client::nyxd::contract_traits::MixnetQueryClient; +use nym_validator_client::nyxd::contract_traits::VestingSigningClient; #[derive(Debug, Parser)] pub struct Args { diff --git a/common/commands/src/validator/mixnet/operators/mixnode/unbond_mixnode.rs b/common/commands/src/validator/mixnet/operators/mixnode/unbond_mixnode.rs index ecfc3652e1..fe6f3df223 100644 --- a/common/commands/src/validator/mixnet/operators/mixnode/unbond_mixnode.rs +++ b/common/commands/src/validator/mixnet/operators/mixnode/unbond_mixnode.rs @@ -3,7 +3,7 @@ use clap::Parser; use log::info; -use nym_validator_client::nyxd::traits::MixnetSigningClient; +use nym_validator_client::nyxd::contract_traits::MixnetSigningClient; use crate::context::SigningClient; diff --git a/common/commands/src/validator/mixnet/operators/mixnode/vesting_bond_mixnode.rs b/common/commands/src/validator/mixnet/operators/mixnode/vesting_bond_mixnode.rs index 9928dec18f..415f9fe2b3 100644 --- a/common/commands/src/validator/mixnet/operators/mixnode/vesting_bond_mixnode.rs +++ b/common/commands/src/validator/mixnet/operators/mixnode/vesting_bond_mixnode.rs @@ -11,7 +11,7 @@ use nym_mixnet_contract_common::{MixNode, Percent}; use nym_network_defaults::{ DEFAULT_HTTP_API_LISTENING_PORT, DEFAULT_MIX_LISTENING_PORT, DEFAULT_VERLOC_LISTENING_PORT, }; -use nym_validator_client::nyxd::{traits::VestingSigningClient, CosmWasmCoin}; +use nym_validator_client::nyxd::{contract_traits::VestingSigningClient, CosmWasmCoin}; #[derive(Debug, Parser)] pub struct Args { diff --git a/common/commands/src/validator/mixnet/operators/mixnode/vesting_decrease_pledge.rs b/common/commands/src/validator/mixnet/operators/mixnode/vesting_decrease_pledge.rs index d38d7f61dc..bb83e1ffaa 100644 --- a/common/commands/src/validator/mixnet/operators/mixnode/vesting_decrease_pledge.rs +++ b/common/commands/src/validator/mixnet/operators/mixnode/vesting_decrease_pledge.rs @@ -5,7 +5,7 @@ use crate::context::SigningClient; use clap::Parser; use log::info; use nym_mixnet_contract_common::Coin; -use nym_validator_client::nyxd::traits::VestingSigningClient; +use nym_validator_client::nyxd::contract_traits::VestingSigningClient; #[derive(Debug, Parser)] pub struct Args { diff --git a/common/commands/src/validator/mixnet/operators/mixnode/vesting_pledge_more.rs b/common/commands/src/validator/mixnet/operators/mixnode/vesting_pledge_more.rs index 0774fd89d6..9917e02860 100644 --- a/common/commands/src/validator/mixnet/operators/mixnode/vesting_pledge_more.rs +++ b/common/commands/src/validator/mixnet/operators/mixnode/vesting_pledge_more.rs @@ -4,7 +4,7 @@ use clap::Parser; use log::info; use nym_mixnet_contract_common::Coin; -use nym_validator_client::nyxd::traits::VestingSigningClient; +use nym_validator_client::nyxd::contract_traits::VestingSigningClient; use crate::context::SigningClient; diff --git a/common/commands/src/validator/mixnet/operators/mixnode/vesting_unbond_mixnode.rs b/common/commands/src/validator/mixnet/operators/mixnode/vesting_unbond_mixnode.rs index 49f717a5af..3e63846430 100644 --- a/common/commands/src/validator/mixnet/operators/mixnode/vesting_unbond_mixnode.rs +++ b/common/commands/src/validator/mixnet/operators/mixnode/vesting_unbond_mixnode.rs @@ -4,7 +4,7 @@ use crate::context::SigningClient; use clap::Parser; use log::info; -use nym_validator_client::nyxd::traits::VestingSigningClient; +use nym_validator_client::nyxd::contract_traits::VestingSigningClient; #[derive(Debug, Parser)] pub struct Args { diff --git a/common/commands/src/validator/mixnet/operators/name/delete.rs b/common/commands/src/validator/mixnet/operators/name/delete.rs index 558dbf190c..d93b432108 100644 --- a/common/commands/src/validator/mixnet/operators/name/delete.rs +++ b/common/commands/src/validator/mixnet/operators/name/delete.rs @@ -1,7 +1,7 @@ use clap::Parser; use log::{error, info}; use nym_name_service_common::NameId; -use nym_validator_client::nyxd::{error::NyxdError, traits::NameServiceSigningClient}; +use nym_validator_client::nyxd::{contract_traits::NameServiceSigningClient, error::NyxdError}; use tap::TapFallible; use crate::context::SigningClient; diff --git a/common/commands/src/validator/mixnet/operators/name/register.rs b/common/commands/src/validator/mixnet/operators/name/register.rs index 85afd3012a..54a4b1a20d 100644 --- a/common/commands/src/validator/mixnet/operators/name/register.rs +++ b/common/commands/src/validator/mixnet/operators/name/register.rs @@ -3,7 +3,7 @@ use log::{error, info}; use nym_contracts_common::signing::MessageSignature; use nym_name_service_common::{Address, Coin, NameDetails, NymName}; use nym_sphinx::addressing::clients::Recipient; -use nym_validator_client::nyxd::{error::NyxdError, traits::NameServiceSigningClient}; +use nym_validator_client::nyxd::{contract_traits::NameServiceSigningClient, error::NyxdError}; use tap::TapFallible; use crate::context::SigningClient; diff --git a/common/commands/src/validator/mixnet/operators/service/announce.rs b/common/commands/src/validator/mixnet/operators/service/announce.rs index a3e86bc674..b61652254e 100644 --- a/common/commands/src/validator/mixnet/operators/service/announce.rs +++ b/common/commands/src/validator/mixnet/operators/service/announce.rs @@ -2,7 +2,7 @@ use clap::Parser; use log::info; use nym_contracts_common::signing::MessageSignature; use nym_service_provider_directory_common::{Coin, NymAddress, ServiceDetails, ServiceType}; -use nym_validator_client::nyxd::traits::SpDirectorySigningClient; +use nym_validator_client::nyxd::contract_traits::SpDirectorySigningClient; use crate::context::SigningClient; diff --git a/common/commands/src/validator/mixnet/operators/service/announce_sign_payload.rs b/common/commands/src/validator/mixnet/operators/service/announce_sign_payload.rs index f8ac587f9b..bda4e56b9d 100644 --- a/common/commands/src/validator/mixnet/operators/service/announce_sign_payload.rs +++ b/common/commands/src/validator/mixnet/operators/service/announce_sign_payload.rs @@ -15,7 +15,7 @@ use nym_service_provider_directory_common::{ ServiceType::NetworkRequester, }; use nym_sphinx::addressing::clients::Recipient; -use nym_validator_client::nyxd::traits::SpDirectoryQueryClient; +use nym_validator_client::nyxd::contract_traits::SpDirectoryQueryClient; #[derive(Debug, Parser)] pub struct Args { diff --git a/common/commands/src/validator/mixnet/operators/service/delete.rs b/common/commands/src/validator/mixnet/operators/service/delete.rs index eb86f4028f..3d0ca4a676 100644 --- a/common/commands/src/validator/mixnet/operators/service/delete.rs +++ b/common/commands/src/validator/mixnet/operators/service/delete.rs @@ -1,7 +1,7 @@ use clap::Parser; use log::info; use nym_service_provider_directory_common::ServiceId; -use nym_validator_client::nyxd::traits::SpDirectorySigningClient; +use nym_validator_client::nyxd::contract_traits::SpDirectorySigningClient; use crate::context::SigningClient; diff --git a/common/commands/src/validator/vesting/balance.rs b/common/commands/src/validator/vesting/balance.rs index d5f5af20fe..8208e1e2e4 100644 --- a/common/commands/src/validator/vesting/balance.rs +++ b/common/commands/src/validator/vesting/balance.rs @@ -5,7 +5,7 @@ use clap::Parser; use cosmrs::AccountId; use log::{error, info}; -use nym_validator_client::nyxd::{traits::VestingQueryClient, Coin}; +use nym_validator_client::nyxd::{contract_traits::VestingQueryClient, Coin}; use crate::context::QueryClient; use crate::utils::show_error; diff --git a/common/commands/src/validator/vesting/create_vesting_schedule.rs b/common/commands/src/validator/vesting/create_vesting_schedule.rs index f7397bf14c..151350bf2c 100644 --- a/common/commands/src/validator/vesting/create_vesting_schedule.rs +++ b/common/commands/src/validator/vesting/create_vesting_schedule.rs @@ -8,7 +8,7 @@ use log::info; use nym_mixnet_contract_common::Coin; use nym_network_defaults::NymNetworkDetails; -use nym_validator_client::nyxd::traits::VestingSigningClient; +use nym_validator_client::nyxd::contract_traits::VestingSigningClient; use nym_validator_client::nyxd::AccountId; use nym_validator_client::nyxd::{CosmosCoin, Denom}; use nym_vesting_contract_common::types::VestingSpecification; diff --git a/common/commands/src/validator/vesting/query_vesting_schedule.rs b/common/commands/src/validator/vesting/query_vesting_schedule.rs index 9c8facfb70..5c8b0bf153 100644 --- a/common/commands/src/validator/vesting/query_vesting_schedule.rs +++ b/common/commands/src/validator/vesting/query_vesting_schedule.rs @@ -6,7 +6,7 @@ use cosmrs::AccountId; use cosmwasm_std::Coin as CosmWasmCoin; use log::{error, info}; -use nym_validator_client::nyxd::{traits::VestingQueryClient, Coin}; +use nym_validator_client::nyxd::{contract_traits::VestingQueryClient, Coin}; use crate::context::QueryClient; use crate::utils::show_error; diff --git a/common/commands/src/validator/vesting/withdraw_vested.rs b/common/commands/src/validator/vesting/withdraw_vested.rs index a85e960a1a..8a0c3f3f9c 100644 --- a/common/commands/src/validator/vesting/withdraw_vested.rs +++ b/common/commands/src/validator/vesting/withdraw_vested.rs @@ -5,7 +5,7 @@ use clap::Parser; use log::info; use nym_validator_client::nyxd::{ - traits::{VestingQueryClient, VestingSigningClient}, + contract_traits::{VestingQueryClient, VestingSigningClient}, Coin, }; diff --git a/gateway/src/node/client_handling/websocket/connection_handler/coconut.rs b/gateway/src/node/client_handling/websocket/connection_handler/coconut.rs index e19f4a14fe..8d2dcbebb6 100644 --- a/gateway/src/node/client_handling/websocket/connection_handler/coconut.rs +++ b/gateway/src/node/client_handling/websocket/connection_handler/coconut.rs @@ -4,11 +4,13 @@ use super::authenticated::RequestHandlingError; use log::*; use nym_coconut_interface::Credential; -use nym_validator_client::nyxd::traits::DkgQueryClient; use nym_validator_client::{ nyxd::{ + contract_traits::{ + CoconutBandwidthSigningClient, DkgQueryClient, MultisigQueryClient, + MultisigSigningClient, + }, cosmwasm_client::logs::{find_attribute, BANDWIDTH_PROPOSAL_ID}, - traits::{CoconutBandwidthSigningClient, MultisigQueryClient, MultisigSigningClient}, Coin, DirectSigningNyxdClient, Fee, }, Client, CoconutApiClient, diff --git a/nym-api/src/nym_contract_cache/cache/refresher.rs b/nym-api/src/nym_contract_cache/cache/refresher.rs index 93ddabf3a1..7df88a225f 100644 --- a/nym-api/src/nym_contract_cache/cache/refresher.rs +++ b/nym-api/src/nym_contract_cache/cache/refresher.rs @@ -4,7 +4,7 @@ use crate::support::caching::CacheNotification; use anyhow::Result; use nym_mixnet_contract_common::{MixId, MixNodeDetails, RewardedSetNodeStatus}; use nym_task::TaskClient; -use nym_validator_client::nyxd::traits::{NameServiceQueryClient, SpDirectoryQueryClient}; +use nym_validator_client::nyxd::contract_traits::{NameServiceQueryClient, SpDirectoryQueryClient}; use std::{collections::HashMap, sync::atomic::Ordering, time::Duration}; use tokio::sync::watch; use tokio::time; diff --git a/nym-api/src/support/nyxd/mod.rs b/nym-api/src/support/nyxd/mod.rs index e35098ee1f..b3aa95b209 100644 --- a/nym-api/src/support/nyxd/mod.rs +++ b/nym-api/src/support/nyxd/mod.rs @@ -28,15 +28,13 @@ use nym_mixnet_contract_common::{ use nym_name_service_common::msg::QueryMsg as NameServiceQueryMsg; use nym_service_provider_directory_common::msg::QueryMsg as SpQueryMsg; use nym_validator_client::nyxd::error::NyxdError; -use nym_validator_client::nyxd::traits::{ - MixnetQueryClient, MixnetSigningClient, SpDirectoryQueryClient, -}; use nym_validator_client::nyxd::{ - cosmwasm_client::types::ExecuteResult, - traits::{ + contract_traits::{ CoconutBandwidthQueryClient, DkgQueryClient, DkgSigningClient, GroupQueryClient, - MultisigQueryClient, MultisigSigningClient, NameServiceQueryClient, VestingQueryClient, + MixnetQueryClient, MixnetSigningClient, MultisigQueryClient, MultisigSigningClient, + NameServiceQueryClient, SpDirectoryQueryClient, VestingQueryClient, }, + cosmwasm_client::types::ExecuteResult, Fee, }; use nym_validator_client::nyxd::{ diff --git a/nym-wallet/src-tauri/src/operations/helpers.rs b/nym-wallet/src-tauri/src/operations/helpers.rs index 57fcb5d1bb..35e59cca25 100644 --- a/nym-wallet/src-tauri/src/operations/helpers.rs +++ b/nym-wallet/src-tauri/src/operations/helpers.rs @@ -12,8 +12,8 @@ use nym_mixnet_contract_common::{ construct_mixnode_bonding_sign_payload, Gateway, GatewayBondingPayload, MixNode, MixNodeCostParams, SignableGatewayBondingMsg, SignableMixNodeBondingMsg, }; +use nym_validator_client::nyxd::contract_traits::MixnetQueryClient; use nym_validator_client::nyxd::error::NyxdError; -use nym_validator_client::nyxd::traits::MixnetQueryClient; use nym_validator_client::nyxd::{Coin, DirectSigningNyxdClient}; use nym_validator_client::Client; diff --git a/nym-wallet/src-tauri/src/operations/mixnet/admin.rs b/nym-wallet/src-tauri/src/operations/mixnet/admin.rs index d8824e41d8..2670ff360c 100644 --- a/nym-wallet/src-tauri/src/operations/mixnet/admin.rs +++ b/nym-wallet/src-tauri/src/operations/mixnet/admin.rs @@ -5,7 +5,7 @@ use crate::error::BackendError; use crate::state::WalletState; use nym_mixnet_contract_common::ContractStateParams; use nym_types::transaction::TransactionExecuteResult; -use nym_validator_client::nyxd::traits::{MixnetQueryClient, MixnetSigningClient}; +use nym_validator_client::nyxd::contract_traits::{MixnetQueryClient, MixnetSigningClient}; use nym_validator_client::nyxd::Fee; use nym_wallet_types::admin::TauriContractStateParams; diff --git a/nym-wallet/src-tauri/src/operations/mixnet/bond.rs b/nym-wallet/src-tauri/src/operations/mixnet/bond.rs index 4acd1aecfc..94ce11a815 100644 --- a/nym-wallet/src-tauri/src/operations/mixnet/bond.rs +++ b/nym-wallet/src-tauri/src/operations/mixnet/bond.rs @@ -14,7 +14,7 @@ use nym_types::currency::DecCoin; use nym_types::gateway::GatewayBond; use nym_types::mixnode::{MixNodeCostParams, MixNodeDetails}; use nym_types::transaction::TransactionExecuteResult; -use nym_validator_client::nyxd::traits::{MixnetQueryClient, MixnetSigningClient}; +use nym_validator_client::nyxd::contract_traits::{MixnetQueryClient, MixnetSigningClient}; use nym_validator_client::nyxd::Fee; use serde::{Deserialize, Serialize}; use std::cmp::Ordering; diff --git a/nym-wallet/src-tauri/src/operations/mixnet/delegate.rs b/nym-wallet/src-tauri/src/operations/mixnet/delegate.rs index 8a4a82e158..e29dda737b 100644 --- a/nym-wallet/src-tauri/src/operations/mixnet/delegate.rs +++ b/nym-wallet/src-tauri/src/operations/mixnet/delegate.rs @@ -13,7 +13,7 @@ use nym_types::deprecated::{ use nym_types::mixnode::MixNodeCostParams; use nym_types::pending_events::PendingEpochEvent; use nym_types::transaction::TransactionExecuteResult; -use nym_validator_client::nyxd::traits::{MixnetQueryClient, MixnetSigningClient}; +use nym_validator_client::nyxd::contract_traits::{MixnetQueryClient, MixnetSigningClient}; use nym_validator_client::nyxd::Fee; #[tauri::command] diff --git a/nym-wallet/src-tauri/src/operations/mixnet/interval.rs b/nym-wallet/src-tauri/src/operations/mixnet/interval.rs index e18fa1e44a..14a1d09699 100644 --- a/nym-wallet/src-tauri/src/operations/mixnet/interval.rs +++ b/nym-wallet/src-tauri/src/operations/mixnet/interval.rs @@ -5,7 +5,7 @@ use crate::error::BackendError; use crate::nyxd_client; use crate::state::WalletState; use nym_types::pending_events::{PendingEpochEvent, PendingIntervalEvent}; -use nym_validator_client::nyxd::traits::MixnetQueryClient; +use nym_validator_client::nyxd::contract_traits::MixnetQueryClient; use nym_wallet_types::interval::Interval; #[tauri::command] diff --git a/nym-wallet/src-tauri/src/operations/mixnet/rewards.rs b/nym-wallet/src-tauri/src/operations/mixnet/rewards.rs index 62ef534d02..81da431443 100644 --- a/nym-wallet/src-tauri/src/operations/mixnet/rewards.rs +++ b/nym-wallet/src-tauri/src/operations/mixnet/rewards.rs @@ -3,7 +3,7 @@ use crate::state::WalletState; use crate::vesting::rewards::vesting_claim_delegator_reward; use nym_mixnet_contract_common::{MixId, RewardingParams}; use nym_types::transaction::TransactionExecuteResult; -use nym_validator_client::nyxd::traits::{MixnetQueryClient, MixnetSigningClient}; +use nym_validator_client::nyxd::contract_traits::{MixnetQueryClient, MixnetSigningClient}; use nym_validator_client::nyxd::Fee; #[tauri::command] diff --git a/nym-wallet/src-tauri/src/operations/vesting/bond.rs b/nym-wallet/src-tauri/src/operations/vesting/bond.rs index f2077e5694..8e47953109 100644 --- a/nym-wallet/src-tauri/src/operations/vesting/bond.rs +++ b/nym-wallet/src-tauri/src/operations/vesting/bond.rs @@ -10,7 +10,7 @@ use nym_mixnet_contract_common::{GatewayConfigUpdate, MixNodeConfigUpdate}; use nym_types::currency::DecCoin; use nym_types::mixnode::MixNodeCostParams; use nym_types::transaction::TransactionExecuteResult; -use nym_validator_client::nyxd::{traits::VestingSigningClient, Fee}; +use nym_validator_client::nyxd::{contract_traits::VestingSigningClient, Fee}; use std::cmp::Ordering; #[tauri::command] diff --git a/nym-wallet/src-tauri/src/operations/vesting/delegate.rs b/nym-wallet/src-tauri/src/operations/vesting/delegate.rs index ff7c33710f..64ac3ed736 100644 --- a/nym-wallet/src-tauri/src/operations/vesting/delegate.rs +++ b/nym-wallet/src-tauri/src/operations/vesting/delegate.rs @@ -6,7 +6,7 @@ use crate::state::WalletState; use nym_mixnet_contract_common::MixId; use nym_types::currency::DecCoin; use nym_types::transaction::TransactionExecuteResult; -use nym_validator_client::nyxd::{traits::VestingSigningClient, Fee}; +use nym_validator_client::nyxd::{contract_traits::VestingSigningClient, Fee}; #[tauri::command] pub async fn vesting_delegate_to_mixnode( diff --git a/nym-wallet/src-tauri/src/operations/vesting/queries.rs b/nym-wallet/src-tauri/src/operations/vesting/queries.rs index a24e26d001..f3377d5ed5 100644 --- a/nym-wallet/src-tauri/src/operations/vesting/queries.rs +++ b/nym-wallet/src-tauri/src/operations/vesting/queries.rs @@ -8,7 +8,7 @@ use cosmwasm_std::Timestamp; use nym_types::currency::DecCoin; use nym_types::vesting::VestingAccountInfo; use nym_types::vesting::{OriginalVestingResponse, PledgeData}; -use nym_validator_client::nyxd::traits::VestingQueryClient; +use nym_validator_client::nyxd::contract_traits::VestingQueryClient; use nym_vesting_contract_common::Period; #[tauri::command] diff --git a/nym-wallet/src-tauri/src/operations/vesting/rewards.rs b/nym-wallet/src-tauri/src/operations/vesting/rewards.rs index dbedb302e3..d990b2c1c5 100644 --- a/nym-wallet/src-tauri/src/operations/vesting/rewards.rs +++ b/nym-wallet/src-tauri/src/operations/vesting/rewards.rs @@ -5,7 +5,7 @@ use crate::error::BackendError; use crate::state::WalletState; use nym_mixnet_contract_common::MixId; use nym_types::transaction::TransactionExecuteResult; -use nym_validator_client::nyxd::traits::VestingSigningClient; +use nym_validator_client::nyxd::contract_traits::VestingSigningClient; use nym_validator_client::nyxd::Fee; #[tauri::command] diff --git a/nym-wallet/src-tauri/src/utils.rs b/nym-wallet/src-tauri/src/utils.rs index 579ccc5add..f6fe9ab4b3 100644 --- a/nym-wallet/src-tauri/src/utils.rs +++ b/nym-wallet/src-tauri/src/utils.rs @@ -8,7 +8,7 @@ use cosmwasm_std::Decimal; use nym_mixnet_contract_common::{IdentityKey, MixId, Percent}; use nym_types::currency::DecCoin; use nym_types::mixnode::MixNodeCostParams; -use nym_validator_client::nyxd::traits::MixnetQueryClient; +use nym_validator_client::nyxd::contract_traits::MixnetQueryClient; use nym_wallet_types::app::AppEnv; fn get_env_as_option(key: &str) -> Option { From e2bf9daf524b2b707269c8e36fb822c0ec4063e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Mon, 31 Jul 2023 11:42:50 +0100 Subject: [PATCH 02/24] wip --- Cargo.lock | 1 + .../client-libs/validator-client/Cargo.toml | 1 + .../validator-client/src/client.rs | 795 ++++++++-------- .../validator-client/src/connection_tester.rs | 11 +- .../coconut_bandwidth_query_client.rs | 58 +- .../nyxd/contract_traits/dkg_query_client.rs | 32 +- .../contract_traits/group_query_client.rs | 57 +- .../contract_traits/mixnet_query_client.rs | 194 +++- .../src/nyxd/contract_traits/mod.rs | 157 +++- .../contract_traits/multisig_query_client.rs | 159 +++- .../name_service_query_client.rs | 44 +- .../sp_directory_query_client.rs | 40 +- .../contract_traits/vesting_query_client.rs | 31 +- .../nyxd/cosmwasm_client/client_traits/mod.rs | 12 + .../query_client.rs} | 38 +- .../{ => client_traits}/signing_client.rs | 203 +--- .../src/nyxd/cosmwasm_client/mod.rs | 164 +++- .../validator-client/src/nyxd/error.rs | 4 + .../src/nyxd/fee/gas_price.rs | 14 + .../validator-client/src/nyxd/mod.rs | 868 +++++++----------- .../src/signing/direct_wallet.rs | 1 + .../validator-client/src/signing/signer.rs | 22 + .../validator-client/src/signing/tx_signer.rs | 111 ++- common/network-defaults/src/lib.rs | 4 + nym-connect/desktop/Cargo.lock | 1 + nym-wallet/Cargo.lock | 1 + 26 files changed, 1679 insertions(+), 1344 deletions(-) create mode 100644 common/client-libs/validator-client/src/nyxd/cosmwasm_client/client_traits/mod.rs rename common/client-libs/validator-client/src/nyxd/cosmwasm_client/{client.rs => client_traits/query_client.rs} (95%) rename common/client-libs/validator-client/src/nyxd/cosmwasm_client/{ => client_traits}/signing_client.rs (86%) diff --git a/Cargo.lock b/Cargo.lock index a2b1c5d75f..47bd947773 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4885,6 +4885,7 @@ dependencies = [ "colored", "cosmrs", "cosmwasm-std", + "cw-utils", "cw3", "cw4", "eyre", diff --git a/common/client-libs/validator-client/Cargo.toml b/common/client-libs/validator-client/Cargo.toml index 793adaf3cb..bead36057c 100644 --- a/common/client-libs/validator-client/Cargo.toml +++ b/common/client-libs/validator-client/Cargo.toml @@ -45,6 +45,7 @@ cosmrs = { workspace = true, features = ["bip32", "cosmwasm"] } tendermint-rpc = { workspace = true } eyre = { version = "0.6", optional = true } +cw-utils = { workspace = true } cw3 = { workspace = true } cw4 = { workspace = true } prost = { version = "0.11", default-features = false } diff --git a/common/client-libs/validator-client/src/client.rs b/common/client-libs/validator-client/src/client.rs index 70511efe61..854648bcc9 100644 --- a/common/client-libs/validator-client/src/client.rs +++ b/common/client-libs/validator-client/src/client.rs @@ -16,9 +16,8 @@ pub use nym_mixnet_contract_common::{ }; use url::Url; -use crate::nyxd::contract_traits::{DkgQueryClient, MixnetQueryClient}; -#[cfg(feature = "http-client")] -use crate::nyxd::QueryNyxdClient; +// use crate::nyxd::contract_traits::{DkgQueryClient, MixnetQueryClient}; +use crate::nyxd::contract_traits::NymContractsProvider; use crate::nyxd::{self, CosmWasmClient, NyxdClient}; use nym_api_requests::models::MixNodeBondAnnotated; use nym_coconut_dkg_common::{types::EpochId, verification_key::ContractVKShare}; @@ -31,11 +30,11 @@ use nym_mixnet_contract_common::{ }; use nym_network_defaults::NymNetworkDetails; use std::str::FromStr; +use tendermint_rpc::HttpClient; -#[cfg(all(feature = "signing", feature = "http-client"))] -use crate::nyxd::SigningNyxdClient; #[cfg(all(feature = "signing", feature = "http-client"))] use crate::signing::direct_wallet::DirectSecp256k1HdWallet; +use crate::signing::signer::NoSigner; #[must_use] #[derive(Debug, Clone)] @@ -116,29 +115,32 @@ impl Config { } } -pub struct Client { +pub struct Client { + #[deprecated] mixnode_page_limit: Option, + #[deprecated] gateway_page_limit: Option, + #[deprecated] mixnode_delegations_page_limit: Option, + #[deprecated] rewarded_set_page_limit: Option, // ideally they would have been read-only, but unfortunately rust doesn't have such features pub nym_api: nym_api::Client, - pub nyxd: NyxdClient, + pub nyxd: NyxdClient, } #[cfg(all(feature = "signing", feature = "http-client"))] -impl Client> { +impl Client { pub fn new_signing( config: Config, mnemonic: bip39::Mnemonic, - ) -> Result>, ValidatorClientError> { + ) -> Result, ValidatorClientError> { let nym_api_client = nym_api::Client::new(config.api_url.clone()); let nyxd_client = NyxdClient::connect_with_mnemonic( config.nyxd_config.clone(), config.nyxd_url.as_str(), mnemonic, - None, )?; Ok(Client { @@ -157,13 +159,14 @@ impl Client> { } pub fn set_nyxd_simulated_gas_multiplier(&mut self, multiplier: f32) { - self.nyxd.set_simulated_gas_multiplier(multiplier) + todo!() + // self.nyxd.set_simulated_gas_multiplier(multiplier) } } #[cfg(feature = "http-client")] -impl Client { - pub fn new_query(config: Config) -> Result, ValidatorClientError> { +impl Client { + pub fn new_query(config: Config) -> Result, ValidatorClientError> { let nym_api_client = nym_api::Client::new(config.api_url.clone()); let nyxd_client = NyxdClient::connect(config.nyxd_config.clone(), config.nyxd_url.as_str())?; @@ -195,375 +198,379 @@ impl Client { } pub fn get_mixnet_contract_address(&self) -> cosmrs::AccountId { - self.nyxd.mixnet_contract_address().clone() + // TODO: deal with the expect + self.nyxd + .mixnet_contract_address() + .expect("mixnet contract address is not available") + .clone() } - pub async fn get_all_node_families(&self) -> Result, ValidatorClientError> - where - C: CosmWasmClient + Sync + Send, - { - let mut families = Vec::new(); - let mut start_after = None; - - loop { - let paged_response = self - .nyxd - .get_all_node_families_paged(start_after.take(), None) - .await?; - families.extend(paged_response.families); - - if let Some(start_after_res) = paged_response.start_next_after { - start_after = Some(start_after_res) - } else { - break; - } - } - - Ok(families) - } - - pub async fn get_all_family_members( - &self, - ) -> Result, ValidatorClientError> - where - C: CosmWasmClient + Sync + Send, - { - let mut members = Vec::new(); - let mut start_after = None; - - loop { - let paged_response = self - .nyxd - .get_all_family_members_paged(start_after.take(), None) - .await?; - members.extend(paged_response.members); - - if let Some(start_after_res) = paged_response.start_next_after { - start_after = Some(start_after_res) - } else { - break; - } - } - - Ok(members) - } - - // basically handles paging for us - pub async fn get_all_nyxd_rewarded_set_mixnodes( - &self, - ) -> Result, ValidatorClientError> - where - C: CosmWasmClient + Sync + Send, - { - let mut identities = Vec::new(); - let mut start_after = None; - - loop { - let mut paged_response = self - .nyxd - .get_rewarded_set_paged(start_after.take(), self.rewarded_set_page_limit) - .await?; - identities.append(&mut paged_response.nodes); - - if let Some(start_after_res) = paged_response.start_next_after { - start_after = Some(start_after_res) - } else { - break; - } - } - - Ok(identities) - } - - pub async fn get_all_nyxd_mixnode_bonds(&self) -> Result, ValidatorClientError> - where - C: CosmWasmClient + Sync + Send, - { - let mut mixnodes = Vec::new(); - let mut start_after = None; - loop { - let mut paged_response = self - .nyxd - .get_mixnode_bonds_paged(self.mixnode_page_limit, start_after.take()) - .await?; - mixnodes.append(&mut paged_response.nodes); - - if let Some(start_after_res) = paged_response.start_next_after { - start_after = Some(start_after_res) - } else { - break; - } - } - - Ok(mixnodes) - } - - pub async fn get_all_nyxd_mixnodes_detailed( - &self, - ) -> Result, ValidatorClientError> - where - C: CosmWasmClient + Sync + Send, - { - let mut mixnodes = Vec::new(); - let mut start_after = None; - loop { - let mut paged_response = self - .nyxd - .get_mixnodes_detailed_paged(self.mixnode_page_limit, start_after.take()) - .await?; - mixnodes.append(&mut paged_response.nodes); - - if let Some(start_after_res) = paged_response.start_next_after { - start_after = Some(start_after_res) - } else { - break; - } - } - - Ok(mixnodes) - } - - pub async fn get_all_nyxd_unbonded_mixnodes( - &self, - ) -> Result, ValidatorClientError> - where - C: CosmWasmClient + Sync + Send, - { - let mut mixnodes = Vec::new(); - let mut start_after = None; - loop { - let mut paged_response = self - .nyxd - .get_unbonded_paged(self.mixnode_page_limit, start_after.take()) - .await?; - mixnodes.append(&mut paged_response.nodes); - - if let Some(start_after_res) = paged_response.start_next_after { - start_after = Some(start_after_res) - } else { - break; - } - } - - Ok(mixnodes) - } - - pub async fn get_all_nyxd_unbonded_mixnodes_by_owner( - &self, - owner: &cosmrs::AccountId, - ) -> Result, ValidatorClientError> - where - C: CosmWasmClient + Sync + Send, - { - let mut mixnodes = Vec::new(); - let mut start_after = None; - loop { - let mut paged_response = self - .nyxd - .get_unbonded_by_owner_paged(owner, self.mixnode_page_limit, start_after.take()) - .await?; - mixnodes.append(&mut paged_response.nodes); - - if let Some(start_after_res) = paged_response.start_next_after { - start_after = Some(start_after_res) - } else { - break; - } - } - - Ok(mixnodes) - } - - pub async fn get_all_nyxd_unbonded_mixnodes_by_identity( - &self, - identity_key: String, - ) -> Result, ValidatorClientError> - where - C: CosmWasmClient + Sync + Send, - { - let mut mixnodes = Vec::new(); - let mut start_after = None; - loop { - let mut paged_response = self - .nyxd - .get_unbonded_by_identity_paged( - identity_key.clone(), - self.mixnode_page_limit, - start_after.take(), - ) - .await?; - mixnodes.append(&mut paged_response.nodes); - - if let Some(start_after_res) = paged_response.start_next_after { - start_after = Some(start_after_res) - } else { - break; - } - } - - Ok(mixnodes) - } - - pub async fn get_all_nyxd_gateways(&self) -> Result, ValidatorClientError> - where - C: CosmWasmClient + Sync + Send, - { - let mut gateways = Vec::new(); - let mut start_after = None; - loop { - let mut paged_response = self - .nyxd - .get_gateways_paged(start_after.take(), self.gateway_page_limit) - .await?; - gateways.append(&mut paged_response.nodes); - - if let Some(start_after_res) = paged_response.start_next_after { - start_after = Some(start_after_res) - } else { - break; - } - } - - Ok(gateways) - } - - pub async fn get_all_nyxd_single_mixnode_delegations( - &self, - mix_id: MixId, - ) -> Result, ValidatorClientError> - where - C: CosmWasmClient + Sync + Send, - { - let mut delegations = Vec::new(); - let mut start_after = None; - loop { - let mut paged_response = self - .nyxd - .get_mixnode_delegations_paged( - mix_id, - start_after.take(), - self.mixnode_delegations_page_limit, - ) - .await?; - delegations.append(&mut paged_response.delegations); - - if let Some(start_after_res) = paged_response.start_next_after { - start_after = Some(start_after_res) - } else { - break; - } - } - - Ok(delegations) - } - - pub async fn get_all_delegator_delegations( - &self, - delegation_owner: &cosmrs::AccountId, - ) -> Result, ValidatorClientError> - where - C: CosmWasmClient + Sync + Send, - { - let mut delegations = Vec::new(); - let mut start_after = None; - loop { - let mut paged_response = self - .nyxd - .get_delegator_delegations_paged( - delegation_owner.to_string(), - start_after.take(), - self.mixnode_delegations_page_limit, - ) - .await?; - delegations.append(&mut paged_response.delegations); - - if let Some(start_after_res) = paged_response.start_next_after { - start_after = Some(start_after_res) - } else { - break; - } - } - - Ok(delegations) - } - - pub async fn get_all_network_delegations(&self) -> Result, ValidatorClientError> - where - C: CosmWasmClient + Sync + Send, - { - let mut delegations = Vec::new(); - let mut start_after = None; - loop { - let mut paged_response = self - .nyxd - .get_all_network_delegations_paged( - start_after.take(), - self.mixnode_delegations_page_limit, - ) - .await?; - delegations.append(&mut paged_response.delegations); - - if let Some(start_after_res) = paged_response.start_next_after { - start_after = Some(start_after_res) - } else { - break; - } - } - - Ok(delegations) - } - - pub async fn get_all_nyxd_pending_epoch_events( - &self, - ) -> Result, ValidatorClientError> - where - C: CosmWasmClient + Sync + Send, - { - let mut events = Vec::new(); - let mut start_after = None; - - loop { - let mut paged_response = self - .nyxd - .get_pending_epoch_events_paged(start_after.take(), self.rewarded_set_page_limit) - .await?; - events.append(&mut paged_response.events); - - if let Some(start_after_res) = paged_response.start_next_after { - start_after = Some(start_after_res) - } else { - break; - } - } - - Ok(events) - } - - pub async fn get_all_nyxd_pending_interval_events( - &self, - ) -> Result, ValidatorClientError> - where - C: CosmWasmClient + Sync + Send, - { - let mut events = Vec::new(); - let mut start_after = None; - - loop { - let mut paged_response = self - .nyxd - .get_pending_interval_events_paged(start_after.take(), self.rewarded_set_page_limit) - .await?; - events.append(&mut paged_response.events); - - if let Some(start_after_res) = paged_response.start_next_after { - start_after = Some(start_after_res) - } else { - break; - } - } - - Ok(events) - } + // pub async fn get_all_node_families(&self) -> Result, ValidatorClientError> + // where + // C: CosmWasmClient + Sync + Send, + // { + // let mut families = Vec::new(); + // let mut start_after = None; + // + // loop { + // let paged_response = self + // .nyxd + // .get_all_node_families_paged(start_after.take(), None) + // .await?; + // families.extend(paged_response.families); + // + // if let Some(start_after_res) = paged_response.start_next_after { + // start_after = Some(start_after_res) + // } else { + // break; + // } + // } + // + // Ok(families) + // } + // + // pub async fn get_all_family_members( + // &self, + // ) -> Result, ValidatorClientError> + // where + // C: CosmWasmClient + Sync + Send, + // { + // let mut members = Vec::new(); + // let mut start_after = None; + // + // loop { + // let paged_response = self + // .nyxd + // .get_all_family_members_paged(start_after.take(), None) + // .await?; + // members.extend(paged_response.members); + // + // if let Some(start_after_res) = paged_response.start_next_after { + // start_after = Some(start_after_res) + // } else { + // break; + // } + // } + // + // Ok(members) + // } + // + // // basically handles paging for us + // pub async fn get_all_nyxd_rewarded_set_mixnodes( + // &self, + // ) -> Result, ValidatorClientError> + // where + // C: CosmWasmClient + Sync + Send, + // { + // let mut identities = Vec::new(); + // let mut start_after = None; + // + // loop { + // let mut paged_response = self + // .nyxd + // .get_rewarded_set_paged(start_after.take(), self.rewarded_set_page_limit) + // .await?; + // identities.append(&mut paged_response.nodes); + // + // if let Some(start_after_res) = paged_response.start_next_after { + // start_after = Some(start_after_res) + // } else { + // break; + // } + // } + // + // Ok(identities) + // } + // + // pub async fn get_all_nyxd_mixnode_bonds(&self) -> Result, ValidatorClientError> + // where + // C: CosmWasmClient + Sync + Send, + // { + // let mut mixnodes = Vec::new(); + // let mut start_after = None; + // loop { + // let mut paged_response = self + // .nyxd + // .get_mixnode_bonds_paged(self.mixnode_page_limit, start_after.take()) + // .await?; + // mixnodes.append(&mut paged_response.nodes); + // + // if let Some(start_after_res) = paged_response.start_next_after { + // start_after = Some(start_after_res) + // } else { + // break; + // } + // } + // + // Ok(mixnodes) + // } + // + // pub async fn get_all_nyxd_mixnodes_detailed( + // &self, + // ) -> Result, ValidatorClientError> + // where + // C: CosmWasmClient + Sync + Send, + // { + // let mut mixnodes = Vec::new(); + // let mut start_after = None; + // loop { + // let mut paged_response = self + // .nyxd + // .get_mixnodes_detailed_paged(self.mixnode_page_limit, start_after.take()) + // .await?; + // mixnodes.append(&mut paged_response.nodes); + // + // if let Some(start_after_res) = paged_response.start_next_after { + // start_after = Some(start_after_res) + // } else { + // break; + // } + // } + // + // Ok(mixnodes) + // } + // + // pub async fn get_all_nyxd_unbonded_mixnodes( + // &self, + // ) -> Result, ValidatorClientError> + // where + // C: CosmWasmClient + Sync + Send, + // { + // let mut mixnodes = Vec::new(); + // let mut start_after = None; + // loop { + // let mut paged_response = self + // .nyxd + // .get_unbonded_paged(self.mixnode_page_limit, start_after.take()) + // .await?; + // mixnodes.append(&mut paged_response.nodes); + // + // if let Some(start_after_res) = paged_response.start_next_after { + // start_after = Some(start_after_res) + // } else { + // break; + // } + // } + // + // Ok(mixnodes) + // } + // + // pub async fn get_all_nyxd_unbonded_mixnodes_by_owner( + // &self, + // owner: &cosmrs::AccountId, + // ) -> Result, ValidatorClientError> + // where + // C: CosmWasmClient + Sync + Send, + // { + // let mut mixnodes = Vec::new(); + // let mut start_after = None; + // loop { + // let mut paged_response = self + // .nyxd + // .get_unbonded_by_owner_paged(owner, self.mixnode_page_limit, start_after.take()) + // .await?; + // mixnodes.append(&mut paged_response.nodes); + // + // if let Some(start_after_res) = paged_response.start_next_after { + // start_after = Some(start_after_res) + // } else { + // break; + // } + // } + // + // Ok(mixnodes) + // } + // + // pub async fn get_all_nyxd_unbonded_mixnodes_by_identity( + // &self, + // identity_key: String, + // ) -> Result, ValidatorClientError> + // where + // C: CosmWasmClient + Sync + Send, + // { + // let mut mixnodes = Vec::new(); + // let mut start_after = None; + // loop { + // let mut paged_response = self + // .nyxd + // .get_unbonded_by_identity_paged( + // identity_key.clone(), + // self.mixnode_page_limit, + // start_after.take(), + // ) + // .await?; + // mixnodes.append(&mut paged_response.nodes); + // + // if let Some(start_after_res) = paged_response.start_next_after { + // start_after = Some(start_after_res) + // } else { + // break; + // } + // } + // + // Ok(mixnodes) + // } + // + // pub async fn get_all_nyxd_gateways(&self) -> Result, ValidatorClientError> + // where + // C: CosmWasmClient + Sync + Send, + // { + // let mut gateways = Vec::new(); + // let mut start_after = None; + // loop { + // let mut paged_response = self + // .nyxd + // .get_gateways_paged(start_after.take(), self.gateway_page_limit) + // .await?; + // gateways.append(&mut paged_response.nodes); + // + // if let Some(start_after_res) = paged_response.start_next_after { + // start_after = Some(start_after_res) + // } else { + // break; + // } + // } + // + // Ok(gateways) + // } + // + // pub async fn get_all_nyxd_single_mixnode_delegations( + // &self, + // mix_id: MixId, + // ) -> Result, ValidatorClientError> + // where + // C: CosmWasmClient + Sync + Send, + // { + // let mut delegations = Vec::new(); + // let mut start_after = None; + // loop { + // let mut paged_response = self + // .nyxd + // .get_mixnode_delegations_paged( + // mix_id, + // start_after.take(), + // self.mixnode_delegations_page_limit, + // ) + // .await?; + // delegations.append(&mut paged_response.delegations); + // + // if let Some(start_after_res) = paged_response.start_next_after { + // start_after = Some(start_after_res) + // } else { + // break; + // } + // } + // + // Ok(delegations) + // } + // + // pub async fn get_all_delegator_delegations( + // &self, + // delegation_owner: &cosmrs::AccountId, + // ) -> Result, ValidatorClientError> + // where + // C: CosmWasmClient + Sync + Send, + // { + // let mut delegations = Vec::new(); + // let mut start_after = None; + // loop { + // let mut paged_response = self + // .nyxd + // .get_delegator_delegations_paged( + // delegation_owner.to_string(), + // start_after.take(), + // self.mixnode_delegations_page_limit, + // ) + // .await?; + // delegations.append(&mut paged_response.delegations); + // + // if let Some(start_after_res) = paged_response.start_next_after { + // start_after = Some(start_after_res) + // } else { + // break; + // } + // } + // + // Ok(delegations) + // } + // + // pub async fn get_all_network_delegations(&self) -> Result, ValidatorClientError> + // where + // C: CosmWasmClient + Sync + Send, + // { + // let mut delegations = Vec::new(); + // let mut start_after = None; + // loop { + // let mut paged_response = self + // .nyxd + // .get_all_network_delegations_paged( + // start_after.take(), + // self.mixnode_delegations_page_limit, + // ) + // .await?; + // delegations.append(&mut paged_response.delegations); + // + // if let Some(start_after_res) = paged_response.start_next_after { + // start_after = Some(start_after_res) + // } else { + // break; + // } + // } + // + // Ok(delegations) + // } + // + // pub async fn get_all_nyxd_pending_epoch_events( + // &self, + // ) -> Result, ValidatorClientError> + // where + // C: CosmWasmClient + Sync + Send, + // { + // let mut events = Vec::new(); + // let mut start_after = None; + // + // loop { + // let mut paged_response = self + // .nyxd + // .get_pending_epoch_events_paged(start_after.take(), self.rewarded_set_page_limit) + // .await?; + // events.append(&mut paged_response.events); + // + // if let Some(start_after_res) = paged_response.start_next_after { + // start_after = Some(start_after_res) + // } else { + // break; + // } + // } + // + // Ok(events) + // } + // + // pub async fn get_all_nyxd_pending_interval_events( + // &self, + // ) -> Result, ValidatorClientError> + // where + // C: CosmWasmClient + Sync + Send, + // { + // let mut events = Vec::new(); + // let mut start_after = None; + // + // loop { + // let mut paged_response = self + // .nyxd + // .get_pending_interval_events_paged(start_after.take(), self.rewarded_set_page_limit) + // .await?; + // events.append(&mut paged_response.events); + // + // if let Some(start_after_res) = paged_response.start_next_after { + // start_after = Some(start_after_res) + // } else { + // break; + // } + // } + // + // Ok(events) + // } } // validator-api wrappers @@ -633,20 +640,20 @@ pub struct CoconutApiClient { } impl CoconutApiClient { - pub async fn all_coconut_api_clients( - client: &C, - epoch_id: EpochId, - ) -> Result, ValidatorClientError> - where - C: DkgQueryClient + Sync + Send, - { - Ok(client - .get_all_verification_key_shares(epoch_id) - .await? - .into_iter() - .filter_map(Self::try_from) - .collect()) - } + // pub async fn all_coconut_api_clients( + // client: &C, + // epoch_id: EpochId, + // ) -> Result, ValidatorClientError> + // where + // C: DkgQueryClient + Sync + Send, + // { + // Ok(client + // .get_all_verification_key_shares(epoch_id) + // .await? + // .into_iter() + // .filter_map(Self::try_from) + // .collect()) + // } fn try_from(share: ContractVKShare) -> Option { if share.verified { diff --git a/common/client-libs/validator-client/src/connection_tester.rs b/common/client-libs/validator-client/src/connection_tester.rs index b1d2293850..1eb0c50914 100644 --- a/common/client-libs/validator-client/src/connection_tester.rs +++ b/common/client-libs/validator-client/src/connection_tester.rs @@ -1,7 +1,8 @@ use crate::nyxd::error::NyxdError; -use crate::nyxd::{Config as ClientConfig, NyxdClient, QueryNyxdClient}; +use crate::nyxd::{Config as ClientConfig, QueryHttpNyxdClient}; use crate::{NymApiClient, ValidatorClientError}; +// use crate::nyxd::contract_traits::MixnetQueryClient; use crate::nyxd::contract_traits::MixnetQueryClient; use colored::Colorize; use core::fmt; @@ -53,7 +54,7 @@ pub async fn test_nyxd_url_connection( let config = ClientConfig::try_from_nym_network_details(&network) .expect("failed to create valid nyxd client config"); - let mut nyxd_client = NyxdClient::::connect(config, nyxd_url.as_str())?; + let mut nyxd_client = QueryHttpNyxdClient::connect(config, nyxd_url.as_str())?; // possibly redundant, but lets just leave it here nyxd_client.set_mixnet_contract_address(address); match test_nyxd_connection(network, &nyxd_url, &nyxd_client).await { @@ -75,7 +76,7 @@ fn setup_connection_tests( let config = ClientConfig::try_from_nym_network_details(&network) .expect("failed to create valid nyxd client config"); - if let Ok(mut client) = NyxdClient::::connect(config, url.as_str()) { + if let Ok(mut client) = QueryHttpNyxdClient::connect(config, url.as_str()) { // possibly redundant, but lets just leave it here client.set_mixnet_contract_address(address); Some(ClientForConnectionTest::Nyxd( @@ -112,7 +113,7 @@ fn extract_and_collect_results_into_map( async fn test_nyxd_connection( network: NymNetworkDetails, url: &Url, - client: &NyxdClient, + client: &QueryHttpNyxdClient, ) -> ConnectionResult { let result = match timeout( Duration::from_secs(CONNECTION_TEST_TIMEOUT_SEC), @@ -186,7 +187,7 @@ async fn test_nym_api_connection( } enum ClientForConnectionTest { - Nyxd(NymNetworkDetails, Url, Box>), + Nyxd(NymNetworkDetails, Url, Box), Api(NymNetworkDetails, Url, NymApiClient), } diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/coconut_bandwidth_query_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/coconut_bandwidth_query_client.rs index 66ac21947b..b1ecc7a18c 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/coconut_bandwidth_query_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/coconut_bandwidth_query_client.rs @@ -1,33 +1,65 @@ -// Copyright 2022 - Nym Technologies SA +// Copyright 2022-2023 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 use crate::nyxd::error::NyxdError; use crate::nyxd::{CosmWasmClient, NyxdClient}; - -use nym_coconut_bandwidth_contract_common::msg::QueryMsg; +use nym_coconut_bandwidth_contract_common::msg::QueryMsg as CoconutBandwidthQueryMsg; use nym_coconut_bandwidth_contract_common::spend_credential::SpendCredentialResponse; +use crate::nyxd::contract_traits::NymContractsProvider; use async_trait::async_trait; +use serde::Deserialize; #[async_trait] pub trait CoconutBandwidthQueryClient { - async fn get_spent_credential( + async fn query_coconut_bandwidth_contract( &self, - blinded_serial_number: String, - ) -> Result; -} + query: CoconutBandwidthQueryMsg, + ) -> Result + where + for<'a> T: Deserialize<'a>; -#[async_trait] -impl CoconutBandwidthQueryClient for NyxdClient { async fn get_spent_credential( &self, blinded_serial_number: String, ) -> Result { - let request = QueryMsg::GetSpentCredential { + self.query_coconut_bandwidth_contract(CoconutBandwidthQueryMsg::GetSpentCredential { blinded_serial_number, - }; - self.client - .query_contract_smart(self.coconut_bandwidth_contract_address(), &request) + }) + .await + } +} + +#[async_trait] +impl CoconutBandwidthQueryClient for C +where + C: CosmWasmClient + NymContractsProvider + Send + Sync, +{ + async fn query_coconut_bandwidth_contract( + &self, + query: CoconutBandwidthQueryMsg, + ) -> Result + where + for<'a> T: Deserialize<'a>, + { + let coconut_bandwidth_contract_address = self + .coconut_bandwidth_contract_address() + .ok_or_else(|| NyxdError::unavailable_contract_address("coconut bandwidth contract"))?; + self.query_contract_smart(coconut_bandwidth_contract_address, &query) .await } } + +#[cfg(test)] +mod tests { + use super::*; + + // it's enough that this compiles + #[deprecated] + async fn all_query_variants_are_covered( + client: C, + msg: CoconutBandwidthQueryMsg, + ) { + unimplemented!() + } +} 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 92334424c2..9465cc74ab 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 @@ -1,6 +1,7 @@ // Copyright 2022 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 +use crate::nyxd::contract_traits::NymContractsProvider; use crate::nyxd::error::NyxdError; use crate::nyxd::{CosmWasmClient, NyxdClient}; use async_trait::async_trait; @@ -176,29 +177,32 @@ pub trait DkgQueryClient { } #[async_trait] -impl DkgQueryClient for NyxdClient +impl DkgQueryClient for C where - C: CosmWasmClient + Send + Sync, + C: CosmWasmClient + NymContractsProvider + Send + Sync, { async fn query_dkg_contract(&self, query: DkgQueryMsg) -> Result where for<'a> T: Deserialize<'a>, { - self.client - .query_contract_smart(self.coconut_dkg_contract_address(), &query) + let dkg_contract_address = &self + .dkg_contract_address() + .ok_or_else(|| NyxdError::unavailable_contract_address("dkg contract"))?; + self.query_contract_smart(dkg_contract_address, &query) .await } } -#[async_trait] -impl DkgQueryClient for crate::Client -where - C: CosmWasmClient + Sync + Send, -{ - async fn query_dkg_contract(&self, query: DkgQueryMsg) -> Result - where - for<'a> T: Deserialize<'a>, - { - self.nyxd.query_dkg_contract(query).await +#[cfg(test)] +mod tests { + use super::*; + + // it's enough that this compiles + #[deprecated] + async fn all_query_variants_are_covered( + client: C, + msg: DkgQueryMsg, + ) { + unimplemented!() } } diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/group_query_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/group_query_client.rs index b5b4c1d1ee..6102bcc5f2 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/group_query_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/group_query_client.rs @@ -1,28 +1,57 @@ // Copyright 2023 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 +use crate::nyxd::contract_traits::NymContractsProvider; use crate::nyxd::error::NyxdError; use crate::nyxd::{CosmWasmClient, NyxdClient}; - -use nym_group_contract_common::msg::QueryMsg; - use async_trait::async_trait; use cw4::MemberResponse; +use nym_group_contract_common::msg::QueryMsg as GroupQueryMsg; +use serde::Deserialize; #[async_trait] pub trait GroupQueryClient { - async fn member(&self, addr: String) -> Result; -} + async fn query_group_contract(&self, query: GroupQueryMsg) -> Result + where + for<'a> T: Deserialize<'a>; -#[async_trait] -impl GroupQueryClient for NyxdClient { - async fn member(&self, addr: String) -> Result { - let request = QueryMsg::Member { - addr, - at_height: None, - }; - self.client - .query_contract_smart(self.group_contract_address(), &request) + async fn member( + &self, + addr: String, + at_height: Option, + ) -> Result { + self.query_group_contract(GroupQueryMsg::Member { addr, at_height }) .await } } + +#[async_trait] +impl GroupQueryClient for C +where + C: CosmWasmClient + NymContractsProvider + Send + Sync, +{ + async fn query_group_contract(&self, query: GroupQueryMsg) -> Result + where + for<'a> T: Deserialize<'a>, + { + let group_contract_address = &self + .group_contract_address() + .ok_or_else(|| NyxdError::unavailable_contract_address("group contract"))?; + self.query_contract_smart(group_contract_address, &query) + .await + } +} + +#[cfg(test)] +mod tests { + use super::*; + + // it's enough that this compiles + #[deprecated] + async fn all_query_variants_are_covered( + client: C, + msg: GroupQueryMsg, + ) { + unimplemented!() + } +} diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/mixnet_query_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/mixnet_query_client.rs index 0297b90452..f4128f0024 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/mixnet_query_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/mixnet_query_client.rs @@ -1,9 +1,10 @@ -// Copyright 2022 - Nym Technologies SA +// Copyright 2022-2023 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -pub use crate::nyxd::cosmwasm_client::client::CosmWasmClient; +use crate::define_paged_response; +use crate::nyxd::contract_traits::NymContractsProvider; use crate::nyxd::error::NyxdError; -use crate::nyxd::NyxdClient; +use crate::nyxd::CosmWasmClient; use async_trait::async_trait; use cosmrs::AccountId; use nym_contracts_common::signing::Nonce; @@ -93,8 +94,8 @@ pub trait MixnetQueryClient { async fn get_all_family_members_paged( &self, - start_after: Option, limit: Option, + start_after: Option, ) -> Result { self.query_mixnet_contract(MixnetQueryMsg::GetAllMembersPaged { limit, start_after }) .await @@ -435,46 +436,177 @@ pub trait MixnetQueryClient { async fn get_node_family_by_label( &self, - label: &str, + label: String, ) -> Result { - self.query_mixnet_contract(MixnetQueryMsg::GetFamilyByLabel { - label: label.to_string(), - }) - .await + self.query_mixnet_contract(MixnetQueryMsg::GetFamilyByLabel { label }) + .await } - async fn get_node_family_by_head(&self, head: &str) -> Result { - self.query_mixnet_contract(MixnetQueryMsg::GetFamilyByHead { - head: head.to_string(), - }) - .await - } -} - -#[async_trait] -impl MixnetQueryClient for NyxdClient -where - C: CosmWasmClient + Sync + Send, -{ - async fn query_mixnet_contract(&self, query: MixnetQueryMsg) -> Result - where - for<'a> T: Deserialize<'a>, - { - self.client - .query_contract_smart(self.mixnet_contract_address(), &query) + async fn get_node_family_by_head( + &self, + head: String, + ) -> Result { + self.query_mixnet_contract(MixnetQueryMsg::GetFamilyByHead { head }) .await } } +// extension trait to the query client to deal with the paged queries +// (it didn't feel appropriate to combine it with the existing trait #[async_trait] -impl MixnetQueryClient for crate::Client +pub trait PagedMixnetClient: MixnetQueryClient + Send + Sync { + // async fn get_all_node_families(&self) -> Result, NyxdError> { + // let mut res = Vec::new(); + // let mut start_after = None; + // + // loop { + // let paged_response = self + // .get_all_node_families_paged(start_after.take(), None) + // .await?; + // res.extend(paged_response.families); + // + // if let Some(start_next_after) = paged_response.start_next_after { + // start_after = Some(start_next_after) + // } else { + // break; + // } + // } + // + // Ok(res) + // } + + // define_paged_response!( + // get_all_node_families, + // Family, + // get_all_node_families_paged, + // families + // ); +} + +#[async_trait] +impl PagedMixnetClient for T where T: MixnetQueryClient {} + +#[async_trait] +impl MixnetQueryClient for C where - C: CosmWasmClient + Sync + Send, + C: CosmWasmClient + NymContractsProvider + Send + Sync, { async fn query_mixnet_contract(&self, query: MixnetQueryMsg) -> Result where for<'a> T: Deserialize<'a>, { - self.nyxd.query_mixnet_contract(query).await + let mixnet_contract_address = &self + .mixnet_contract_address() + .ok_or_else(|| NyxdError::unavailable_contract_address("mixnet contract"))?; + self.query_contract_smart(mixnet_contract_address, &query) + .await + } +} + +#[cfg(test)] +mod tests { + use super::*; + + // it's enough that this compiles + #[deprecated] + async fn all_query_variants_are_covered( + client: C, + msg: MixnetQueryMsg, + ) { + todo!() + // match msg { + // MixnetQueryMsg::GetAllFamiliesPaged { limit, start_after } => client + // .get_all_family_members_paged(limit, start_after) + // .await + // .map(|_| ()), + // MixnetQueryMsg::GetAllMembersPaged { limit, start_after } => client + // .get_all_family_members_paged(limit, start_after) + // .await + // .map(|_| ()), + // MixnetQueryMsg::GetFamilyByHead { head } => { + // client.get_node_family_by_head(head).await.map(|_| ()) + // } + // MixnetQueryMsg::GetFamilyByLabel { label } => { + // client.get_node_family_by_label(label).await.map(|_| ()) + // } + // MixnetQueryMsg::GetFamilyMembersByHead { head } => todo!(), + // MixnetQueryMsg::GetFamilyMembersByLabel { label } => todo!(), + // MixnetQueryMsg::GetContractVersion {} => { + // client.get_mixnet_contract_version().await.map(|_| ()) + // } + // MixnetQueryMsg::GetCW2ContractVersion {} => todo!(), + // MixnetQueryMsg::GetRewardingValidatorAddress {} => { + // client.get_rewarding_validator_address().await.map(|_| ()) + // } + // MixnetQueryMsg::GetStateParams {} => todo!(), + // MixnetQueryMsg::GetState {} => client.get_mixnet_contract_state().await.map(|_| ()), + // MixnetQueryMsg::GetRewardingParams {} => {} + // MixnetQueryMsg::GetEpochStatus {} => {} + // MixnetQueryMsg::GetCurrentIntervalDetails {} => {} + // MixnetQueryMsg::GetRewardedSet { limit, start_after } => {} + // MixnetQueryMsg::GetMixNodeBonds { limit, start_after } => {} + // MixnetQueryMsg::GetMixNodesDetailed { limit, start_after } => {} + // MixnetQueryMsg::GetUnbondedMixNodes { limit, start_after } => {} + // MixnetQueryMsg::GetUnbondedMixNodesByOwner { + // owner, + // limit, + // start_after, + // } => {} + // MixnetQueryMsg::GetUnbondedMixNodesByIdentityKey { + // identity_key, + // limit, + // start_after, + // } => {} + // MixnetQueryMsg::GetOwnedMixnode { address } => {} + // MixnetQueryMsg::GetMixnodeDetails { mix_id } => {} + // MixnetQueryMsg::GetMixnodeRewardingDetails { mix_id } => {} + // MixnetQueryMsg::GetStakeSaturation { mix_id } => {} + // MixnetQueryMsg::GetUnbondedMixNodeInformation { mix_id } => {} + // MixnetQueryMsg::GetBondedMixnodeDetailsByIdentity { mix_identity } => {} + // MixnetQueryMsg::GetLayerDistribution {} => {} + // MixnetQueryMsg::GetGateways { start_after, limit } => {} + // MixnetQueryMsg::GetGatewayBond { identity } => {} + // MixnetQueryMsg::GetOwnedGateway { address } => {} + // MixnetQueryMsg::GetMixnodeDelegations { + // mix_id, + // start_after, + // limit, + // } => {} + // MixnetQueryMsg::GetDelegatorDelegations { + // delegator, + // start_after, + // limit, + // } => {} + // MixnetQueryMsg::GetDelegationDetails { + // mix_id, + // delegator, + // proxy, + // } => {} + // MixnetQueryMsg::GetAllDelegations { start_after, limit } => {} + // MixnetQueryMsg::GetPendingOperatorReward { address } => {} + // MixnetQueryMsg::GetPendingMixNodeOperatorReward { mix_id } => {} + // MixnetQueryMsg::GetPendingDelegatorReward { + // address, + // mix_id, + // proxy, + // } => {} + // MixnetQueryMsg::GetEstimatedCurrentEpochOperatorReward { + // mix_id, + // estimated_performance, + // } => {} + // MixnetQueryMsg::GetEstimatedCurrentEpochDelegatorReward { + // address, + // mix_id, + // proxy, + // estimated_performance, + // } => {} + // MixnetQueryMsg::GetPendingEpochEvents { limit, start_after } => {} + // MixnetQueryMsg::GetPendingIntervalEvents { limit, start_after } => {} + // MixnetQueryMsg::GetPendingEpochEvent { event_id } => {} + // MixnetQueryMsg::GetPendingIntervalEvent { event_id } => {} + // MixnetQueryMsg::GetNumberOfPendingEvents {} => {} + // MixnetQueryMsg::GetSigningNonce { address } => {} + // } + // .expect("ignore error") } } diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/mod.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/mod.rs index 9f6dac5354..cf75c407af 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/mod.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/mod.rs @@ -1,7 +1,11 @@ // Copyright 2021-2023 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -// TODO: expose query-related capabilities to wasm client... +use cosmrs::AccountId; +use nym_network_defaults::NymContracts; +use std::str::FromStr; + +// TODO: all of those could/should be derived via a macro mod coconut_bandwidth_query_client; mod dkg_query_client; @@ -12,20 +16,20 @@ mod name_service_query_client; mod sp_directory_query_client; mod vesting_query_client; -#[cfg(feature = "signing")] -mod coconut_bandwidth_signing_client; -#[cfg(feature = "signing")] -mod dkg_signing_client; -#[cfg(feature = "signing")] -mod mixnet_signing_client; -#[cfg(feature = "signing")] -mod multisig_signing_client; -#[cfg(feature = "signing")] -mod name_service_signing_client; -#[cfg(feature = "signing")] -mod sp_directory_signing_client; -#[cfg(feature = "signing")] -mod vesting_signing_client; +// #[cfg(feature = "signing")] +// mod coconut_bandwidth_signing_client; +// #[cfg(feature = "signing")] +// mod dkg_signing_client; +// #[cfg(feature = "signing")] +// mod mixnet_signing_client; +// #[cfg(feature = "signing")] +// mod multisig_signing_client; +// #[cfg(feature = "signing")] +// mod name_service_signing_client; +// #[cfg(feature = "signing")] +// mod sp_directory_signing_client; +// #[cfg(feature = "signing")] +// mod vesting_signing_client; pub use coconut_bandwidth_query_client::CoconutBandwidthQueryClient; pub use dkg_query_client::DkgQueryClient; @@ -36,17 +40,112 @@ pub use name_service_query_client::NameServiceQueryClient; pub use sp_directory_query_client::SpDirectoryQueryClient; pub use vesting_query_client::VestingQueryClient; -#[cfg(feature = "signing")] -pub use coconut_bandwidth_signing_client::CoconutBandwidthSigningClient; -#[cfg(feature = "signing")] -pub use dkg_signing_client::DkgSigningClient; -#[cfg(feature = "signing")] -pub use mixnet_signing_client::MixnetSigningClient; -#[cfg(feature = "signing")] -pub use multisig_signing_client::MultisigSigningClient; -#[cfg(feature = "signing")] -pub use name_service_signing_client::NameServiceSigningClient; -#[cfg(feature = "signing")] -pub use sp_directory_signing_client::SpDirectorySigningClient; -#[cfg(feature = "signing")] -pub use vesting_signing_client::VestingSigningClient; +// #[cfg(feature = "signing")] +// pub use coconut_bandwidth_signing_client::CoconutBandwidthSigningClient; +// #[cfg(feature = "signing")] +// pub use dkg_signing_client::DkgSigningClient; +// #[cfg(feature = "signing")] +// pub use mixnet_signing_client::MixnetSigningClient; +// #[cfg(feature = "signing")] +// pub use multisig_signing_client::MultisigSigningClient; +// #[cfg(feature = "signing")] +// pub use name_service_signing_client::NameServiceSigningClient; +// #[cfg(feature = "signing")] +// pub use sp_directory_signing_client::SpDirectorySigningClient; +// #[cfg(feature = "signing")] +// pub use vesting_signing_client::VestingSigningClient; + +pub trait NymContractsProvider { + // main + fn mixnet_contract_address(&self) -> Option<&AccountId>; + fn vesting_contract_address(&self) -> Option<&AccountId>; + + // coconut-related + fn coconut_bandwidth_contract_address(&self) -> Option<&AccountId>; + fn dkg_contract_address(&self) -> Option<&AccountId>; + fn group_contract_address(&self) -> Option<&AccountId>; + fn multisig_contract_address(&self) -> Option<&AccountId>; + + // SPs + fn name_service_contract_address(&self) -> Option<&AccountId>; + fn service_provider_contract_address(&self) -> Option<&AccountId>; +} + +#[derive(Debug, Clone)] +pub struct TypedNymContracts { + pub mixnet_contract_address: Option, + pub vesting_contract_address: Option, + + pub coconut_bandwidth_contract_address: Option, + pub group_contract_address: Option, + pub multisig_contract_address: Option, + pub coconut_dkg_contract_address: Option, + + pub service_provider_directory_contract_address: Option, + pub name_service_contract_address: Option, +} + +impl TryFrom for TypedNymContracts { + type Error = ::Err; + + fn try_from(value: NymContracts) -> Result { + Ok(TypedNymContracts { + mixnet_contract_address: value + .mixnet_contract_address + .map(|addr| addr.parse()) + .transpose()?, + vesting_contract_address: value + .vesting_contract_address + .map(|addr| addr.parse()) + .transpose()?, + coconut_bandwidth_contract_address: value + .coconut_bandwidth_contract_address + .map(|addr| addr.parse()) + .transpose()?, + group_contract_address: value + .group_contract_address + .map(|addr| addr.parse()) + .transpose()?, + multisig_contract_address: value + .multisig_contract_address + .map(|addr| addr.parse()) + .transpose()?, + coconut_dkg_contract_address: value + .coconut_dkg_contract_address + .map(|addr| addr.parse()) + .transpose()?, + service_provider_directory_contract_address: value + .service_provider_directory_contract_address + .map(|addr| addr.parse()) + .transpose()?, + name_service_contract_address: value + .name_service_contract_address + .map(|addr| addr.parse()) + .transpose()?, + }) + } +} + +// a simple helper macro to define a function to repeatedly call a paged query until a full response is constructed +#[macro_export] +macro_rules! define_paged_response { + ( $f: ident, $r: ty, $fc: ident, $field: ident ) => { + async fn $f(&self) -> Result, NyxdError> { + let mut res = Vec::new(); + let mut start_after = None; + + loop { + let paged_response = self.$fc(start_after.take(), None).await?; + res.extend(paged_response.$field); + + if let Some(start_next_after) = paged_response.start_next_after { + start_after = Some(start_next_after) + } else { + break; + } + } + + Ok(res) + } + }; +} diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/multisig_query_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/multisig_query_client.rs index ea461d1080..f25a4f9a64 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/multisig_query_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/multisig_query_client.rs @@ -1,23 +1,93 @@ -// Copyright 2022 - Nym Technologies SA +// Copyright 2022-2023 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 +use crate::nyxd::contract_traits::NymContractsProvider; use crate::nyxd::error::NyxdError; -use crate::nyxd::{CosmWasmClient, NyxdClient}; - -use cw3::{ProposalListResponse, ProposalResponse}; -use nym_multisig_contract_common::msg::QueryMsg; - +use crate::nyxd::CosmWasmClient; use async_trait::async_trait; +use cw3::{ + ProposalListResponse, ProposalResponse, VoteListResponse, VoteResponse, VoterListResponse, + VoterResponse, +}; +use cw_utils::ThresholdResponse; +use nym_multisig_contract_common::msg::QueryMsg as MultisigQueryMsg; +use serde::Deserialize; #[async_trait] pub trait MultisigQueryClient { - async fn get_proposal(&self, proposal_id: u64) -> Result; + async fn query_multisig_contract(&self, query: MultisigQueryMsg) -> Result + where + for<'a> T: Deserialize<'a>; + + async fn query_threshold(&self) -> Result { + self.query_multisig_contract(MultisigQueryMsg::Threshold {}) + .await + } + + async fn query_proposal(&self, proposal_id: u64) -> Result { + self.query_multisig_contract(MultisigQueryMsg::Proposal { proposal_id }) + .await + } async fn list_proposals( &self, start_after: Option, limit: Option, - ) -> Result; + ) -> Result { + self.query_multisig_contract(MultisigQueryMsg::ListProposals { start_after, limit }) + .await + } + + async fn reverse_proposals( + &self, + start_before: Option, + limit: Option, + ) -> Result { + self.query_multisig_contract(MultisigQueryMsg::ReverseProposals { + start_before, + limit, + }) + .await + } + + async fn query_vote(&self, proposal_id: u64, voter: String) -> Result { + self.query_multisig_contract(MultisigQueryMsg::Vote { proposal_id, voter }) + .await + } + + async fn list_votes( + &self, + proposal_id: u64, + start_after: Option, + limit: Option, + ) -> Result { + self.query_multisig_contract(MultisigQueryMsg::ListVotes { + proposal_id, + start_after, + limit, + }) + .await + } + + async fn query_voter(&self, address: String) -> Result { + self.query_multisig_contract(MultisigQueryMsg::Voter { address }) + .await + } + + async fn list_voters( + &self, + start_after: Option, + limit: Option, + ) -> Result { + self.query_multisig_contract(MultisigQueryMsg::ListVoters { start_after, limit }) + .await + } + + // technically it's not deprecated, just not implemented, but I need clippy to point it out to me before I make a PR + #[deprecated] + async fn query_config(&self) -> Result<(), NyxdError> { + unimplemented!() + } async fn get_all_proposals(&self) -> Result, NyxdError> { let mut proposals = Vec::new(); @@ -41,22 +111,63 @@ pub trait MultisigQueryClient { } #[async_trait] -impl MultisigQueryClient for NyxdClient { - async fn get_proposal(&self, proposal_id: u64) -> Result { - let request = QueryMsg::Proposal { proposal_id }; - self.client - .query_contract_smart(self.multisig_contract_address(), &request) - .await - } - - async fn list_proposals( - &self, - start_after: Option, - limit: Option, - ) -> Result { - let request = QueryMsg::ListProposals { start_after, limit }; - self.client - .query_contract_smart(self.multisig_contract_address(), &request) +impl MultisigQueryClient for C +where + C: CosmWasmClient + NymContractsProvider + Send + Sync, +{ + async fn query_multisig_contract(&self, query: MultisigQueryMsg) -> Result + where + for<'a> T: Deserialize<'a>, + { + let multisig_contract_address = &self + .multisig_contract_address() + .ok_or_else(|| NyxdError::unavailable_contract_address("multisig contract"))?; + self.query_contract_smart(multisig_contract_address, &query) .await } } + +#[cfg(test)] +mod tests { + use super::*; + + // it's enough that this compiles + async fn all_query_variants_are_covered( + client: C, + msg: MultisigQueryMsg, + ) { + match msg { + MultisigQueryMsg::Threshold {} => client.query_threshold().await.map(|_| ()), + MultisigQueryMsg::Proposal { proposal_id } => { + client.query_proposal(proposal_id).await.map(|_| ()) + } + MultisigQueryMsg::ListProposals { start_after, limit } => { + client.list_proposals(start_after, limit).await.map(|_| ()) + } + MultisigQueryMsg::ReverseProposals { + start_before, + limit, + } => client + .reverse_proposals(start_before, limit) + .await + .map(|_| ()), + MultisigQueryMsg::Vote { proposal_id, voter } => { + client.query_vote(proposal_id, voter).await.map(|_| ()) + } + MultisigQueryMsg::ListVotes { + proposal_id, + start_after, + limit, + } => client + .list_votes(proposal_id, start_after, limit) + .await + .map(|_| ()), + MultisigQueryMsg::Voter { address } => client.query_voter(address).await.map(|_| ()), + MultisigQueryMsg::ListVoters { start_after, limit } => { + client.list_voters(start_after, limit).await.map(|_| ()) + } + MultisigQueryMsg::Config {} => client.query_config().await.map(|_| ()), + } + .expect("ignore error") + } +} diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/name_service_query_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/name_service_query_client.rs index 1cb59711ff..4f53fa52dc 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/name_service_query_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/name_service_query_client.rs @@ -1,3 +1,8 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::nyxd::contract_traits::NymContractsProvider; +use crate::nyxd::{error::NyxdError, CosmWasmClient}; use async_trait::async_trait; use cosmrs::AccountId; use nym_contracts_common::{signing::Nonce, ContractBuildInformation}; @@ -8,8 +13,6 @@ use nym_name_service_common::{ }; use serde::Deserialize; -use crate::nyxd::{error::NyxdError, CosmWasmClient, NyxdClient}; - #[async_trait] pub trait NameServiceQueryClient { async fn query_name_service_contract(&self, query: NameQueryMsg) -> Result @@ -81,36 +84,33 @@ pub trait NameServiceQueryClient { .await } } - #[async_trait] -impl NameServiceQueryClient for NyxdClient +impl NameServiceQueryClient for C where - C: CosmWasmClient + Send + Sync, + C: CosmWasmClient + NymContractsProvider + Send + Sync, { async fn query_name_service_contract(&self, query: NameQueryMsg) -> Result where for<'a> T: Deserialize<'a>, { - self.client - .query_contract_smart( - self.name_service_contract_address().ok_or( - NyxdError::NoContractAddressAvailable("name service contract".to_string()), - )?, - &query, - ) + let name_service_contract_address = &self + .name_service_contract_address() + .ok_or_else(|| NyxdError::unavailable_contract_address("name service contract"))?; + self.query_contract_smart(name_service_contract_address, &query) .await } } -#[async_trait] -impl NameServiceQueryClient for crate::Client -where - C: CosmWasmClient + Send + Sync, -{ - async fn query_name_service_contract(&self, query: NameQueryMsg) -> Result - where - for<'a> T: Deserialize<'a>, - { - self.nyxd.query_name_service_contract(query).await +#[cfg(test)] +mod tests { + use super::*; + + // it's enough that this compiles + #[deprecated] + async fn all_query_variants_are_covered( + client: C, + msg: NameQueryMsg, + ) { + unimplemented!() } } diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/sp_directory_query_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/sp_directory_query_client.rs index 0ed99d5c1c..a292cb1121 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/sp_directory_query_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/sp_directory_query_client.rs @@ -10,6 +10,7 @@ use nym_service_provider_directory_common::{ }; use serde::Deserialize; +use crate::nyxd::contract_traits::NymContractsProvider; use crate::nyxd::{error::NyxdError, CosmWasmClient, NyxdClient}; #[async_trait] @@ -89,36 +90,33 @@ pub trait SpDirectoryQueryClient { } #[async_trait] -impl SpDirectoryQueryClient for NyxdClient +impl SpDirectoryQueryClient for C where - C: CosmWasmClient + Send + Sync, + C: CosmWasmClient + NymContractsProvider + Send + Sync, { async fn query_service_provider_contract(&self, query: SpQueryMsg) -> Result where for<'a> T: Deserialize<'a>, { - self.client - .query_contract_smart( - self.service_provider_contract_address().ok_or( - NyxdError::NoContractAddressAvailable( - "service provider directory contract".to_string(), - ), - )?, - &query, - ) + let sp_directory_contract_address = + &self.service_provider_contract_address().ok_or_else(|| { + NyxdError::unavailable_contract_address("service provider directory contract") + })?; + self.query_contract_smart(sp_directory_contract_address, &query) .await } } -#[async_trait] -impl SpDirectoryQueryClient for crate::Client -where - C: CosmWasmClient + Send + Sync, -{ - async fn query_service_provider_contract(&self, query: SpQueryMsg) -> Result - where - for<'a> T: Deserialize<'a>, - { - self.nyxd.query_service_provider_contract(query).await +#[cfg(test)] +mod tests { + use super::*; + + // it's enough that this compiles + #[deprecated] + async fn all_query_variants_are_covered( + client: C, + msg: SpQueryMsg, + ) { + unimplemented!() } } diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/vesting_query_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/vesting_query_client.rs index c70f0a78ca..df073b4e45 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/vesting_query_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/vesting_query_client.rs @@ -1,10 +1,10 @@ -// Copyright 2021 - Nym Technologies SA +// Copyright 2021-2023 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 use crate::nyxd::coin::Coin; -pub use crate::nyxd::cosmwasm_client::client::CosmWasmClient; +use crate::nyxd::contract_traits::NymContractsProvider; use crate::nyxd::error::NyxdError; -use crate::nyxd::NyxdClient; +use crate::nyxd::{CosmWasmClient, NyxdClient}; use async_trait::async_trait; use cosmwasm_std::{Coin as CosmWasmCoin, Timestamp}; use nym_contracts_common::ContractBuildInformation; @@ -334,13 +334,32 @@ pub trait VestingQueryClient { } #[async_trait] -impl VestingQueryClient for NyxdClient { +impl VestingQueryClient for C +where + C: CosmWasmClient + NymContractsProvider + Send + Sync, +{ async fn query_vesting_contract(&self, query: VestingQueryMsg) -> Result where for<'a> T: Deserialize<'a>, { - self.client - .query_contract_smart(self.vesting_contract_address(), &query) + let vesting_contract_address = &self + .vesting_contract_address() + .ok_or_else(|| NyxdError::unavailable_contract_address("vesting contract"))?; + self.query_contract_smart(vesting_contract_address, &query) .await } } + +#[cfg(test)] +mod tests { + use super::*; + + // it's enough that this compiles + #[deprecated] + async fn all_query_variants_are_covered( + client: C, + msg: VestingQueryMsg, + ) { + unimplemented!() + } +} diff --git a/common/client-libs/validator-client/src/nyxd/cosmwasm_client/client_traits/mod.rs b/common/client-libs/validator-client/src/nyxd/cosmwasm_client/client_traits/mod.rs new file mode 100644 index 0000000000..1fc9b3789d --- /dev/null +++ b/common/client-libs/validator-client/src/nyxd/cosmwasm_client/client_traits/mod.rs @@ -0,0 +1,12 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +pub mod query_client; + +#[cfg(feature = "signing")] +pub mod signing_client; + +pub use query_client::CosmWasmClient; + +#[cfg(feature = "signing")] +pub use signing_client::SigningCosmWasmClient; diff --git a/common/client-libs/validator-client/src/nyxd/cosmwasm_client/client.rs b/common/client-libs/validator-client/src/nyxd/cosmwasm_client/client_traits/query_client.rs similarity index 95% rename from common/client-libs/validator-client/src/nyxd/cosmwasm_client/client.rs rename to common/client-libs/validator-client/src/nyxd/cosmwasm_client/client_traits/query_client.rs index 9ca497e1c8..46073a2671 100644 --- a/common/client-libs/validator-client/src/nyxd/cosmwasm_client/client.rs +++ b/common/client-libs/validator-client/src/nyxd/cosmwasm_client/client_traits/query_client.rs @@ -1,4 +1,4 @@ -// Copyright 2021-2023 - Nym Technologies SA +// Copyright 2023 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 use crate::nyxd; @@ -39,25 +39,15 @@ use tendermint_rpc::{ Order, }; +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 { - fn broadcast_polling_rate(&self) -> Duration { - Duration::from_secs(4) - } - - fn broadcast_timeout(&self) -> Duration { - Duration::from_secs(60) - } -} +impl CosmWasmClient for cosmrs::rpc::HttpClient {} #[async_trait] pub trait CosmWasmClient: TendermintClient { - // this should probably get redesigned, but I'm leaving those like that temporarily to fix - // the underlying issue more quickly - fn broadcast_polling_rate(&self) -> Duration; - fn broadcast_timeout(&self) -> Duration; - // helper method to remove duplicate code involved in making abci requests with protobuf messages // TODO: perhaps it should have an additional argument to determine whether the response should // require proof? @@ -268,10 +258,20 @@ pub trait CosmWasmClient: TendermintClient { Ok(tendermint_rpc::client::Client::broadcast_tx_commit(self, tx).await?) } - async fn broadcast_tx(&self, tx: T) -> Result + async fn broadcast_tx( + &self, + tx: T, + timeout: impl Into> + Send, + poll_interval: impl Into> + Send, + ) -> Result where T: Into> + Send, { + let timeout = timeout.into().unwrap_or(DEFAULT_BROADCAST_TIMEOUT); + let poll_interval = poll_interval + .into() + .unwrap_or(DEFAULT_BROADCAST_POLLING_RATE); + let broadcasted = CosmWasmClient::broadcast_tx_sync(self, tx).await?; if broadcasted.code.is_err() { @@ -292,10 +292,10 @@ pub trait CosmWasmClient: TendermintClient { "Polling for result of including {} in a block...", broadcasted.hash ); - if tokio::time::Instant::now().duration_since(start) >= self.broadcast_timeout() { + if tokio::time::Instant::now().duration_since(start) >= timeout { return Err(NyxdError::BroadcastTimeout { hash: tx_hash, - timeout: self.broadcast_timeout(), + timeout, }); } @@ -303,7 +303,7 @@ pub trait CosmWasmClient: TendermintClient { return Ok(poll_res); } - tokio::time::sleep(self.broadcast_polling_rate()).await; + tokio::time::sleep(poll_interval).await; } } diff --git a/common/client-libs/validator-client/src/nyxd/cosmwasm_client/signing_client.rs b/common/client-libs/validator-client/src/nyxd/cosmwasm_client/client_traits/signing_client.rs similarity index 86% rename from common/client-libs/validator-client/src/nyxd/cosmwasm_client/signing_client.rs rename to common/client-libs/validator-client/src/nyxd/cosmwasm_client/client_traits/signing_client.rs index f4d6a41829..a73f987936 100644 --- a/common/client-libs/validator-client/src/nyxd/cosmwasm_client/signing_client.rs +++ b/common/client-libs/validator-client/src/nyxd/cosmwasm_client/client_traits/signing_client.rs @@ -1,7 +1,7 @@ -// Copyright 2021-2023 - Nym Technologies SA +// Copyright 2023 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use crate::nyxd::cosmwasm_client::client::CosmWasmClient; +use crate::nyxd::cosmwasm_client::client_traits::CosmWasmClient; use crate::nyxd::cosmwasm_client::helpers::{compress_wasm_code, CheckResponse}; use crate::nyxd::cosmwasm_client::logs::{self, parse_raw_logs}; use crate::nyxd::cosmwasm_client::types::*; @@ -9,6 +9,7 @@ use crate::nyxd::error::NyxdError; use crate::nyxd::fee::{Fee, DEFAULT_SIMULATED_GAS_MULTIPLIER}; use crate::nyxd::{Coin, GasAdjustable, GasPrice, TxResponse}; use crate::signing::signer::OfflineSigner; +use crate::signing::tx_signer::TxSigner; use crate::signing::SignerData; use async_trait::async_trait; use cosmrs::abci::GasInfo; @@ -26,21 +27,9 @@ use serde::Serialize; use sha2::Digest; use sha2::Sha256; use std::convert::TryInto; -use std::time::{Duration, SystemTime}; +use std::time::SystemTime; use tendermint_rpc::endpoint::broadcast; -#[cfg(feature = "http-client")] -use crate::signing::tx_signer::TxSigner; - -#[cfg(feature = "http-client")] -use tendermint_rpc::{Error as TendermintRpcError, SimpleRequest}; - -#[cfg(feature = "http-client")] -use cosmrs::rpc::{HttpClient, HttpClientUrl}; - -pub const DEFAULT_BROADCAST_POLLING_RATE: Duration = Duration::from_secs(4); -pub const DEFAULT_BROADCAST_TIMEOUT: Duration = Duration::from_secs(60); - fn empty_fee() -> tx::Fee { tx::Fee { amount: vec![], @@ -65,15 +54,16 @@ fn single_unspecified_signer_auth( } #[async_trait] -pub trait SigningCosmWasmClient: CosmWasmClient { - type Signer: OfflineSigner + Send + Sync; - - fn signer(&self) -> &Self::Signer; - +pub trait SigningCosmWasmClient: CosmWasmClient + TxSigner +where + NyxdError: From<::Error>, +{ + // TODO: would it somehow be possible to get rid of this method and allow for + // blanket implementation for anything that provides CosmWasmClient + TxSigner? fn gas_price(&self) -> &GasPrice; fn signer_public_key(&self, signer_address: &AccountId) -> Option { - let account = self.signer().find_account(signer_address).ok()?; + let account = self.find_account(signer_address).ok()?; Some(account.public_key().into()) } @@ -587,9 +577,9 @@ pub trait SigningCosmWasmClient: CosmWasmClient { let multiplier = multiplier.unwrap_or(DEFAULT_SIMULATED_GAS_MULTIPLIER); let gas = gas_estimation.adjust_gas(multiplier); - debug!("Gas estimation: {}", gas_estimation); - debug!("Multiplying the estimation by {}", multiplier); - debug!("Final gas limit used: {}", gas); + debug!("Gas estimation: {gas_estimation}"); + debug!("Multiplying the estimation by {multiplier}"); + debug!("Final gas limit used: {gas}"); let fee = self.gas_price() * gas; Ok::(tx::Fee::from_amount_and_gas(fee, gas)) @@ -687,7 +677,7 @@ pub trait SigningCosmWasmClient: CosmWasmClient { .to_bytes() .map_err(|_| NyxdError::SerializationError("Tx".to_owned()))?; - self.broadcast_tx(tx_bytes).await + self.broadcast_tx(tx_bytes, None, None).await } async fn sign( @@ -710,161 +700,14 @@ pub trait SigningCosmWasmClient: CosmWasmClient { } }; - self.sign_direct(signer_address, messages, fee, memo, signer_data) - } - - fn sign_amino( - &self, - signer_address: &AccountId, - messages: Vec, - fee: tx::Fee, - memo: impl Into + Send + 'static, - signer_data: SignerData, - ) -> Result; - - fn sign_direct( - &self, - signer_address: &AccountId, - messages: Vec, - fee: tx::Fee, - memo: impl Into + Send + 'static, - signer_data: SignerData, - ) -> Result; -} - -#[cfg(feature = "http-client")] -#[derive(Debug)] -pub struct Client { - // TODO: somehow nicely hide this guy if we decide to use our client in offline mode, - // maybe just convert it into an option? - // or maybe we need another level of indirection. tbd. - rpc_client: HttpClient, - tx_signer: TxSigner, - gas_price: GasPrice, - - broadcast_polling_rate: Duration, - broadcast_timeout: Duration, -} - -#[cfg(feature = "http-client")] -impl Client { - pub fn connect_with_signer( - endpoint: U, - signer: S, - gas_price: GasPrice, - ) -> Result - where - U: TryInto, - { - let rpc_client = HttpClient::new(endpoint)?; - Ok(Client { - rpc_client, - tx_signer: TxSigner::new(signer), - gas_price, - broadcast_polling_rate: DEFAULT_BROADCAST_POLLING_RATE, - broadcast_timeout: DEFAULT_BROADCAST_TIMEOUT, - }) - } - - pub fn offline(signer: S) -> TxSigner - where - S: OfflineSigner, - { - TxSigner::new(signer) - } - - pub fn change_endpoint(&mut self, new_endpoint: U) -> Result<(), NyxdError> - where - U: TryInto, - { - let new_rpc_client = HttpClient::new(new_endpoint)?; - self.rpc_client = new_rpc_client; - Ok(()) - } - - pub fn into_signer(self) -> S { - self.tx_signer.into_inner_signer() - } - - pub fn set_broadcast_polling_rate(&mut self, broadcast_polling_rate: Duration) { - self.broadcast_polling_rate = broadcast_polling_rate - } - - pub fn set_broadcast_timeout(&mut self, broadcast_timeout: Duration) { - self.broadcast_timeout = broadcast_timeout - } -} - -#[cfg(feature = "http-client")] -#[async_trait] -impl tendermint_rpc::client::Client for Client -where - S: Send + Sync, -{ - async fn perform(&self, request: R) -> Result - where - R: SimpleRequest, - { - self.rpc_client.perform(request).await - } -} - -#[cfg(feature = "http-client")] -#[async_trait] -impl CosmWasmClient for Client -where - S: Send + Sync, -{ - fn broadcast_polling_rate(&self) -> Duration { - self.broadcast_polling_rate - } - - fn broadcast_timeout(&self) -> Duration { - self.broadcast_timeout - } -} - -#[cfg(feature = "http-client")] -#[async_trait] -impl SigningCosmWasmClient for Client -where - S: OfflineSigner + Send + Sync, - NyxdError: From, -{ - type Signer = S; - - fn signer(&self) -> &Self::Signer { - self.tx_signer.signer() - } - - fn gas_price(&self) -> &GasPrice { - &self.gas_price - } - - fn sign_amino( - &self, - signer_address: &AccountId, - messages: Vec, - fee: tx::Fee, - memo: impl Into + Send + 'static, - signer_data: SignerData, - ) -> Result { - Ok(self - .tx_signer - .sign_amino(signer_address, messages, fee, memo, signer_data)?) - } - - fn sign_direct( - &self, - signer_address: &AccountId, - messages: Vec, - fee: tx::Fee, - memo: impl Into + Send + 'static, - signer_data: SignerData, - ) -> Result { - Ok(self - .tx_signer - .sign_direct(signer_address, messages, fee, memo, signer_data)?) + Ok(::sign_direct( + self, + signer_address, + messages, + fee, + memo, + signer_data, + )?) } } 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 0a2d2c7c32..be570d128d 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,37 +1,153 @@ // Copyright 2021 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -#[cfg(feature = "http-client")] +use crate::nyxd::cosmwasm_client::client_traits::{CosmWasmClient, SigningCosmWasmClient}; use crate::nyxd::error::NyxdError; -#[cfg(feature = "http-client")] -use cosmrs::rpc::{Error as TendermintRpcError, HttpClient, HttpClientUrl}; -#[cfg(feature = "http-client")] -use std::convert::TryInto; +use crate::nyxd::{Config, GasPrice, TendermintClient}; +use crate::signing::signer::{NoSigner, OfflineSigner}; +use crate::signing::tx_signer::TxSigner; +use crate::signing::AccountData; +use async_trait::async_trait; +use cosmrs::rpc::Error as TendermintRpcError; +use cosmrs::AccountId; +use tendermint_rpc::SimpleRequest; -pub mod client; +pub mod client_traits; mod helpers; pub mod logs; pub mod types; -#[cfg(feature = "signing")] -pub mod signing_client; - -#[cfg(feature = "http-client")] -pub fn connect(endpoint: U) -> Result -where - U: TryInto, -{ - Ok(HttpClient::new(endpoint)?) +#[derive(Debug)] +pub(crate) struct SigningClientOptions { + gas_price: GasPrice, } -#[cfg(all(feature = "signing", feature = "http-client"))] -pub fn connect_with_signer( - endpoint: U, +impl<'a> From<&'a Config> for SigningClientOptions { + fn from(value: &'a Config) -> Self { + SigningClientOptions { + gas_price: value.gas_price.clone(), + } + } +} + +// convenience wrapper around query client to allow for optional signing +#[derive(Debug)] +pub(crate) struct MaybeSigningClient { + client: C, signer: S, - gas_price: crate::nyxd::GasPrice, -) -> Result, NyxdError> -where - U: TryInto, -{ - signing_client::Client::connect_with_signer(endpoint, signer, gas_price) + opts: SigningClientOptions, + derived_addresses: Option>, } + +impl MaybeSigningClient { + pub(crate) fn new(client: C, opts: SigningClientOptions) -> Self { + MaybeSigningClient { + client, + signer: Default::default(), + opts, + derived_addresses: None, + } + } +} + +impl MaybeSigningClient { + pub(crate) fn new_signing( + client: C, + signer: S, + opts: SigningClientOptions, + ) -> Result + where + S: OfflineSigner, + { + let derived_addresses = signer + .get_accounts()? + .into_iter() + .map(|account| account.address) + .collect(); + Ok(MaybeSigningClient { + client, + signer, + opts, + derived_addresses: Some(derived_addresses), + }) + } + + pub(crate) fn derived_addresses(&self) -> &[AccountId] { + // the unwrap is fine here as you can't construct a signing client without setting the addresses + self.derived_addresses.as_ref().unwrap() + } +} + +#[async_trait] +impl TendermintClient for MaybeSigningClient +where + C: TendermintClient + Send + Sync, + S: Send + Sync, +{ + async fn perform(&self, request: R) -> Result + where + R: SimpleRequest, + { + self.client.perform(request).await + } +} + +#[async_trait] +impl CosmWasmClient for MaybeSigningClient +where + C: CosmWasmClient + Send + Sync, + S: Send + Sync, +{ +} + +impl OfflineSigner for MaybeSigningClient +where + C: CosmWasmClient, + S: OfflineSigner, +{ + type Error = S::Error; + + fn get_accounts(&self) -> Result, Self::Error> { + self.signer.get_accounts() + } +} + +impl TxSigner for MaybeSigningClient +where + C: CosmWasmClient, + S: OfflineSigner, +{ +} + +#[async_trait] +impl SigningCosmWasmClient for MaybeSigningClient +where + C: CosmWasmClient + Send + Sync, + S: OfflineSigner + Send + Sync, + NyxdError: From, +{ + fn gas_price(&self) -> &GasPrice { + &self.opts.gas_price + } +} + +// +// #[cfg(feature = "http-client")] +// pub fn connect(endpoint: U) -> Result, NyxdError> +// where +// U: TryInto, +// { +// Ok(HttpClient::new(endpoint)?) +// } +// +// #[cfg(all(feature = "signing", feature = "http-client"))] +// pub fn connect_with_signer( +// endpoint: U, +// signer: S, +// gas_price: crate::nyxd::GasPrice, +// ) -> Result, NyxdError> +// where +// U: TryInto, +// { +// signing_client::Client::connect_with_signer(endpoint, signer, gas_price) +// } diff --git a/common/client-libs/validator-client/src/nyxd/error.rs b/common/client-libs/validator-client/src/nyxd/error.rs index b63be6e75c..7a414a6914 100644 --- a/common/client-libs/validator-client/src/nyxd/error.rs +++ b/common/client-libs/validator-client/src/nyxd/error.rs @@ -224,4 +224,8 @@ impl NyxdError { _ => false, } } + + pub fn unavailable_contract_address>(contract_type: S) -> Self { + NyxdError::NoContractAddressAvailable(contract_type.into()) + } } diff --git a/common/client-libs/validator-client/src/nyxd/fee/gas_price.rs b/common/client-libs/validator-client/src/nyxd/fee/gas_price.rs index caccceb436..f6c0d83c24 100644 --- a/common/client-libs/validator-client/src/nyxd/fee/gas_price.rs +++ b/common/client-libs/validator-client/src/nyxd/fee/gas_price.rs @@ -6,6 +6,7 @@ use cosmrs::Coin; use cosmrs::Gas; use cosmwasm_std::{Decimal, Fraction, Uint128}; use nym_config::defaults; +use nym_network_defaults::{ChainDetails, NymNetworkDetails}; use std::ops::Mul; use std::str::FromStr; @@ -73,6 +74,19 @@ impl FromStr for GasPrice { } } +impl<'a> TryFrom<&'a NymNetworkDetails> for GasPrice { + type Error = NyxdError; + + fn try_from(value: &'a NymNetworkDetails) -> Result { + format!( + "{}{}", + value.default_gas_price_amount(), + value.chain_details.mix_denom.base + ) + .parse() + } +} + impl GasPrice { pub fn new_with_default_price(denom: &str) -> Result { format!("{}{}", defaults::GAS_PRICE_AMOUNT, denom).parse() diff --git a/common/client-libs/validator-client/src/nyxd/mod.rs b/common/client-libs/validator-client/src/nyxd/mod.rs index 934aeec8b2..3fb4cc9372 100644 --- a/common/client-libs/validator-client/src/nyxd/mod.rs +++ b/common/client-libs/validator-client/src/nyxd/mod.rs @@ -6,12 +6,11 @@ use crate::nyxd::error::NyxdError; use log::{debug, trace}; use nym_network_defaults::{ChainDetails, NymNetworkDetails}; use serde::{Deserialize, Serialize}; -use tendermint_rpc::{endpoint::block::Response as BlockResponse, query::Query}; +use tendermint_rpc::{ + endpoint::block::Response as BlockResponse, query::Query, HttpClient, HttpClientUrl, +}; -#[cfg(feature = "http-client")] -use tendermint_rpc::Error as TendermintRpcError; - -pub use crate::nyxd::cosmwasm_client::client::CosmWasmClient; +pub use crate::nyxd::cosmwasm_client::client_traits::{CosmWasmClient, SigningCosmWasmClient}; pub use crate::nyxd::fee::Fee; pub use coin::Coin; pub use cosmrs::bank::MsgSend; @@ -33,10 +32,8 @@ pub use tendermint_rpc::{ }; #[cfg(feature = "http-client")] -pub use cosmrs::rpc::{HttpClient as QueryNyxdClient, HttpClientUrl}; +use tendermint_rpc::Error as TendermintRpcError; -#[cfg(all(feature = "signing", feature = "http-client"))] -use crate::nyxd::cosmwasm_client::signing_client; #[cfg(feature = "signing")] use crate::nyxd::cosmwasm_client::types::{ ChangeAdminResult, ContractCodeId, ExecuteResult, InstantiateOptions, InstantiateResult, @@ -46,6 +43,7 @@ use crate::nyxd::cosmwasm_client::types::{ use crate::signing::direct_wallet::DirectSecp256k1HdWallet; #[cfg(all(feature = "signing", feature = "http-client"))] use crate::signing::signer::OfflineSigner; +use async_trait::async_trait; #[cfg(feature = "signing")] use cosmrs::cosmwasm; #[cfg(feature = "signing")] @@ -55,14 +53,10 @@ use cosmwasm_std::Addr; #[cfg(feature = "signing")] use std::time::SystemTime; -#[cfg(feature = "signing")] -pub use crate::nyxd::cosmwasm_client::signing_client::SigningCosmWasmClient; - -#[cfg(all(feature = "signing", feature = "http-client"))] -pub use signing_client::Client as SigningNyxdClient; - -#[cfg(all(feature = "signing", feature = "http-client"))] -pub type DirectSigningNyxdClient = SigningNyxdClient; +use crate::nyxd::contract_traits::{NymContractsProvider, TypedNymContracts}; +use crate::nyxd::cosmwasm_client::MaybeSigningClient; +use crate::nyxd::fee::DEFAULT_SIMULATED_GAS_MULTIPLIER; +use crate::signing::signer::NoSigner; pub mod coin; pub mod contract_traits; @@ -70,22 +64,24 @@ pub mod cosmwasm_client; pub mod error; pub mod fee; +// temp +#[deprecated] +type QueryNyxdClient = HttpClient; + +// helper types +#[cfg(all(feature = "signing", feature = "http-client"))] +pub type DirectSigningHttpNyxdClient = NyxdClient; +#[cfg(feature = "http-client")] +pub type QueryHttpNyxdClient = NyxdClient; + +// TODO: reqwest based for wasm + #[derive(Debug, Clone)] pub struct Config { pub(crate) chain_details: ChainDetails, - - // I'd love to have used `NymContracts` struct directly here instead, - // however, I'd really prefer to use something more strongly typed (i.e. AccountId vs String) - pub(crate) mixnet_contract_address: Option, - pub(crate) vesting_contract_address: Option, - pub(crate) coconut_bandwidth_contract_address: Option, - pub(crate) group_contract_address: Option, - pub(crate) multisig_contract_address: Option, - pub(crate) coconut_dkg_contract_address: Option, - pub(crate) service_provider_contract_address: Option, - pub(crate) name_service_contract_address: Option, - // TODO: add this in later commits - // pub(crate) gas_price: GasPrice, + pub(crate) contracts: TypedNymContracts, + pub(crate) gas_price: GasPrice, + pub(crate) simulated_gas_multiplier: f32, } impl Config { @@ -114,96 +110,64 @@ impl Config { } pub fn try_from_nym_network_details(details: &NymNetworkDetails) -> Result { - let prefix = &details.chain_details.bech32_account_prefix; Ok(Config { chain_details: details.chain_details.clone(), - mixnet_contract_address: Self::parse_optional_account( - details.contracts.mixnet_contract_address.as_ref(), - prefix, - )?, - vesting_contract_address: Self::parse_optional_account( - details.contracts.vesting_contract_address.as_ref(), - prefix, - )?, - coconut_bandwidth_contract_address: Self::parse_optional_account( - details - .contracts - .coconut_bandwidth_contract_address - .as_ref(), - prefix, - )?, - group_contract_address: Self::parse_optional_account( - details.contracts.group_contract_address.as_ref(), - prefix, - )?, - multisig_contract_address: Self::parse_optional_account( - details.contracts.multisig_contract_address.as_ref(), - prefix, - )?, - coconut_dkg_contract_address: Self::parse_optional_account( - details.contracts.coconut_dkg_contract_address.as_ref(), - prefix, - )?, - service_provider_contract_address: Self::parse_optional_account( - details - .contracts - .service_provider_directory_contract_address - .as_ref(), - prefix, - )?, - name_service_contract_address: Self::parse_optional_account( - details.contracts.name_service_contract_address.as_ref(), - prefix, - )?, + contracts: TypedNymContracts::try_from(details.contracts.clone())?, + gas_price: details.try_into()?, + simulated_gas_multiplier: DEFAULT_SIMULATED_GAS_MULTIPLIER, }) } } +// so youd have: +// for queries: +// NyxdClient +// NyxdClient +// +// for signing: +// NyxdClient +// NyxdClient + #[derive(Debug)] -pub struct NyxdClient { - client: C, +pub struct NyxdClient { + client: MaybeSigningClient, config: Config, - // TODO: refactor because that field is only really used for signing - #[allow(dead_code)] - client_address: Option>, - simulated_gas_multiplier: f32, } #[cfg(feature = "http-client")] -impl NyxdClient { - pub fn connect(config: Config, endpoint: U) -> Result, NyxdError> +impl NyxdClient { + pub fn connect(config: Config, endpoint: U) -> Result where U: TryInto, { + let client = HttpClient::new(endpoint)?; + Ok(NyxdClient { - client: QueryNyxdClient::new(endpoint)?, + client: MaybeSigningClient::new(client, (&config).into()), config, - client_address: None, - simulated_gas_multiplier: crate::nyxd::fee::DEFAULT_SIMULATED_GAS_MULTIPLIER, }) } } #[cfg(all(feature = "signing", feature = "http-client"))] -impl NyxdClient> { +impl NyxdClient { // TODO: rename this one pub fn connect_with_mnemonic( config: Config, endpoint: U, mnemonic: bip39::Mnemonic, - gas_price: Option, - ) -> Result>, NyxdError> + ) -> Result where U: TryInto, { let prefix = &config.chain_details.bech32_account_prefix; let wallet = DirectSecp256k1HdWallet::from_mnemonic(prefix, mnemonic); - Self::connect_with_signer(config, endpoint, wallet, gas_price) + Self::connect_with_signer(config, endpoint, wallet) } } #[cfg(all(feature = "signing", feature = "http-client"))] -impl NyxdClient> +impl NyxdClient where S: OfflineSigner, // I have no idea why S::Error: Into bound wouldn't do the trick @@ -214,319 +178,41 @@ where config: Config, endpoint: U, signer: S, - gas_price: Option, - ) -> Result>, NyxdError> + ) -> Result, NyxdError> where U: TryInto, { - let denom = &config.chain_details.mix_denom.base; - let client_address = signer - .get_accounts()? - .into_iter() - .map(|account| account.address) - .collect(); - let gas_price = gas_price.unwrap_or(GasPrice::new_with_default_price(denom)?); - + let client = HttpClient::new(endpoint)?; Ok(NyxdClient { - client: SigningNyxdClient::connect_with_signer(endpoint, signer, gas_price)?, + client: MaybeSigningClient::new_signing(client, signer, (&config).into())?, config, - client_address: Some(client_address), - simulated_gas_multiplier: crate::nyxd::fee::DEFAULT_SIMULATED_GAS_MULTIPLIER, }) } - #[cfg(feature = "http-client")] - pub fn change_endpoint(&mut self, new_endpoint: U) -> Result<(), NyxdError> + // #[cfg(feature = "http-client")] + // pub fn change_endpoint(&mut self, new_endpoint: U) -> Result<(), NyxdError> + // where + // U: TryInto, + // { + // self.client.change_endpoint(new_endpoint) + // } + + #[deprecated] + pub fn into_signer(self) -> S { + todo!() + // self.client.into_signer() + } +} + +// no trait bounds +impl NyxdClient { + pub(crate) fn change_endpoint(&mut self, new_endpoint: U) -> Result<(), NyxdError> where U: TryInto, { - self.client.change_endpoint(new_endpoint) + todo!() } - pub fn into_signer(self) -> S { - self.client.into_signer() - } -} - -#[cfg(feature = "signing")] -impl NyxdClient -where - C: SigningCosmWasmClient + Sync, -{ - pub fn address(&self) -> &AccountId - where - C: SigningCosmWasmClient, - { - // if this is a signing client (as required by the trait bound), it must have the address set - &self.client_address.as_ref().unwrap()[0] - } - - pub fn cw_address(&self) -> Addr - where - C: SigningCosmWasmClient, - { - // the call to unchecked is fine here as we're converting directly from `AccountId` - // which must have been a valid bech32 address - Addr::unchecked(self.address().as_ref()) - } - - pub async fn account_sequence(&self) -> Result - where - C: SigningCosmWasmClient + Sync, - { - self.client.get_sequence(self.address()).await - } - - pub fn signer(&self) -> &::Signer - where - C: SigningCosmWasmClient, - { - self.client.signer() - } - - pub fn gas_price(&self) -> &GasPrice - where - C: SigningCosmWasmClient, - { - self.client.gas_price() - } - - pub fn wrap_contract_execute_message( - &self, - contract_address: &AccountId, - msg: &M, - funds: Vec, - ) -> Result - where - C: SigningCosmWasmClient, - M: ?Sized + Serialize, - { - Ok(cosmwasm::MsgExecuteContract { - sender: self.address().clone(), - contract: contract_address.clone(), - msg: serde_json::to_vec(msg)?, - funds: funds.into_iter().map(Into::into).collect(), - }) - } - - pub async fn simulate(&self, messages: I) -> Result - where - C: SigningCosmWasmClient + Sync, - I: IntoIterator + Send, - M: Msg, - { - self.client - .simulate( - self.address(), - messages - .into_iter() - .map(|msg| msg.into_any()) - .collect::, _>>() - .map_err(|_| { - NyxdError::SerializationError("custom simulate messages".to_owned()) - })?, - "simulating execution of transactions", - ) - .await - } - - /// Send funds from one address to another - pub async fn send( - &self, - recipient: &AccountId, - amount: Vec, - memo: impl Into + Send + 'static, - fee: Option, - ) -> Result - where - C: SigningCosmWasmClient + Sync, - { - let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier))); - self.client - .send_tokens(self.address(), recipient, amount, fee, memo) - .await - } - - /// Send funds from one address to multiple others - pub async fn send_multiple( - &self, - msgs: Vec<(AccountId, Vec)>, - memo: impl Into + Send + 'static, - fee: Option, - ) -> Result - where - C: SigningCosmWasmClient + Sync, - { - let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier))); - self.client - .send_tokens_multiple(self.address(), msgs, fee, memo) - .await - } - - /// Grant a fee allowance from one address to another - pub async fn grant_allowance( - &self, - grantee: &AccountId, - spend_limit: Vec, - expiration: Option, - allowed_messages: Vec, - memo: impl Into + Send + 'static, - fee: Option, - ) -> Result - where - C: SigningCosmWasmClient + Sync, - { - let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier))); - self.client - .grant_allowance( - self.address(), - grantee, - spend_limit, - expiration, - allowed_messages, - fee, - memo, - ) - .await - } - - /// Revoke a fee allowance from one address to another - pub async fn revoke_allowance( - &self, - grantee: &AccountId, - memo: impl Into + Send + 'static, - fee: Option, - ) -> Result - where - C: SigningCosmWasmClient + Sync, - { - let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier))); - self.client - .revoke_allowance(self.address(), grantee, fee, memo) - .await - } - - pub async fn execute( - &self, - contract_address: &AccountId, - msg: &M, - fee: Option, - memo: impl Into + Send + 'static, - funds: Vec, - ) -> Result - where - C: SigningCosmWasmClient + Sync, - M: ?Sized + Serialize + Sync, - { - let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier))); - self.client - .execute(self.address(), contract_address, msg, fee, memo, funds) - .await - } - - pub async fn execute_multiple( - &self, - contract_address: &AccountId, - msgs: I, - fee: Option, - memo: impl Into + Send + 'static, - ) -> Result - where - C: SigningCosmWasmClient + Sync, - I: IntoIterator)> + Send, - M: Serialize, - { - let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier))); - self.client - .execute_multiple(self.address(), contract_address, msgs, fee, memo) - .await - } - - pub async fn upload( - &self, - wasm_code: Vec, - memo: impl Into + Send + 'static, - fee: Option, - ) -> Result - where - C: SigningCosmWasmClient + Sync, - { - let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier))); - self.client - .upload(self.address(), wasm_code, fee, memo) - .await - } - - pub async fn instantiate( - &self, - code_id: ContractCodeId, - msg: &M, - label: String, - memo: impl Into + Send + 'static, - options: Option, - fee: Option, - ) -> Result - where - C: SigningCosmWasmClient + Sync, - M: ?Sized + Serialize + Sync, - { - let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier))); - self.client - .instantiate(self.address(), code_id, msg, label, fee, memo, options) - .await - } - - pub async fn update_admin( - &self, - contract_address: &AccountId, - new_admin: &AccountId, - memo: impl Into + Send + 'static, - fee: Option, - ) -> Result - where - C: SigningCosmWasmClient + Sync, - { - let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier))); - self.client - .update_admin(self.address(), contract_address, new_admin, fee, memo) - .await - } - - pub async fn clear_admin( - &self, - contract_address: &AccountId, - memo: impl Into + Send + 'static, - fee: Option, - ) -> Result - where - C: SigningCosmWasmClient + Sync, - { - let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier))); - self.client - .clear_admin(self.address(), contract_address, fee, memo) - .await - } - - pub async fn migrate( - &self, - contract_address: &AccountId, - code_id: ContractCodeId, - msg: &M, - memo: impl Into + Send + 'static, - fee: Option, - ) -> Result - where - C: SigningCosmWasmClient + Sync, - M: ?Sized + Serialize + Sync, - { - let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier))); - self.client - .migrate(self.address(), contract_address, code_id, fee, msg, memo) - .await - } -} - -impl NyxdClient { pub fn current_config(&self) -> &Config { &self.config } @@ -536,130 +222,78 @@ impl NyxdClient { } pub fn set_mixnet_contract_address(&mut self, address: AccountId) { - self.config.mixnet_contract_address = Some(address); + self.config.contracts.mixnet_contract_address = Some(address); } pub fn set_vesting_contract_address(&mut self, address: AccountId) { - self.config.vesting_contract_address = Some(address); + self.config.contracts.vesting_contract_address = Some(address); } pub fn set_coconut_bandwidth_contract_address(&mut self, address: AccountId) { - self.config.coconut_bandwidth_contract_address = Some(address); + self.config.contracts.coconut_bandwidth_contract_address = Some(address); } pub fn set_multisig_contract_address(&mut self, address: AccountId) { - self.config.multisig_contract_address = Some(address); + self.config.contracts.multisig_contract_address = Some(address); } pub fn set_service_provider_contract_address(&mut self, address: AccountId) { - self.config.service_provider_contract_address = Some(address); - } - - // TODO: this should get changed into Result<&AccountId, NyxdError> (or Option<&AccountId> in future commits - // note: what unwrap is doing here is just moving a failure that would have normally - // occurred in `connect` when attempting to parse an empty address, - // so it's not introducing new source of failure (just moves it) - pub fn mixnet_contract_address(&self) -> &AccountId { - self.config.mixnet_contract_address.as_ref().unwrap() - } - - // TODO: this should get changed into Result<&AccountId, NyxdError> (or Option<&AccountId> in future commits - // note: what unwrap is doing here is just moving a failure that would have normally - // occurred in `connect` when attempting to parse an empty address, - // so it's not introducing new source of failure (just moves it) - pub fn vesting_contract_address(&self) -> &AccountId { - self.config.vesting_contract_address.as_ref().unwrap() - } - - // TODO: this should get changed into Result<&AccountId, NyxdError> (or Option<&AccountId> in future commits - // note: what unwrap is doing here is just moving a failure that would have normally - // occurred in `connect` when attempting to parse an empty address, - // so it's not introducing new source of failure (just moves it) - pub fn coconut_bandwidth_contract_address(&self) -> &AccountId { self.config - .coconut_bandwidth_contract_address - .as_ref() - .unwrap() - } - - pub fn group_contract_address(&self) -> &AccountId { - self.config.group_contract_address.as_ref().unwrap() - } - - // TODO: this should get changed into Result<&AccountId, NyxdError> (or Option<&AccountId> in future commits - // note: what unwrap is doing here is just moving a failure that would have normally - // occurred in `connect` when attempting to parse an empty address, - // so it's not introducing new source of failure (just moves it) - pub fn multisig_contract_address(&self) -> &AccountId { - self.config.multisig_contract_address.as_ref().unwrap() - } - - // TODO: this should get changed into Result<&AccountId, NyxdError> (or Option<&AccountId> in future commits - // note: what unwrap is doing here is just moving a failure that would have normally - // occurred in `connect` when attempting to parse an empty address, - // so it's not introducing new source of failure (just moves it) - pub fn coconut_dkg_contract_address(&self) -> &AccountId { - self.config.coconut_dkg_contract_address.as_ref().unwrap() - } - - // The service provider directory contract is optional, so we return an Option not a Result - pub fn service_provider_contract_address(&self) -> Option<&AccountId> { - self.config.service_provider_contract_address.as_ref() - } - - // The name service contract is optional, so we return an Option not a Result - pub fn name_service_contract_address(&self) -> Option<&AccountId> { - self.config.name_service_contract_address.as_ref() + .contracts + .service_provider_directory_contract_address = Some(address); } pub fn set_simulated_gas_multiplier(&mut self, multiplier: f32) { - self.simulated_gas_multiplier = multiplier; + self.config.simulated_gas_multiplier = multiplier; + } +} + +impl NymContractsProvider for NyxdClient { + fn mixnet_contract_address(&self) -> Option<&AccountId> { + self.config.contracts.mixnet_contract_address.as_ref() } - pub async fn query_contract_smart( - &self, - contract: &AccountId, - query_msg: &M, - ) -> Result - where - C: CosmWasmClient + Sync, - M: ?Sized + Serialize + Sync, - for<'a> T: Deserialize<'a>, - { - self.client.query_contract_smart(contract, query_msg).await + fn vesting_contract_address(&self) -> Option<&AccountId> { + self.config.contracts.vesting_contract_address.as_ref() } - pub async fn query_contract_raw( - &self, - contract: &AccountId, - query_data: Vec, - ) -> Result, NyxdError> - where - C: CosmWasmClient + Sync, - { - self.client.query_contract_raw(contract, query_data).await + fn coconut_bandwidth_contract_address(&self) -> Option<&AccountId> { + self.config + .contracts + .coconut_bandwidth_contract_address + .as_ref() } - pub fn gas_adjustment(&self) -> GasAdjustment { - self.simulated_gas_multiplier + fn dkg_contract_address(&self) -> Option<&AccountId> { + self.config.contracts.coconut_dkg_contract_address.as_ref() } - // ============= - // CHAIN RELATED - // ============= - - // CHAIN QUERIES - - pub async fn get_account_details( - &self, - address: &AccountId, - ) -> Result, NyxdError> - where - C: CosmWasmClient + Sync, - { - self.client.get_account(address).await + fn group_contract_address(&self) -> Option<&AccountId> { + self.config.contracts.group_contract_address.as_ref() } + fn multisig_contract_address(&self) -> Option<&AccountId> { + self.config.contracts.multisig_contract_address.as_ref() + } + + fn name_service_contract_address(&self) -> Option<&AccountId> { + self.config.contracts.name_service_contract_address.as_ref() + } + + fn service_provider_contract_address(&self) -> Option<&AccountId> { + self.config + .contracts + .service_provider_directory_contract_address + .as_ref() + } +} + +// queries +impl NyxdClient +where + C: CosmWasmClient + Send + Sync, + S: Send + Sync, +{ pub async fn get_account_public_key( &self, address: &AccountId, @@ -720,54 +354,260 @@ impl NyxdClient { .await .map(|block| block.block_id.hash) } +} - pub async fn get_validators( +// signing +#[cfg(feature = "signing")] +impl NyxdClient +where + C: SigningCosmWasmClient + Send + Sync, + S: OfflineSigner + Send + Sync, + + // TODO: figure out those trait bounds lol + NyxdError: From<::Error>, + NyxdError: From<::Error>, +{ + pub fn address(&self) -> &AccountId { + &self.client.derived_addresses()[0] + } + + pub fn cw_address(&self) -> Addr { + // the call to unchecked is fine here as we're converting directly from `AccountId` + // which must have been a valid bech32 address + Addr::unchecked(self.address().as_ref()) + } + + pub async fn account_sequence(&self) -> Result { + self.client.get_sequence(self.address()).await + } + + pub fn wrap_contract_execute_message( &self, - height: u64, - paging: Paging, - ) -> Result + contract_address: &AccountId, + msg: &M, + funds: Vec, + ) -> Result where - C: CosmWasmClient + Sync, + M: ?Sized + Serialize, { - Ok(self.client.validators(height as u32, paging).await?) + Ok(cosmwasm::MsgExecuteContract { + sender: self.address().clone(), + contract: contract_address.clone(), + msg: serde_json::to_vec(msg)?, + funds: funds.into_iter().map(Into::into).collect(), + }) } - pub async fn get_balance( + pub async fn simulate(&self, messages: I) -> Result + where + I: IntoIterator + Send, + M: Msg, + { + self.client + .simulate( + self.address(), + messages + .into_iter() + .map(|msg| msg.into_any()) + .collect::, _>>() + .map_err(|_| { + NyxdError::SerializationError("custom simulate messages".to_owned()) + })?, + "simulating execution of transactions", + ) + .await + } + + /// Send funds from one address to another + pub async fn send( &self, - address: &AccountId, - denom: String, - ) -> Result, NyxdError> - where - C: CosmWasmClient + Sync, - { - self.client.get_balance(address, denom).await + recipient: &AccountId, + amount: Vec, + memo: impl Into + Send + 'static, + fee: Option, + ) -> Result { + let fee = fee.unwrap_or(Fee::Auto(Some(self.config.simulated_gas_multiplier))); + self.client + .send_tokens(self.address(), recipient, amount, fee, memo) + .await } - pub async fn get_all_balances(&self, address: &AccountId) -> Result, NyxdError> - where - C: CosmWasmClient + Sync, - { - self.client.get_all_balances(address).await + /// Send funds from one address to multiple others + pub async fn send_multiple( + &self, + msgs: Vec<(AccountId, Vec)>, + memo: impl Into + Send + 'static, + fee: Option, + ) -> Result { + let fee = fee.unwrap_or(Fee::Auto(Some(self.config.simulated_gas_multiplier))); + self.client + .send_tokens_multiple(self.address(), msgs, fee, memo) + .await } - pub async fn get_tx(&self, id: Hash) -> Result - where - C: CosmWasmClient + Sync, - { - self.client.get_tx(id).await + /// Grant a fee allowance from one address to another + pub async fn grant_allowance( + &self, + grantee: &AccountId, + spend_limit: Vec, + expiration: Option, + allowed_messages: Vec, + memo: impl Into + Send + 'static, + fee: Option, + ) -> Result { + let fee = fee.unwrap_or(Fee::Auto(Some(self.config.simulated_gas_multiplier))); + self.client + .grant_allowance( + self.address(), + grantee, + spend_limit, + expiration, + allowed_messages, + fee, + memo, + ) + .await } - pub async fn search_tx(&self, query: Query) -> Result, NyxdError> - where - C: CosmWasmClient + Sync, - { - self.client.search_tx(query).await + /// Revoke a fee allowance from one address to another + pub async fn revoke_allowance( + &self, + grantee: &AccountId, + memo: impl Into + Send + 'static, + fee: Option, + ) -> Result { + let fee = fee.unwrap_or(Fee::Auto(Some(self.config.simulated_gas_multiplier))); + self.client + .revoke_allowance(self.address(), grantee, fee, memo) + .await } - pub async fn get_total_supply(&self) -> Result, NyxdError> + pub async fn execute( + &self, + contract_address: &AccountId, + msg: &M, + fee: Option, + memo: impl Into + Send + 'static, + funds: Vec, + ) -> Result where - C: CosmWasmClient + Sync, + M: ?Sized + Serialize + Sync, { - self.client.get_total_supply().await + let fee = fee.unwrap_or(Fee::Auto(Some(self.config.simulated_gas_multiplier))); + self.client + .execute(self.address(), contract_address, msg, fee, memo, funds) + .await + } + + pub async fn execute_multiple( + &self, + contract_address: &AccountId, + msgs: I, + fee: Option, + memo: impl Into + Send + 'static, + ) -> Result + where + I: IntoIterator)> + Send, + M: Serialize, + { + let fee = fee.unwrap_or(Fee::Auto(Some(self.config.simulated_gas_multiplier))); + self.client + .execute_multiple(self.address(), contract_address, msgs, fee, memo) + .await + } + + pub async fn upload( + &self, + wasm_code: Vec, + memo: impl Into + Send + 'static, + fee: Option, + ) -> Result { + let fee = fee.unwrap_or(Fee::Auto(Some(self.config.simulated_gas_multiplier))); + self.client + .upload(self.address(), wasm_code, fee, memo) + .await + } + + pub async fn instantiate( + &self, + code_id: ContractCodeId, + msg: &M, + label: String, + memo: impl Into + Send + 'static, + options: Option, + fee: Option, + ) -> Result + where + M: ?Sized + Serialize + Sync, + { + let fee = fee.unwrap_or(Fee::Auto(Some(self.config.simulated_gas_multiplier))); + self.client + .instantiate(self.address(), code_id, msg, label, fee, memo, options) + .await + } + + pub async fn update_admin( + &self, + contract_address: &AccountId, + new_admin: &AccountId, + memo: impl Into + Send + 'static, + fee: Option, + ) -> Result { + let fee = fee.unwrap_or(Fee::Auto(Some(self.config.simulated_gas_multiplier))); + self.client + .update_admin(self.address(), contract_address, new_admin, fee, memo) + .await + } + + pub async fn clear_admin( + &self, + contract_address: &AccountId, + memo: impl Into + Send + 'static, + fee: Option, + ) -> Result { + let fee = fee.unwrap_or(Fee::Auto(Some(self.config.simulated_gas_multiplier))); + self.client + .clear_admin(self.address(), contract_address, fee, memo) + .await + } + + pub async fn migrate( + &self, + contract_address: &AccountId, + code_id: ContractCodeId, + msg: &M, + memo: impl Into + Send + 'static, + fee: Option, + ) -> Result + where + M: ?Sized + Serialize + Sync, + { + let fee = fee.unwrap_or(Fee::Auto(Some(self.config.simulated_gas_multiplier))); + self.client + .migrate(self.address(), contract_address, code_id, fee, msg, memo) + .await } } + +#[async_trait] +impl TendermintClient for NyxdClient +where + C: TendermintClient + Send + Sync, +{ + async fn perform(&self, request: R) -> Result + where + R: SimpleRequest, + { + self.client.perform(request).await + } +} + +#[async_trait] +impl CosmWasmClient for NyxdClient where C: CosmWasmClient + Send + Sync {} + +// #[async_trait] +// impl SigningCosmWasmClient for NyxdClient where C: SigningCosmWasmClient + Send + Sync { +// fn gas_price(&self) -> &GasPrice { +// self.client.gas_price() +// } +// } diff --git a/common/client-libs/validator-client/src/signing/direct_wallet.rs b/common/client-libs/validator-client/src/signing/direct_wallet.rs index 177e50a2f2..b26ac39ada 100644 --- a/common/client-libs/validator-client/src/signing/direct_wallet.rs +++ b/common/client-libs/validator-client/src/signing/direct_wallet.rs @@ -35,6 +35,7 @@ pub enum DirectSecp256k1HdWalletError { AccountDerivationError { source: eyre::Report }, } +// TODO: maybe lock this one behind feature flag? #[derive(Debug, Clone, Zeroize, ZeroizeOnDrop)] pub struct DirectSecp256k1HdWallet { /// Base secret diff --git a/common/client-libs/validator-client/src/signing/signer.rs b/common/client-libs/validator-client/src/signing/signer.rs index 074924a0cd..d4fd30d58b 100644 --- a/common/client-libs/validator-client/src/signing/signer.rs +++ b/common/client-libs/validator-client/src/signing/signer.rs @@ -94,3 +94,25 @@ pub trait OfflineSigner { // fn sign_amino_with_account(&self, signer: &AccountData, sign_doc: AminoSignDoc) -> Result; } + +#[derive(Debug, Default, Copy, Clone)] +pub struct NoSigner; + +// #[derive(Debug, Copy, Clone, Error)] +// #[error("no signer is available")] +// struct SignerUnavailable; +// +// // trait bound requirements +// impl From for SignerUnavailable { +// fn from(_: SigningError) -> Self { +// SignerUnavailable +// } +// } +// +// impl OfflineSigner for NoSigner { +// type Error = SignerUnavailable; +// +// fn get_accounts(&self) -> Result, Self::Error> { +// return Err(SignerUnavailable); +// } +// } diff --git a/common/client-libs/validator-client/src/signing/tx_signer.rs b/common/client-libs/validator-client/src/signing/tx_signer.rs index f14f640793..7db9a7617e 100644 --- a/common/client-libs/validator-client/src/signing/tx_signer.rs +++ b/common/client-libs/validator-client/src/signing/tx_signer.rs @@ -5,54 +5,98 @@ use crate::signing::signer::{OfflineSigner, SigningError}; use crate::signing::SignerData; use cosmrs::tx::{SignDoc, SignerInfo}; use cosmrs::{tx, AccountId, Any}; +// +// #[derive(Debug)] +// /// A client that has only one responsibility - sign transactions +// /// and not touch chain. +// pub struct TxSigner { +// signer: S, +// } +// +// impl TxSigner { +// pub fn new(signer: S) -> Self { +// TxSigner { signer } +// } +// +// pub fn signer(&self) -> &S { +// &self.signer +// } +// +// pub fn into_inner_signer(self) -> S { +// self.signer +// } +// +// pub fn sign_amino( +// &self, +// _signer_address: &AccountId, +// _messages: Vec, +// _fee: tx::Fee, +// _memo: impl Into + Send + 'static, +// _signer_data: SignerData, +// ) -> Result +// where +// S: OfflineSigner, +// { +// unimplemented!() +// } +// +// // TODO: change this sucker to use the trait better +// pub fn sign_direct( +// &self, +// signer_address: &AccountId, +// messages: Vec, +// fee: tx::Fee, +// memo: impl Into + Send + 'static, +// signer_data: SignerData, +// ) -> Result +// where +// S: OfflineSigner, +// { +// let account_from_signer = self.signer.find_account(signer_address)?; +// +// // TODO: experiment with this field +// let timeout_height = 0u32; +// +// let tx_body = tx::Body::new(messages, memo, timeout_height); +// let signer_info = +// SignerInfo::single_direct(Some(account_from_signer.public_key), signer_data.sequence); +// let auth_info = signer_info.auth_info(fee); +// +// let sign_doc = SignDoc::new( +// &tx_body, +// &auth_info, +// &signer_data.chain_id, +// signer_data.account_number, +// ) +// .map_err(|source| SigningError::SignDocFailure { source })?; +// +// self.signer +// .sign_direct_with_account(&account_from_signer, sign_doc) +// } +// } -#[derive(Debug)] -/// A client that has only one responsibility - sign transactions -/// and not touch chain. -pub struct TxSigner { - signer: S, -} - -impl TxSigner { - pub fn new(signer: S) -> Self { - TxSigner { signer } - } - - pub fn signer(&self) -> &S { - &self.signer - } - - pub fn into_inner_signer(self) -> S { - self.signer - } - - pub fn sign_amino( +// extension trait for the OfflineSigner to allow to sign transactions +pub trait TxSigner: OfflineSigner { + fn sign_amino( &self, _signer_address: &AccountId, _messages: Vec, _fee: tx::Fee, _memo: impl Into + Send + 'static, _signer_data: SignerData, - ) -> Result - where - S: OfflineSigner, - { + ) -> Result::Error> { unimplemented!() } - // TODO: change this sucker to use the trait better - pub fn sign_direct( + fn sign_direct( &self, signer_address: &AccountId, messages: Vec, fee: tx::Fee, memo: impl Into + Send + 'static, signer_data: SignerData, - ) -> Result - where - S: OfflineSigner, - { - let account_from_signer = self.signer.find_account(signer_address)?; + ) -> Result::Error> { + let account_from_signer = self.find_account(signer_address)?; // TODO: experiment with this field let timeout_height = 0u32; @@ -70,7 +114,6 @@ impl TxSigner { ) .map_err(|source| SigningError::SignDocFailure { source })?; - self.signer - .sign_direct_with_account(&account_from_signer, sign_doc) + self.sign_direct_with_account(&account_from_signer, sign_doc) } } diff --git a/common/network-defaults/src/lib.rs b/common/network-defaults/src/lib.rs index 77b1761d1c..2be09b0e70 100644 --- a/common/network-defaults/src/lib.rs +++ b/common/network-defaults/src/lib.rs @@ -164,6 +164,10 @@ impl NymNetworkDetails { } } + pub fn default_gas_price_amount(&self) -> f64 { + GAS_PRICE_AMOUNT + } + #[must_use] pub fn with_network_name(mut self, network_name: String) -> Self { self.network_name = network_name; diff --git a/nym-connect/desktop/Cargo.lock b/nym-connect/desktop/Cargo.lock index ef73c6c55e..d30e02be2f 100644 --- a/nym-connect/desktop/Cargo.lock +++ b/nym-connect/desktop/Cargo.lock @@ -4561,6 +4561,7 @@ dependencies = [ "colored 2.0.4", "cosmrs", "cosmwasm-std", + "cw-utils", "cw3", "cw4", "eyre", diff --git a/nym-wallet/Cargo.lock b/nym-wallet/Cargo.lock index bc7f8ae20f..68eff5cacf 100644 --- a/nym-wallet/Cargo.lock +++ b/nym-wallet/Cargo.lock @@ -3415,6 +3415,7 @@ dependencies = [ "colored 2.0.4", "cosmrs", "cosmwasm-std", + "cw-utils", "cw3", "cw4", "eyre", From dd887bd89ba34b512e6feecb9f6e2d85786f1334 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Mon, 31 Jul 2023 15:38:25 +0100 Subject: [PATCH 03/24] start of the paged trait --- .../contract_traits/mixnet_query_client.rs | 33 +++---------------- .../src/nyxd/contract_traits/mod.rs | 31 ++++++++--------- 2 files changed, 18 insertions(+), 46 deletions(-) diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/mixnet_query_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/mixnet_query_client.rs index f4128f0024..5b9e684fb1 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/mixnet_query_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/mixnet_query_client.rs @@ -1,7 +1,7 @@ // Copyright 2022-2023 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use crate::define_paged_response; +use crate::collect_paged; use crate::nyxd::contract_traits::NymContractsProvider; use crate::nyxd::error::NyxdError; use crate::nyxd::CosmWasmClient; @@ -454,33 +454,10 @@ pub trait MixnetQueryClient { // extension trait to the query client to deal with the paged queries // (it didn't feel appropriate to combine it with the existing trait #[async_trait] -pub trait PagedMixnetClient: MixnetQueryClient + Send + Sync { - // async fn get_all_node_families(&self) -> Result, NyxdError> { - // let mut res = Vec::new(); - // let mut start_after = None; - // - // loop { - // let paged_response = self - // .get_all_node_families_paged(start_after.take(), None) - // .await?; - // res.extend(paged_response.families); - // - // if let Some(start_next_after) = paged_response.start_next_after { - // start_after = Some(start_next_after) - // } else { - // break; - // } - // } - // - // Ok(res) - // } - - // define_paged_response!( - // get_all_node_families, - // Family, - // get_all_node_families_paged, - // families - // ); +pub trait PagedMixnetClient: MixnetQueryClient { + async fn get_all_node_families(&self) -> Result, NyxdError> { + collect_paged!(self, get_all_node_families_paged, families) + } } #[async_trait] diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/mod.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/mod.rs index cf75c407af..80dfb1b505 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/mod.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/mod.rs @@ -126,26 +126,21 @@ impl TryFrom for TypedNymContracts { } } -// a simple helper macro to define a function to repeatedly call a paged query until a full response is constructed +// a simple helper macro to define to repeatedly call a paged query until a full response is constructed #[macro_export] -macro_rules! define_paged_response { - ( $f: ident, $r: ty, $fc: ident, $field: ident ) => { - async fn $f(&self) -> Result, NyxdError> { - let mut res = Vec::new(); - let mut start_after = None; +macro_rules! collect_paged { + ( $self:ident, $f: ident, $field: ident ) => {{ + let mut res = Vec::new(); + let mut start_after = None; + loop { + let paged_response = $self.$f(start_after.take(), None).await?; + res.extend(paged_response.$field); - loop { - let paged_response = self.$fc(start_after.take(), None).await?; - res.extend(paged_response.$field); - - if let Some(start_next_after) = paged_response.start_next_after { - start_after = Some(start_next_after) - } else { - break; - } + if let Some(start_next_after) = paged_response.start_next_after { + start_after = Some(start_next_after) + } else { + break Ok(res); } - - Ok(res) } - }; + }}; } From e911e9e7eeaf6367261ca3ecea514250d45b86b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Mon, 31 Jul 2023 15:52:06 +0100 Subject: [PATCH 04/24] wip --- .../validator-client/src/client.rs | 160 ++---------------- .../contract_traits/mixnet_query_client.rs | 48 ++++-- .../websocket/connection_handler/coconut.rs | 4 +- 3 files changed, 51 insertions(+), 161 deletions(-) diff --git a/common/client-libs/validator-client/src/client.rs b/common/client-libs/validator-client/src/client.rs index 854648bcc9..1925ee9910 100644 --- a/common/client-libs/validator-client/src/client.rs +++ b/common/client-libs/validator-client/src/client.rs @@ -205,130 +205,6 @@ impl Client { .clone() } - // pub async fn get_all_node_families(&self) -> Result, ValidatorClientError> - // where - // C: CosmWasmClient + Sync + Send, - // { - // let mut families = Vec::new(); - // let mut start_after = None; - // - // loop { - // let paged_response = self - // .nyxd - // .get_all_node_families_paged(start_after.take(), None) - // .await?; - // families.extend(paged_response.families); - // - // if let Some(start_after_res) = paged_response.start_next_after { - // start_after = Some(start_after_res) - // } else { - // break; - // } - // } - // - // Ok(families) - // } - // - // pub async fn get_all_family_members( - // &self, - // ) -> Result, ValidatorClientError> - // where - // C: CosmWasmClient + Sync + Send, - // { - // let mut members = Vec::new(); - // let mut start_after = None; - // - // loop { - // let paged_response = self - // .nyxd - // .get_all_family_members_paged(start_after.take(), None) - // .await?; - // members.extend(paged_response.members); - // - // if let Some(start_after_res) = paged_response.start_next_after { - // start_after = Some(start_after_res) - // } else { - // break; - // } - // } - // - // Ok(members) - // } - // - // // basically handles paging for us - // pub async fn get_all_nyxd_rewarded_set_mixnodes( - // &self, - // ) -> Result, ValidatorClientError> - // where - // C: CosmWasmClient + Sync + Send, - // { - // let mut identities = Vec::new(); - // let mut start_after = None; - // - // loop { - // let mut paged_response = self - // .nyxd - // .get_rewarded_set_paged(start_after.take(), self.rewarded_set_page_limit) - // .await?; - // identities.append(&mut paged_response.nodes); - // - // if let Some(start_after_res) = paged_response.start_next_after { - // start_after = Some(start_after_res) - // } else { - // break; - // } - // } - // - // Ok(identities) - // } - // - // pub async fn get_all_nyxd_mixnode_bonds(&self) -> Result, ValidatorClientError> - // where - // C: CosmWasmClient + Sync + Send, - // { - // let mut mixnodes = Vec::new(); - // let mut start_after = None; - // loop { - // let mut paged_response = self - // .nyxd - // .get_mixnode_bonds_paged(self.mixnode_page_limit, start_after.take()) - // .await?; - // mixnodes.append(&mut paged_response.nodes); - // - // if let Some(start_after_res) = paged_response.start_next_after { - // start_after = Some(start_after_res) - // } else { - // break; - // } - // } - // - // Ok(mixnodes) - // } - // - // pub async fn get_all_nyxd_mixnodes_detailed( - // &self, - // ) -> Result, ValidatorClientError> - // where - // C: CosmWasmClient + Sync + Send, - // { - // let mut mixnodes = Vec::new(); - // let mut start_after = None; - // loop { - // let mut paged_response = self - // .nyxd - // .get_mixnodes_detailed_paged(self.mixnode_page_limit, start_after.take()) - // .await?; - // mixnodes.append(&mut paged_response.nodes); - // - // if let Some(start_after_res) = paged_response.start_next_after { - // start_after = Some(start_after_res) - // } else { - // break; - // } - // } - // - // Ok(mixnodes) - // } // // pub async fn get_all_nyxd_unbonded_mixnodes( // &self, @@ -676,40 +552,40 @@ impl CoconutApiClient { #[derive(Clone)] pub struct NymApiClient { - pub nym_api_client: nym_api::Client, + pub nym_api: nym_api::Client, // TODO: perhaps if we really need it at some (currently I don't see any reasons for it) // we could re-implement the communication with the REST API on port 1317 } impl NymApiClient { pub fn new(api_url: Url) -> Self { - let nym_api_client = nym_api::Client::new(api_url); + let nym_api = nym_api::Client::new(api_url); - NymApiClient { nym_api_client } + NymApiClient { nym_api } } pub fn change_nym_api(&mut self, new_endpoint: Url) { - self.nym_api_client.change_url(new_endpoint); + self.nym_api.change_url(new_endpoint); } pub async fn get_cached_active_mixnodes( &self, ) -> Result, ValidatorClientError> { - Ok(self.nym_api_client.get_active_mixnodes().await?) + Ok(self.nym_api.get_active_mixnodes().await?) } pub async fn get_cached_rewarded_mixnodes( &self, ) -> Result, ValidatorClientError> { - Ok(self.nym_api_client.get_rewarded_mixnodes().await?) + Ok(self.nym_api.get_rewarded_mixnodes().await?) } pub async fn get_cached_mixnodes(&self) -> Result, ValidatorClientError> { - Ok(self.nym_api_client.get_mixnodes().await?) + Ok(self.nym_api.get_mixnodes().await?) } pub async fn get_cached_gateways(&self) -> Result, ValidatorClientError> { - Ok(self.nym_api_client.get_gateways().await?) + Ok(self.nym_api.get_gateways().await?) } pub async fn get_gateway_core_status_count( @@ -718,7 +594,7 @@ impl NymApiClient { since: Option, ) -> Result { Ok(self - .nym_api_client + .nym_api .get_gateway_core_status_count(identity, since) .await?) } @@ -729,7 +605,7 @@ impl NymApiClient { since: Option, ) -> Result { Ok(self - .nym_api_client + .nym_api .get_mixnode_core_status_count(mix_id, since) .await?) } @@ -738,34 +614,28 @@ impl NymApiClient { &self, mix_id: MixId, ) -> Result { - Ok(self.nym_api_client.get_mixnode_status(mix_id).await?) + Ok(self.nym_api.get_mixnode_status(mix_id).await?) } pub async fn get_mixnode_reward_estimation( &self, mix_id: MixId, ) -> Result { - Ok(self - .nym_api_client - .get_mixnode_reward_estimation(mix_id) - .await?) + Ok(self.nym_api.get_mixnode_reward_estimation(mix_id).await?) } pub async fn get_mixnode_stake_saturation( &self, mix_id: MixId, ) -> Result { - Ok(self - .nym_api_client - .get_mixnode_stake_saturation(mix_id) - .await?) + Ok(self.nym_api.get_mixnode_stake_saturation(mix_id).await?) } pub async fn blind_sign( &self, request_body: &BlindSignRequestBody, ) -> Result { - Ok(self.nym_api_client.blind_sign(request_body).await?) + Ok(self.nym_api.blind_sign(request_body).await?) } pub async fn verify_bandwidth_credential( @@ -773,7 +643,7 @@ impl NymApiClient { request_body: &VerifyCredentialBody, ) -> Result { Ok(self - .nym_api_client + .nym_api .verify_bandwidth_credential(request_body) .await?) } diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/mixnet_query_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/mixnet_query_client.rs index 5b9e684fb1..981a6754f9 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/mixnet_query_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/mixnet_query_client.rs @@ -9,6 +9,7 @@ use async_trait::async_trait; use cosmrs::AccountId; use nym_contracts_common::signing::Nonce; use nym_mixnet_contract_common::delegation::{MixNodeDelegationResponse, OwnerProxySubKey}; +use nym_mixnet_contract_common::families::{Family, FamilyHead}; use nym_mixnet_contract_common::mixnode::{ MixnodeRewardingDetailsResponse, PagedMixnodesDetailsResponse, PagedUnbondedMixnodesResponse, StakeSaturationResponse, UnbondedMixnodeResponse, @@ -22,12 +23,13 @@ use nym_mixnet_contract_common::{ CurrentIntervalResponse, EpochEventId, EpochStatus, FamilyByHeadResponse, FamilyByLabelResponse, FamilyMembersByHeadResponse, FamilyMembersByLabelResponse, GatewayBondResponse, GatewayOwnershipResponse, IdentityKey, IntervalEventId, LayerDistribution, - MixId, MixOwnershipResponse, MixnodeDetailsByIdentityResponse, MixnodeDetailsResponse, - NumberOfPendingEventsResponse, PagedAllDelegationsResponse, PagedDelegatorDelegationsResponse, - PagedFamiliesResponse, PagedGatewayResponse, PagedMembersResponse, - PagedMixNodeDelegationsResponse, PagedMixnodeBondsResponse, PagedRewardedSetResponse, - PendingEpochEventResponse, PendingEpochEventsResponse, PendingIntervalEventResponse, - PendingIntervalEventsResponse, QueryMsg as MixnetQueryMsg, + MixId, MixNodeBond, MixNodeDetails, MixOwnershipResponse, MixnodeDetailsByIdentityResponse, + MixnodeDetailsResponse, NumberOfPendingEventsResponse, PagedAllDelegationsResponse, + PagedDelegatorDelegationsResponse, PagedFamiliesResponse, PagedGatewayResponse, + PagedMembersResponse, PagedMixNodeDelegationsResponse, PagedMixnodeBondsResponse, + PagedRewardedSetResponse, PendingEpochEventResponse, PendingEpochEventsResponse, + PendingIntervalEventResponse, PendingIntervalEventsResponse, QueryMsg as MixnetQueryMsg, + RewardedSetNodeStatus, }; use serde::Deserialize; @@ -94,8 +96,8 @@ pub trait MixnetQueryClient { async fn get_all_family_members_paged( &self, - limit: Option, start_after: Option, + limit: Option, ) -> Result { self.query_mixnet_contract(MixnetQueryMsg::GetAllMembersPaged { limit, start_after }) .await @@ -123,8 +125,8 @@ pub trait MixnetQueryClient { async fn get_mixnode_bonds_paged( &self, - limit: Option, start_after: Option, + limit: Option, ) -> Result { self.query_mixnet_contract(MixnetQueryMsg::GetMixNodeBonds { limit, start_after }) .await @@ -132,8 +134,8 @@ pub trait MixnetQueryClient { async fn get_mixnodes_detailed_paged( &self, - limit: Option, start_after: Option, + limit: Option, ) -> Result { self.query_mixnet_contract(MixnetQueryMsg::GetMixNodesDetailed { limit, start_after }) .await @@ -141,8 +143,8 @@ pub trait MixnetQueryClient { async fn get_unbonded_paged( &self, - limit: Option, start_after: Option, + limit: Option, ) -> Result { self.query_mixnet_contract(MixnetQueryMsg::GetUnbondedMixNodes { limit, start_after }) .await @@ -151,8 +153,8 @@ pub trait MixnetQueryClient { async fn get_unbonded_by_owner_paged( &self, owner: &AccountId, - limit: Option, start_after: Option, + limit: Option, ) -> Result { self.query_mixnet_contract(MixnetQueryMsg::GetUnbondedMixNodesByOwner { owner: owner.to_string(), @@ -165,8 +167,8 @@ pub trait MixnetQueryClient { async fn get_unbonded_by_identity_paged( &self, identity_key: String, - limit: Option, start_after: Option, + limit: Option, ) -> Result { self.query_mixnet_contract(MixnetQueryMsg::GetUnbondedMixNodesByIdentityKey { identity_key, @@ -454,14 +456,32 @@ pub trait MixnetQueryClient { // extension trait to the query client to deal with the paged queries // (it didn't feel appropriate to combine it with the existing trait #[async_trait] -pub trait PagedMixnetClient: MixnetQueryClient { +pub trait PagedMixnetQueryClient: MixnetQueryClient { async fn get_all_node_families(&self) -> Result, NyxdError> { collect_paged!(self, get_all_node_families_paged, families) } + + async fn get_all_family_members(&self) -> Result, NyxdError> { + collect_paged!(self, get_all_family_members_paged, members) + } + + async fn get_all_rewarded_set_mixnodes( + &self, + ) -> Result, NyxdError> { + collect_paged!(self, get_rewarded_set_paged, nodes) + } + + async fn get_all_mixnode_bonds(&self) -> Result, NyxdError> { + collect_paged!(self, get_mixnode_bonds_paged, nodes) + } + + async fn get_all_mixnodes_detailed(&self) -> Result, NyxdError> { + collect_paged!(self, get_mixnodes_detailed_paged, nodes) + } } #[async_trait] -impl PagedMixnetClient for T where T: MixnetQueryClient {} +impl PagedMixnetQueryClient for T where T: MixnetQueryClient {} #[async_trait] impl MixnetQueryClient for C diff --git a/gateway/src/node/client_handling/websocket/connection_handler/coconut.rs b/gateway/src/node/client_handling/websocket/connection_handler/coconut.rs index 8d2dcbebb6..da9e7fd217 100644 --- a/gateway/src/node/client_handling/websocket/connection_handler/coconut.rs +++ b/gateway/src/node/client_handling/websocket/connection_handler/coconut.rs @@ -123,11 +123,11 @@ impl CoconutVerifier { match ret { Ok(res) => { if !res.verification_result { - debug!("Validator {} didn't accept the credential. It will probably vote No on the spending proposal", client.api_client.nym_api_client.current_url()); + debug!("Validator {} didn't accept the credential. It will probably vote No on the spending proposal", client.api_client.nym_api.current_url()); } } Err(e) => { - warn!("Validator {} could not be reached. There might be a problem with the coconut endpoint - {:?}", client.api_client.nym_api_client.current_url(), e); + warn!("Validator {} could not be reached. There might be a problem with the coconut endpoint - {:?}", client.api_client.nym_api.current_url(), e); } } } From a4f415cb45e38a620f488abd30dab335e2a7e5fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Mon, 31 Jul 2023 17:43:46 +0100 Subject: [PATCH 05/24] extended the paged query client --- .../validator-client/src/client.rs | 292 +----------------- .../contract_traits/mixnet_query_client.rs | 80 ++++- .../src/nyxd/contract_traits/mod.rs | 16 + 3 files changed, 86 insertions(+), 302 deletions(-) diff --git a/common/client-libs/validator-client/src/client.rs b/common/client-libs/validator-client/src/client.rs index 1925ee9910..27020200d5 100644 --- a/common/client-libs/validator-client/src/client.rs +++ b/common/client-libs/validator-client/src/client.rs @@ -43,13 +43,7 @@ pub struct Config { nyxd_url: Url, // TODO: until refactored, this is a dead field under some features - #[allow(dead_code)] nyxd_config: nyxd::Config, - - mixnode_page_limit: Option, - gateway_page_limit: Option, - mixnode_delegations_page_limit: Option, - rewarded_set_page_limit: Option, } impl Config { @@ -74,10 +68,6 @@ impl Config { .parse() .map_err(ValidatorClientError::MalformedUrlProvided)?, nyxd_config: nyxd::Config::try_from_nym_network_details(details)?, - mixnode_page_limit: None, - gateway_page_limit: None, - mixnode_delegations_page_limit: None, - rewarded_set_page_limit: None, }) } @@ -93,38 +83,9 @@ impl Config { self.nyxd_url = nyxd_url; self } - - pub fn with_mixnode_page_limit(mut self, limit: Option) -> Config { - self.mixnode_page_limit = limit; - self - } - - pub fn with_gateway_page_limit(mut self, limit: Option) -> Config { - self.gateway_page_limit = limit; - self - } - - pub fn with_mixnode_delegations_page_limit(mut self, limit: Option) -> Config { - self.mixnode_delegations_page_limit = limit; - self - } - - pub fn with_rewarded_set_page_limit(mut self, limit: Option) -> Config { - self.rewarded_set_page_limit = limit; - self - } } pub struct Client { - #[deprecated] - mixnode_page_limit: Option, - #[deprecated] - gateway_page_limit: Option, - #[deprecated] - mixnode_delegations_page_limit: Option, - #[deprecated] - rewarded_set_page_limit: Option, - // ideally they would have been read-only, but unfortunately rust doesn't have such features pub nym_api: nym_api::Client, pub nyxd: NyxdClient, @@ -144,10 +105,6 @@ impl Client { )?; Ok(Client { - mixnode_page_limit: config.mixnode_page_limit, - gateway_page_limit: config.gateway_page_limit, - mixnode_delegations_page_limit: config.mixnode_delegations_page_limit, - rewarded_set_page_limit: config.rewarded_set_page_limit, nym_api: nym_api_client, nyxd: nyxd_client, }) @@ -172,10 +129,6 @@ impl Client { NyxdClient::connect(config.nyxd_config.clone(), config.nyxd_url.as_str())?; Ok(Client { - mixnode_page_limit: config.mixnode_page_limit, - gateway_page_limit: config.gateway_page_limit, - mixnode_delegations_page_limit: config.mixnode_delegations_page_limit, - rewarded_set_page_limit: config.rewarded_set_page_limit, nym_api: nym_api_client, nyxd: nyxd_client, }) @@ -192,11 +145,13 @@ impl Client { // use case: somebody initialised client without a contract in order to upload and initialise one // and now they want to actually use it without making new client + #[deprecated] pub fn set_mixnet_contract_address(&mut self, mixnet_contract_address: cosmrs::AccountId) { self.nyxd .set_mixnet_contract_address(mixnet_contract_address) } + #[deprecated] pub fn get_mixnet_contract_address(&self) -> cosmrs::AccountId { // TODO: deal with the expect self.nyxd @@ -204,249 +159,6 @@ impl Client { .expect("mixnet contract address is not available") .clone() } - - // - // pub async fn get_all_nyxd_unbonded_mixnodes( - // &self, - // ) -> Result, ValidatorClientError> - // where - // C: CosmWasmClient + Sync + Send, - // { - // let mut mixnodes = Vec::new(); - // let mut start_after = None; - // loop { - // let mut paged_response = self - // .nyxd - // .get_unbonded_paged(self.mixnode_page_limit, start_after.take()) - // .await?; - // mixnodes.append(&mut paged_response.nodes); - // - // if let Some(start_after_res) = paged_response.start_next_after { - // start_after = Some(start_after_res) - // } else { - // break; - // } - // } - // - // Ok(mixnodes) - // } - // - // pub async fn get_all_nyxd_unbonded_mixnodes_by_owner( - // &self, - // owner: &cosmrs::AccountId, - // ) -> Result, ValidatorClientError> - // where - // C: CosmWasmClient + Sync + Send, - // { - // let mut mixnodes = Vec::new(); - // let mut start_after = None; - // loop { - // let mut paged_response = self - // .nyxd - // .get_unbonded_by_owner_paged(owner, self.mixnode_page_limit, start_after.take()) - // .await?; - // mixnodes.append(&mut paged_response.nodes); - // - // if let Some(start_after_res) = paged_response.start_next_after { - // start_after = Some(start_after_res) - // } else { - // break; - // } - // } - // - // Ok(mixnodes) - // } - // - // pub async fn get_all_nyxd_unbonded_mixnodes_by_identity( - // &self, - // identity_key: String, - // ) -> Result, ValidatorClientError> - // where - // C: CosmWasmClient + Sync + Send, - // { - // let mut mixnodes = Vec::new(); - // let mut start_after = None; - // loop { - // let mut paged_response = self - // .nyxd - // .get_unbonded_by_identity_paged( - // identity_key.clone(), - // self.mixnode_page_limit, - // start_after.take(), - // ) - // .await?; - // mixnodes.append(&mut paged_response.nodes); - // - // if let Some(start_after_res) = paged_response.start_next_after { - // start_after = Some(start_after_res) - // } else { - // break; - // } - // } - // - // Ok(mixnodes) - // } - // - // pub async fn get_all_nyxd_gateways(&self) -> Result, ValidatorClientError> - // where - // C: CosmWasmClient + Sync + Send, - // { - // let mut gateways = Vec::new(); - // let mut start_after = None; - // loop { - // let mut paged_response = self - // .nyxd - // .get_gateways_paged(start_after.take(), self.gateway_page_limit) - // .await?; - // gateways.append(&mut paged_response.nodes); - // - // if let Some(start_after_res) = paged_response.start_next_after { - // start_after = Some(start_after_res) - // } else { - // break; - // } - // } - // - // Ok(gateways) - // } - // - // pub async fn get_all_nyxd_single_mixnode_delegations( - // &self, - // mix_id: MixId, - // ) -> Result, ValidatorClientError> - // where - // C: CosmWasmClient + Sync + Send, - // { - // let mut delegations = Vec::new(); - // let mut start_after = None; - // loop { - // let mut paged_response = self - // .nyxd - // .get_mixnode_delegations_paged( - // mix_id, - // start_after.take(), - // self.mixnode_delegations_page_limit, - // ) - // .await?; - // delegations.append(&mut paged_response.delegations); - // - // if let Some(start_after_res) = paged_response.start_next_after { - // start_after = Some(start_after_res) - // } else { - // break; - // } - // } - // - // Ok(delegations) - // } - // - // pub async fn get_all_delegator_delegations( - // &self, - // delegation_owner: &cosmrs::AccountId, - // ) -> Result, ValidatorClientError> - // where - // C: CosmWasmClient + Sync + Send, - // { - // let mut delegations = Vec::new(); - // let mut start_after = None; - // loop { - // let mut paged_response = self - // .nyxd - // .get_delegator_delegations_paged( - // delegation_owner.to_string(), - // start_after.take(), - // self.mixnode_delegations_page_limit, - // ) - // .await?; - // delegations.append(&mut paged_response.delegations); - // - // if let Some(start_after_res) = paged_response.start_next_after { - // start_after = Some(start_after_res) - // } else { - // break; - // } - // } - // - // Ok(delegations) - // } - // - // pub async fn get_all_network_delegations(&self) -> Result, ValidatorClientError> - // where - // C: CosmWasmClient + Sync + Send, - // { - // let mut delegations = Vec::new(); - // let mut start_after = None; - // loop { - // let mut paged_response = self - // .nyxd - // .get_all_network_delegations_paged( - // start_after.take(), - // self.mixnode_delegations_page_limit, - // ) - // .await?; - // delegations.append(&mut paged_response.delegations); - // - // if let Some(start_after_res) = paged_response.start_next_after { - // start_after = Some(start_after_res) - // } else { - // break; - // } - // } - // - // Ok(delegations) - // } - // - // pub async fn get_all_nyxd_pending_epoch_events( - // &self, - // ) -> Result, ValidatorClientError> - // where - // C: CosmWasmClient + Sync + Send, - // { - // let mut events = Vec::new(); - // let mut start_after = None; - // - // loop { - // let mut paged_response = self - // .nyxd - // .get_pending_epoch_events_paged(start_after.take(), self.rewarded_set_page_limit) - // .await?; - // events.append(&mut paged_response.events); - // - // if let Some(start_after_res) = paged_response.start_next_after { - // start_after = Some(start_after_res) - // } else { - // break; - // } - // } - // - // Ok(events) - // } - // - // pub async fn get_all_nyxd_pending_interval_events( - // &self, - // ) -> Result, ValidatorClientError> - // where - // C: CosmWasmClient + Sync + Send, - // { - // let mut events = Vec::new(); - // let mut start_after = None; - // - // loop { - // let mut paged_response = self - // .nyxd - // .get_pending_interval_events_paged(start_after.take(), self.rewarded_set_page_limit) - // .await?; - // events.append(&mut paged_response.events); - // - // if let Some(start_after_res) = paged_response.start_next_after { - // start_after = Some(start_after_res) - // } else { - // break; - // } - // } - // - // Ok(events) - // } } // validator-api wrappers diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/mixnet_query_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/mixnet_query_client.rs index 981a6754f9..b3f2e77142 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/mixnet_query_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/mixnet_query_client.rs @@ -8,6 +8,7 @@ use crate::nyxd::CosmWasmClient; use async_trait::async_trait; use cosmrs::AccountId; use nym_contracts_common::signing::Nonce; +use nym_contracts_common::IdentityKeyRef; use nym_mixnet_contract_common::delegation::{MixNodeDelegationResponse, OwnerProxySubKey}; use nym_mixnet_contract_common::families::{Family, FamilyHead}; use nym_mixnet_contract_common::mixnode::{ @@ -20,16 +21,16 @@ use nym_mixnet_contract_common::rewarding::{ }; use nym_mixnet_contract_common::{ delegation, ContractBuildInformation, ContractState, ContractStateParams, - CurrentIntervalResponse, EpochEventId, EpochStatus, FamilyByHeadResponse, - FamilyByLabelResponse, FamilyMembersByHeadResponse, FamilyMembersByLabelResponse, + CurrentIntervalResponse, Delegation, EpochEventId, EpochStatus, FamilyByHeadResponse, + FamilyByLabelResponse, FamilyMembersByHeadResponse, FamilyMembersByLabelResponse, GatewayBond, GatewayBondResponse, GatewayOwnershipResponse, IdentityKey, IntervalEventId, LayerDistribution, - MixId, MixNodeBond, MixNodeDetails, MixOwnershipResponse, MixnodeDetailsByIdentityResponse, - MixnodeDetailsResponse, NumberOfPendingEventsResponse, PagedAllDelegationsResponse, - PagedDelegatorDelegationsResponse, PagedFamiliesResponse, PagedGatewayResponse, - PagedMembersResponse, PagedMixNodeDelegationsResponse, PagedMixnodeBondsResponse, - PagedRewardedSetResponse, PendingEpochEventResponse, PendingEpochEventsResponse, + MixId, MixNodeBond, MixNodeDetails, MixOwnershipResponse, MixnodeDetailsResponse, + NumberOfPendingEventsResponse, PagedAllDelegationsResponse, PagedDelegatorDelegationsResponse, + PagedFamiliesResponse, PagedGatewayResponse, PagedMembersResponse, + PagedMixNodeDelegationsResponse, PagedMixnodeBondsResponse, PagedRewardedSetResponse, + PendingEpochEvent, PendingEpochEventResponse, PendingEpochEventsResponse, PendingIntervalEvent, PendingIntervalEventResponse, PendingIntervalEventsResponse, QueryMsg as MixnetQueryMsg, - RewardedSetNodeStatus, + RewardedSetNodeStatus, UnbondedMixnode, }; use serde::Deserialize; @@ -166,12 +167,12 @@ pub trait MixnetQueryClient { async fn get_unbonded_by_identity_paged( &self, - identity_key: String, + identity_key: IdentityKeyRef<'_>, start_after: Option, limit: Option, ) -> Result { self.query_mixnet_contract(MixnetQueryMsg::GetUnbondedMixNodesByIdentityKey { - identity_key, + identity_key: identity_key.to_string(), limit, start_after, }) @@ -286,12 +287,12 @@ pub trait MixnetQueryClient { /// Gets list of all the mixnodes to which a particular address delegated. async fn get_delegator_delegations_paged( &self, - delegator: String, + delegator: &AccountId, start_after: Option<(MixId, OwnerProxySubKey)>, limit: Option, ) -> Result { self.query_mixnet_contract(MixnetQueryMsg::GetDelegatorDelegations { - delegator, + delegator: delegator.to_string(), start_after, limit, }) @@ -478,6 +479,61 @@ pub trait PagedMixnetQueryClient: MixnetQueryClient { async fn get_all_mixnodes_detailed(&self) -> Result, NyxdError> { collect_paged!(self, get_mixnodes_detailed_paged, nodes) } + + async fn get_all_unbonded_mixnodes(&self) -> Result, NyxdError> { + collect_paged!(self, get_unbonded_paged, nodes) + } + + async fn get_all_unbonded_mixnodes_by_owner( + &self, + owner: &AccountId, + ) -> Result, NyxdError> { + collect_paged!(self, get_unbonded_by_owner_paged, nodes, owner) + } + + async fn get_all_unbonded_mixnodes_by_identity( + &self, + identity_key: IdentityKeyRef<'_>, + ) -> Result, NyxdError> { + collect_paged!(self, get_unbonded_by_identity_paged, nodes, identity_key) + } + + async fn get_all_gateways(&self) -> Result, NyxdError> { + collect_paged!(self, get_gateways_paged, nodes) + } + + async fn get_all_single_mixnode_delegations( + &self, + mix_id: MixId, + ) -> Result, NyxdError> { + collect_paged!(self, get_mixnode_delegations_paged, delegations, mix_id) + } + + async fn get_all_delegator_delegations( + &self, + delegation_owner: &AccountId, + ) -> Result, NyxdError> { + collect_paged!( + self, + get_delegator_delegations_paged, + delegations, + delegation_owner + ) + } + + async fn get_all_network_delegations(&self) -> Result, NyxdError> { + collect_paged!(self, get_all_network_delegations_paged, delegations) + } + + async fn get_all_pending_epoch_events(&self) -> Result, NyxdError> { + collect_paged!(self, get_pending_epoch_events_paged, events) + } + + async fn get_all_pending_interval_events( + &self, + ) -> Result, NyxdError> { + collect_paged!(self, get_pending_interval_events_paged, events) + } } #[async_trait] diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/mod.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/mod.rs index 80dfb1b505..888e24af19 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/mod.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/mod.rs @@ -129,6 +129,7 @@ impl TryFrom for TypedNymContracts { // a simple helper macro to define to repeatedly call a paged query until a full response is constructed #[macro_export] macro_rules! collect_paged { + // TODO: deal with the args in a nicer way ( $self:ident, $f: ident, $field: ident ) => {{ let mut res = Vec::new(); let mut start_after = None; @@ -143,4 +144,19 @@ macro_rules! collect_paged { } } }}; + + ( $self:ident, $f: ident, $field: ident, $($args:tt),*) => {{ + let mut res = Vec::new(); + let mut start_after = None; + loop { + let paged_response = $self.$f($($args),*, start_after.take(), None).await?; + res.extend(paged_response.$field); + + if let Some(start_next_after) = paged_response.start_next_after { + start_after = Some(start_next_after) + } else { + break Ok(res); + } + } + }}; } From ce47e911866296a92e0c0b4610907ea8ee315936 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Tue, 1 Aug 2023 11:37:39 +0100 Subject: [PATCH 06/24] first round of cleanup --- common/bandwidth-controller/Cargo.toml | 1 - common/client-core/Cargo.toml | 1 - .../client-libs/validator-client/Cargo.toml | 19 ++-- .../validator-client/src/client.rs | 83 +++----------- .../validator-client/src/coconut/mod.rs | 82 ++++++++++++++ .../client-libs/validator-client/src/lib.rs | 2 +- .../coconut_bandwidth_query_client.rs | 7 +- .../nyxd/contract_traits/dkg_query_client.rs | 101 ++++-------------- .../contract_traits/group_query_client.rs | 2 +- .../src/nyxd/contract_traits/mod.rs | 4 +- .../sp_directory_query_client.rs | 2 +- .../contract_traits/vesting_query_client.rs | 2 +- .../nyxd/cosmwasm_client/client_traits/mod.rs | 4 - .../src/nyxd/cosmwasm_client/helpers.rs | 1 - .../src/nyxd/cosmwasm_client/mod.rs | 26 ++++- .../validator-client/src/nyxd/error.rs | 5 +- .../src/nyxd/fee/gas_price.rs | 2 +- .../validator-client/src/nyxd/mod.rs | 71 +++++------- common/commands/Cargo.toml | 2 +- nym-api/Cargo.toml | 4 +- nym-wallet/src-tauri/Cargo.toml | 4 +- 21 files changed, 187 insertions(+), 238 deletions(-) create mode 100644 common/client-libs/validator-client/src/coconut/mod.rs diff --git a/common/bandwidth-controller/Cargo.toml b/common/bandwidth-controller/Cargo.toml index 5b168d8b9f..9c57b20a08 100644 --- a/common/bandwidth-controller/Cargo.toml +++ b/common/bandwidth-controller/Cargo.toml @@ -20,4 +20,3 @@ nym-validator-client = { path = "../client-libs/validator-client", default-featu [target."cfg(not(target_arch = \"wasm32\"))".dependencies.nym-validator-client] path = "../client-libs/validator-client" -features = ["signing"] diff --git a/common/client-core/Cargo.toml b/common/client-core/Cargo.toml index 0811b08add..3281272c5e 100644 --- a/common/client-core/Cargo.toml +++ b/common/client-core/Cargo.toml @@ -47,7 +47,6 @@ nym-network-defaults = { path = "../network-defaults" } [target."cfg(not(target_arch = \"wasm32\"))".dependencies.nym-validator-client] path = "../client-libs/validator-client" -features = ["signing", "http-client"] [target."cfg(not(target_arch = \"wasm32\"))".dependencies.tokio-stream] version = "0.1.11" diff --git a/common/client-libs/validator-client/Cargo.toml b/common/client-libs/validator-client/Cargo.toml index bead36057c..58b4d8b581 100644 --- a/common/client-libs/validator-client/Cargo.toml +++ b/common/client-libs/validator-client/Cargo.toml @@ -35,7 +35,8 @@ nym-network-defaults = { path = "../../network-defaults" } nym-api-requests = { path = "../../../nym-api/nym-api-requests" } async-trait = { workspace = true } -bip39 = { workspace = true, features = ["rand"], optional = true } +#bip39 = { workspace = true, features = ["rand"], optional = true } +bip39 = { workspace = true, features = ["rand"] } nym-config = { path = "../../config" } cosmrs = { workspace = true, features = ["bip32", "cosmwasm"] } #cosmrs = { workspace = true, features = ["bip32", "rpc", "cosmwasm"], optional = true } @@ -44,7 +45,7 @@ cosmrs = { workspace = true, features = ["bip32", "cosmwasm"] } # import it just for the `Client` trait tendermint-rpc = { workspace = true } -eyre = { version = "0.6", optional = true } +eyre = { version = "0.6" } cw-utils = { workspace = true } cw3 = { workspace = true } cw4 = { workspace = true } @@ -52,7 +53,7 @@ prost = { version = "0.11", default-features = false } flate2 = { version = "1.0.20" } sha2 = { version = "0.9.5" } itertools = { version = "0.10" } -zeroize = { version = "1.5.7", optional = true, features = ["zeroize_derive"] } +zeroize = { version = "1.5.7", features = ["zeroize_derive"] } cosmwasm-std = { workspace = true } [dev-dependencies] @@ -67,24 +68,20 @@ name = "offline_signing" # it should only really require the "signing" feature, # but that would require another round of refactoring to make it possible # (traits would need to be moved around and refactored themselves) -required-features = ["http-client", "signing"] +required-features = ["http-client"] [[example]] name = "query_service_provider_directory" # TODO: validate the requirements -required-features = ["http-client", "signing"] +required-features = ["http-client"] [[example]] name = "query_name_service" # TODO: validate the requirements -required-features = ["http-client", "signing"] +required-features = ["http-client"] [features] +default = ["http-client"] http-client = ["cosmrs/rpc", "openssl"] -signing = [ - "bip39", - "eyre", - "zeroize" -] generate-ts = [] diff --git a/common/client-libs/validator-client/src/client.rs b/common/client-libs/validator-client/src/client.rs index 27020200d5..0b2ecd01f6 100644 --- a/common/client-libs/validator-client/src/client.rs +++ b/common/client-libs/validator-client/src/client.rs @@ -1,40 +1,33 @@ // Copyright 2021-2023 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 +use crate::nyxd::contract_traits::NymContractsProvider; +use crate::nyxd::{self, NyxdClient}; +use crate::signing::signer::NoSigner; use crate::{nym_api, ValidatorClientError}; use nym_api_requests::coconut::{ BlindSignRequestBody, BlindedSignatureResponse, VerifyCredentialBody, VerifyCredentialResponse, }; +use nym_api_requests::models::MixNodeBondAnnotated; use nym_api_requests::models::{ GatewayCoreStatusResponse, MixnodeCoreStatusResponse, MixnodeStatusResponse, RewardEstimationResponse, StakeSaturationResponse, }; -use nym_coconut_dkg_common::types::NodeIndex; -use nym_coconut_interface::VerificationKey; +use nym_network_defaults::NymNetworkDetails; +use url::Url; + pub use nym_mixnet_contract_common::{ mixnode::MixNodeDetails, GatewayBond, IdentityKey, IdentityKeyRef, MixId, }; -use url::Url; -// use crate::nyxd::contract_traits::{DkgQueryClient, MixnetQueryClient}; -use crate::nyxd::contract_traits::NymContractsProvider; -use crate::nyxd::{self, CosmWasmClient, NyxdClient}; -use nym_api_requests::models::MixNodeBondAnnotated; -use nym_coconut_dkg_common::{types::EpochId, verification_key::ContractVKShare}; -use nym_coconut_interface::Base58; -use nym_mixnet_contract_common::{ - families::{Family, FamilyHead}, - mixnode::MixNodeBond, - pending_events::{PendingEpochEvent, PendingIntervalEvent}, - Delegation, RewardedSetNodeStatus, UnbondedMixnode, -}; -use nym_network_defaults::NymNetworkDetails; -use std::str::FromStr; -use tendermint_rpc::HttpClient; +// re-export the type to not break existing imports +pub use crate::coconut::CoconutApiClient; -#[cfg(all(feature = "signing", feature = "http-client"))] +#[cfg(feature = "direct-secp256k1-wallet")] use crate::signing::direct_wallet::DirectSecp256k1HdWallet; -use crate::signing::signer::NoSigner; + +#[cfg(feature = "http-client")] +use tendermint_rpc::HttpClient; #[must_use] #[derive(Debug, Clone)] @@ -91,7 +84,7 @@ pub struct Client { pub nyxd: NyxdClient, } -#[cfg(all(feature = "signing", feature = "http-client"))] +#[cfg(all(feature = "direct-secp256k1-wallet", feature = "http-client"))] impl Client { pub fn new_signing( config: Config, @@ -114,11 +107,6 @@ impl Client { self.nyxd.change_endpoint(new_endpoint.as_ref())?; Ok(()) } - - pub fn set_nyxd_simulated_gas_multiplier(&mut self, multiplier: f32) { - todo!() - // self.nyxd.set_simulated_gas_multiplier(multiplier) - } } #[cfg(feature = "http-client")] @@ -219,49 +207,6 @@ impl Client { } } -#[derive(Clone)] -pub struct CoconutApiClient { - pub api_client: NymApiClient, - pub verification_key: VerificationKey, - pub node_id: NodeIndex, - pub cosmos_address: cosmrs::AccountId, -} - -impl CoconutApiClient { - // pub async fn all_coconut_api_clients( - // client: &C, - // epoch_id: EpochId, - // ) -> Result, ValidatorClientError> - // where - // C: DkgQueryClient + Sync + Send, - // { - // Ok(client - // .get_all_verification_key_shares(epoch_id) - // .await? - // .into_iter() - // .filter_map(Self::try_from) - // .collect()) - // } - - fn try_from(share: ContractVKShare) -> Option { - if share.verified { - if let Ok(url_address) = Url::parse(&share.announce_address) { - if let Ok(verification_key) = VerificationKey::try_from_bs58(&share.share) { - if let Ok(cosmos_address) = cosmrs::AccountId::from_str(share.owner.as_str()) { - return Some(CoconutApiClient { - api_client: NymApiClient::new(url_address), - verification_key, - node_id: share.node_index, - cosmos_address, - }); - } - } - } - } - None - } -} - #[derive(Clone)] pub struct NymApiClient { pub nym_api: nym_api::Client, diff --git a/common/client-libs/validator-client/src/coconut/mod.rs b/common/client-libs/validator-client/src/coconut/mod.rs new file mode 100644 index 0000000000..640000189b --- /dev/null +++ b/common/client-libs/validator-client/src/coconut/mod.rs @@ -0,0 +1,82 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::NymApiClient; +use nym_coconut_dkg_common::types::NodeIndex; +use nym_coconut_dkg_common::verification_key::ContractVKShare; +use nym_coconut_interface::{Base58, CoconutError, VerificationKey}; +use thiserror::Error; +use url::Url; + +// TODO: it really doesn't feel like this should live in this crate. +#[derive(Clone)] +pub struct CoconutApiClient { + pub api_client: NymApiClient, + pub verification_key: VerificationKey, + pub node_id: NodeIndex, + pub cosmos_address: cosmrs::AccountId, +} + +// TODO: this should be using the coconut error +// (which is in different crate; perhaps this client should be moved there?) + +#[derive(Debug, Error)] +pub enum CoconutApiError { + // TODO: ask @BN whether this is a correct error message + #[error("the provided key share hasn't been verified")] + UnverifiedShare, + + #[error("the provided announce address is malformed: {source}")] + MalformedAnnounceAddress { + #[from] + source: url::ParseError, + }, + + #[error("the provided verification key is malformed: {source}")] + MalformedVerificationKey { + #[from] + source: CoconutError, + }, + + #[error("the provided account address is malformed: {source}")] + MalformedAccountAddress { + #[from] + source: cosmrs::ErrorReport, + }, +} + +impl TryFrom for CoconutApiClient { + type Error = CoconutApiError; + + fn try_from(share: ContractVKShare) -> Result { + if !share.verified { + return Err(CoconutApiError::UnverifiedShare); + } + + let url_address = Url::parse(&share.announce_address)?; + + Ok(CoconutApiClient { + api_client: NymApiClient::new(url_address), + verification_key: VerificationKey::try_from_bs58(&share.share)?, + node_id: share.node_index, + cosmos_address: share.owner.as_str().parse()?, + }) + } +} + +// impl CoconutApiClient { +// // pub async fn all_coconut_api_clients( +// // client: &C, +// // epoch_id: EpochId, +// // ) -> Result, ValidatorClientError> +// // where +// // C: DkgQueryClient + Sync + Send, +// // { +// // Ok(client +// // .get_all_verification_key_shares(epoch_id) +// // .await? +// // .into_iter() +// // .filter_map(Self::try_from) +// // .collect()) +// // } +// } diff --git a/common/client-libs/validator-client/src/lib.rs b/common/client-libs/validator-client/src/lib.rs index ab0cff646e..a3d5422b99 100644 --- a/common/client-libs/validator-client/src/lib.rs +++ b/common/client-libs/validator-client/src/lib.rs @@ -8,7 +8,7 @@ pub mod error; pub mod nym_api; pub mod nyxd; -#[cfg(feature = "signing")] +pub mod coconut; pub mod signing; pub use crate::error::ValidatorClientError; diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/coconut_bandwidth_query_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/coconut_bandwidth_query_client.rs index b1ecc7a18c..b48ab83e94 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/coconut_bandwidth_query_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/coconut_bandwidth_query_client.rs @@ -1,13 +1,12 @@ // Copyright 2022-2023 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 +use crate::nyxd::contract_traits::NymContractsProvider; use crate::nyxd::error::NyxdError; -use crate::nyxd::{CosmWasmClient, NyxdClient}; +use crate::nyxd::CosmWasmClient; +use async_trait::async_trait; use nym_coconut_bandwidth_contract_common::msg::QueryMsg as CoconutBandwidthQueryMsg; use nym_coconut_bandwidth_contract_common::spend_credential::SpendCredentialResponse; - -use crate::nyxd::contract_traits::NymContractsProvider; -use async_trait::async_trait; use serde::Deserialize; #[async_trait] 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 9465cc74ab..7acc1e4041 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 @@ -1,9 +1,10 @@ // Copyright 2022 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 +use crate::collect_paged; use crate::nyxd::contract_traits::NymContractsProvider; use crate::nyxd::error::NyxdError; -use crate::nyxd::{CosmWasmClient, NyxdClient}; +use crate::nyxd::CosmWasmClient; use async_trait::async_trait; use cosmrs::AccountId; use nym_coconut_dkg_common::dealer::{ @@ -47,24 +48,18 @@ pub trait DkgQueryClient { async fn get_current_dealers_paged( &self, start_after: Option, - page_limit: Option, + limit: Option, ) -> Result { - let request = DkgQueryMsg::GetCurrentDealers { - start_after, - limit: page_limit, - }; + let request = DkgQueryMsg::GetCurrentDealers { start_after, limit }; self.query_dkg_contract(request).await } async fn get_past_dealers_paged( &self, start_after: Option, - page_limit: Option, + limit: Option, ) -> Result { - let request = DkgQueryMsg::GetPastDealers { - start_after, - limit: page_limit, - }; + let request = DkgQueryMsg::GetPastDealers { start_after, limit }; self.query_dkg_contract(request).await } @@ -72,11 +67,11 @@ pub trait DkgQueryClient { &self, idx: usize, start_after: Option, - page_limit: Option, + limit: Option, ) -> Result { let request = DkgQueryMsg::GetDealing { idx: idx as u64, - limit: page_limit, + limit, start_after, }; self.query_dkg_contract(request).await @@ -86,96 +81,44 @@ pub trait DkgQueryClient { &self, epoch_id: EpochId, start_after: Option, - page_limit: Option, + limit: Option, ) -> Result { let request = DkgQueryMsg::GetVerificationKeys { epoch_id, - limit: page_limit, + limit, start_after, }; self.query_dkg_contract(request).await } +} +// extension trait to the query client to deal with the paged queries +// (it didn't feel appropriate to combine it with the existing trait +#[async_trait] +pub trait PagedDkgQueryClient: DkgQueryClient { async fn get_all_current_dealers(&self) -> Result, NyxdError> { - let mut dealers = Vec::new(); - let mut start_after = None; - loop { - let mut paged_response = self - .get_current_dealers_paged(start_after.take(), None) - .await?; - dealers.append(&mut paged_response.dealers); - - if let Some(start_after_res) = paged_response.start_next_after { - start_after = Some(start_after_res.into_string()) - } else { - break; - } - } - - Ok(dealers) + collect_paged!(self, get_current_dealers_paged, dealers) } async fn get_all_past_dealers(&self) -> Result, NyxdError> { - let mut dealers = Vec::new(); - let mut start_after = None; - loop { - let mut paged_response = self - .get_past_dealers_paged(start_after.take(), None) - .await?; - dealers.append(&mut paged_response.dealers); - - if let Some(start_after_res) = paged_response.start_next_after { - start_after = Some(start_after_res.into_string()) - } else { - break; - } - } - - Ok(dealers) + collect_paged!(self, get_past_dealers_paged, dealers) } async fn get_all_epoch_dealings(&self, idx: usize) -> Result, NyxdError> { - let mut dealings = Vec::new(); - let mut start_after = None; - loop { - let mut paged_response = self - .get_dealings_paged(idx, start_after.take(), None) - .await?; - dealings.append(&mut paged_response.dealings); - - if let Some(start_after_res) = paged_response.start_next_after { - start_after = Some(start_after_res.into_string()) - } else { - break; - } - } - - Ok(dealings) + collect_paged!(self, get_dealings_paged, dealings, idx) } async fn get_all_verification_key_shares( &self, epoch_id: EpochId, ) -> Result, NyxdError> { - let mut shares = Vec::new(); - let mut start_after = None; - loop { - let mut paged_response = self - .get_vk_shares_paged(epoch_id, start_after.take(), None) - .await?; - shares.append(&mut paged_response.shares); - - if let Some(start_after_res) = paged_response.start_next_after { - start_after = Some(start_after_res.into_string()) - } else { - break; - } - } - - Ok(shares) + collect_paged!(self, get_vk_shares_paged, shares, epoch_id) } } +#[async_trait] +impl PagedDkgQueryClient for T where T: DkgQueryClient {} + #[async_trait] impl DkgQueryClient for C where diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/group_query_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/group_query_client.rs index 6102bcc5f2..3bc5bcabef 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/group_query_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/group_query_client.rs @@ -3,7 +3,7 @@ use crate::nyxd::contract_traits::NymContractsProvider; use crate::nyxd::error::NyxdError; -use crate::nyxd::{CosmWasmClient, NyxdClient}; +use crate::nyxd::CosmWasmClient; use async_trait::async_trait; use cw4::MemberResponse; use nym_group_contract_common::msg::QueryMsg as GroupQueryMsg; diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/mod.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/mod.rs index 888e24af19..9906e7dbdb 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/mod.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/mod.rs @@ -138,7 +138,7 @@ macro_rules! collect_paged { res.extend(paged_response.$field); if let Some(start_next_after) = paged_response.start_next_after { - start_after = Some(start_next_after) + start_after = Some(start_next_after.into()) } else { break Ok(res); } @@ -153,7 +153,7 @@ macro_rules! collect_paged { res.extend(paged_response.$field); if let Some(start_next_after) = paged_response.start_next_after { - start_after = Some(start_next_after) + start_after = Some(start_next_after.into()) } else { break Ok(res); } diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/sp_directory_query_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/sp_directory_query_client.rs index a292cb1121..f246fc7f18 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/sp_directory_query_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/sp_directory_query_client.rs @@ -11,7 +11,7 @@ use nym_service_provider_directory_common::{ use serde::Deserialize; use crate::nyxd::contract_traits::NymContractsProvider; -use crate::nyxd::{error::NyxdError, CosmWasmClient, NyxdClient}; +use crate::nyxd::{error::NyxdError, CosmWasmClient}; #[async_trait] pub trait SpDirectoryQueryClient { diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/vesting_query_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/vesting_query_client.rs index df073b4e45..6d96546c87 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/vesting_query_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/vesting_query_client.rs @@ -4,7 +4,7 @@ use crate::nyxd::coin::Coin; use crate::nyxd::contract_traits::NymContractsProvider; use crate::nyxd::error::NyxdError; -use crate::nyxd::{CosmWasmClient, NyxdClient}; +use crate::nyxd::CosmWasmClient; use async_trait::async_trait; use cosmwasm_std::{Coin as CosmWasmCoin, Timestamp}; use nym_contracts_common::ContractBuildInformation; diff --git a/common/client-libs/validator-client/src/nyxd/cosmwasm_client/client_traits/mod.rs b/common/client-libs/validator-client/src/nyxd/cosmwasm_client/client_traits/mod.rs index 1fc9b3789d..bfa126ba37 100644 --- a/common/client-libs/validator-client/src/nyxd/cosmwasm_client/client_traits/mod.rs +++ b/common/client-libs/validator-client/src/nyxd/cosmwasm_client/client_traits/mod.rs @@ -2,11 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 pub mod query_client; - -#[cfg(feature = "signing")] pub mod signing_client; pub use query_client::CosmWasmClient; - -#[cfg(feature = "signing")] pub use signing_client::SigningCosmWasmClient; diff --git a/common/client-libs/validator-client/src/nyxd/cosmwasm_client/helpers.rs b/common/client-libs/validator-client/src/nyxd/cosmwasm_client/helpers.rs index 64c2fd25fa..b639b223e3 100644 --- a/common/client-libs/validator-client/src/nyxd/cosmwasm_client/helpers.rs +++ b/common/client-libs/validator-client/src/nyxd/cosmwasm_client/helpers.rs @@ -48,7 +48,6 @@ impl CheckResponse for crate::nyxd::TxResponse { } } -#[cfg(feature = "signing")] pub(crate) fn compress_wasm_code(code: &[u8]) -> Result, NyxdError> { use flate2::write::GzEncoder; use flate2::Compression; 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 be570d128d..e8c78c1884 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 @@ -4,13 +4,18 @@ use crate::nyxd::cosmwasm_client::client_traits::{CosmWasmClient, SigningCosmWasmClient}; use crate::nyxd::error::NyxdError; use crate::nyxd::{Config, GasPrice, TendermintClient}; -use crate::signing::signer::{NoSigner, OfflineSigner}; -use crate::signing::tx_signer::TxSigner; -use crate::signing::AccountData; use async_trait::async_trait; -use cosmrs::rpc::Error as TendermintRpcError; use cosmrs::AccountId; -use tendermint_rpc::SimpleRequest; +use tendermint_rpc::{Error as TendermintRpcError, SimpleRequest}; + +#[cfg(feature = "http-client")] +use cosmrs::rpc::{HttpClient, HttpClientUrl}; + +use crate::signing::{ + signer::{NoSigner, OfflineSigner}, + tx_signer::TxSigner, + AccountData, +}; pub mod client_traits; mod helpers; @@ -78,6 +83,17 @@ impl MaybeSigningClient { } } +#[cfg(feature = "http-client")] +impl MaybeSigningClient { + pub(crate) fn change_endpoint(&mut self, new_endpoint: U) -> Result<(), NyxdError> + where + U: TryInto, + { + self.client = HttpClient::new(new_endpoint)?; + Ok(()) + } +} + #[async_trait] impl TendermintClient for MaybeSigningClient where diff --git a/common/client-libs/validator-client/src/nyxd/error.rs b/common/client-libs/validator-client/src/nyxd/error.rs index 7a414a6914..e247dff6a1 100644 --- a/common/client-libs/validator-client/src/nyxd/error.rs +++ b/common/client-libs/validator-client/src/nyxd/error.rs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use crate::nyxd::cosmwasm_client::types::ContractCodeId; +use crate::signing::direct_wallet::DirectSecp256k1HdWalletError; use cosmrs::tendermint::Hash; use cosmrs::{ tendermint::{abci::Code as AbciCode, block}, @@ -11,9 +12,6 @@ use std::{io, time::Duration}; use tendermint_rpc::endpoint::abci_query::AbciQuery; use thiserror::Error; -#[cfg(feature = "signing")] -use crate::signing::direct_wallet::DirectSecp256k1HdWalletError; - pub use cosmrs::tendermint::error::Error as TendermintError; pub use tendermint_rpc::{ error::{Error as TendermintRpcError, ErrorDetail as TendermintRpcErrorDetail}, @@ -25,7 +23,6 @@ pub enum NyxdError { #[error("No contract address is available to perform the call: {0}")] NoContractAddressAvailable(String), - #[cfg(feature = "signing")] #[error(transparent)] WalletError(#[from] DirectSecp256k1HdWalletError), diff --git a/common/client-libs/validator-client/src/nyxd/fee/gas_price.rs b/common/client-libs/validator-client/src/nyxd/fee/gas_price.rs index f6c0d83c24..6f68dbbcf2 100644 --- a/common/client-libs/validator-client/src/nyxd/fee/gas_price.rs +++ b/common/client-libs/validator-client/src/nyxd/fee/gas_price.rs @@ -6,7 +6,7 @@ use cosmrs::Coin; use cosmrs::Gas; use cosmwasm_std::{Decimal, Fraction, Uint128}; use nym_config::defaults; -use nym_network_defaults::{ChainDetails, NymNetworkDetails}; +use nym_network_defaults::NymNetworkDetails; use std::ops::Mul; use std::str::FromStr; diff --git a/common/client-libs/validator-client/src/nyxd/mod.rs b/common/client-libs/validator-client/src/nyxd/mod.rs index 3fb4cc9372..df671473ac 100644 --- a/common/client-libs/validator-client/src/nyxd/mod.rs +++ b/common/client-libs/validator-client/src/nyxd/mod.rs @@ -1,14 +1,13 @@ // Copyright 2021 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use crate::nyxd::cosmwasm_client::types::Account; use crate::nyxd::error::NyxdError; +use async_trait::async_trait; use log::{debug, trace}; use nym_network_defaults::{ChainDetails, NymNetworkDetails}; -use serde::{Deserialize, Serialize}; -use tendermint_rpc::{ - endpoint::block::Response as BlockResponse, query::Query, HttpClient, HttpClientUrl, -}; +use serde::Serialize; +use tendermint_rpc::endpoint::block::Response as BlockResponse; +use tendermint_rpc::Error as TendermintRpcError; pub use crate::nyxd::cosmwasm_client::client_traits::{CosmWasmClient, SigningCosmWasmClient}; pub use crate::nyxd::fee::Fee; @@ -31,28 +30,22 @@ pub use tendermint_rpc::{ Paging, }; -#[cfg(feature = "http-client")] -use tendermint_rpc::Error as TendermintRpcError; - -#[cfg(feature = "signing")] use crate::nyxd::cosmwasm_client::types::{ ChangeAdminResult, ContractCodeId, ExecuteResult, InstantiateOptions, InstantiateResult, MigrateResult, SequenceResponse, SimulateResponse, UploadResult, }; -#[cfg(all(feature = "signing", feature = "http-client"))] -use crate::signing::direct_wallet::DirectSecp256k1HdWallet; -#[cfg(all(feature = "signing", feature = "http-client"))] use crate::signing::signer::OfflineSigner; -use async_trait::async_trait; -#[cfg(feature = "signing")] use cosmrs::cosmwasm; -#[cfg(feature = "signing")] use cosmrs::tx::Msg; -#[cfg(feature = "signing")] use cosmwasm_std::Addr; -#[cfg(feature = "signing")] use std::time::SystemTime; +#[cfg(feature = "http-client")] +use cosmrs::rpc::{HttpClient, HttpClientUrl}; + +#[cfg(feature = "direct-secp256k1-wallet")] +use crate::signing::direct_wallet::DirectSecp256k1HdWallet; + use crate::nyxd::contract_traits::{NymContractsProvider, TypedNymContracts}; use crate::nyxd::cosmwasm_client::MaybeSigningClient; use crate::nyxd::fee::DEFAULT_SIMULATED_GAS_MULTIPLIER; @@ -64,12 +57,8 @@ pub mod cosmwasm_client; pub mod error; pub mod fee; -// temp -#[deprecated] -type QueryNyxdClient = HttpClient; - // helper types -#[cfg(all(feature = "signing", feature = "http-client"))] +#[cfg(all(feature = "direct-secp256k1-wallet", feature = "http-client"))] pub type DirectSigningHttpNyxdClient = NyxdClient; #[cfg(feature = "http-client")] pub type QueryHttpNyxdClient = NyxdClient; @@ -117,6 +106,11 @@ impl Config { simulated_gas_multiplier: DEFAULT_SIMULATED_GAS_MULTIPLIER, }) } + + pub fn with_simulated_gas_multplier(mut self, simulated_gas_multiplier: f32) -> Self { + self.simulated_gas_multiplier = simulated_gas_multiplier; + self + } } // so youd have: @@ -149,7 +143,7 @@ impl NyxdClient { } } -#[cfg(all(feature = "signing", feature = "http-client"))] +#[cfg(all(feature = "direct-secp256k1-wallet", feature = "http-client"))] impl NyxdClient { // TODO: rename this one pub fn connect_with_mnemonic( @@ -166,14 +160,13 @@ impl NyxdClient { } } -#[cfg(all(feature = "signing", feature = "http-client"))] +#[cfg(feature = "http-client")] impl NyxdClient where S: OfflineSigner, // I have no idea why S::Error: Into bound wouldn't do the trick NyxdError: From, { - #[cfg(feature = "http-client")] pub fn connect_with_signer( config: Config, endpoint: U, @@ -188,31 +181,20 @@ where config, }) } +} - // #[cfg(feature = "http-client")] - // pub fn change_endpoint(&mut self, new_endpoint: U) -> Result<(), NyxdError> - // where - // U: TryInto, - // { - // self.client.change_endpoint(new_endpoint) - // } - - #[deprecated] - pub fn into_signer(self) -> S { - todo!() - // self.client.into_signer() +#[cfg(feature = "http-client")] +impl NyxdClient { + pub fn change_endpoint(&mut self, new_endpoint: U) -> Result<(), NyxdError> + where + U: TryInto, + { + self.client.change_endpoint(new_endpoint) } } // no trait bounds impl NyxdClient { - pub(crate) fn change_endpoint(&mut self, new_endpoint: U) -> Result<(), NyxdError> - where - U: TryInto, - { - todo!() - } - pub fn current_config(&self) -> &Config { &self.config } @@ -357,7 +339,6 @@ where } // signing -#[cfg(feature = "signing")] impl NyxdClient where C: SigningCosmWasmClient + Send + Sync, diff --git a/common/commands/Cargo.toml b/common/commands/Cargo.toml index 28f319b875..dd6e8e3895 100644 --- a/common/commands/Cargo.toml +++ b/common/commands/Cargo.toml @@ -28,7 +28,7 @@ tap = "1" cosmrs = { workspace = true } cosmwasm-std = { workspace = true } -nym-validator-client = { path = "../client-libs/validator-client", features = ["signing", "http-client"] } +nym-validator-client = { path = "../client-libs/validator-client" } nym-bin-common = { path = "../../common/bin-common", features = ["output_format"] } nym-crypto = { path = "../../common/crypto", features = ["asymmetric"] } nym-network-defaults = { path = "../network-defaults" } diff --git a/nym-api/Cargo.toml b/nym-api/Cargo.toml index 10f1017cb4..f91180fd37 100644 --- a/nym-api/Cargo.toml +++ b/nym-api/Cargo.toml @@ -91,9 +91,7 @@ nym-pemstore = { path = "../common/pemstore" } nym-task = { path = "../common/task" } nym-topology = { path = "../common/topology" } nym-api-requests = { path = "nym-api-requests" } -nym-validator-client = { path = "../common/client-libs/validator-client", features = [ - "http-client", "signing" -] } +nym-validator-client = { path = "../common/client-libs/validator-client" } nym-bin-common = { path = "../common/bin-common" } nym-node-tester-utils = { path = "../common/node-tester-utils" } diff --git a/nym-wallet/src-tauri/Cargo.toml b/nym-wallet/src-tauri/Cargo.toml index b34190a6d2..2297a1ac90 100644 --- a/nym-wallet/src-tauri/Cargo.toml +++ b/nym-wallet/src-tauri/Cargo.toml @@ -51,9 +51,7 @@ zeroize = { version = "1.5", features = ["zeroize_derive", "serde"] } cosmwasm-std = "1.3.0" cosmrs = "=0.14.0" -nym-validator-client = { path = "../../common/client-libs/validator-client", features = [ - "signing", "http-client" -] } +nym-validator-client = { path = "../../common/client-libs/validator-client" } nym-crypto = { path = "../../common/crypto", features = ["asymmetric"] } nym-contracts-common = { path = "../../common/cosmwasm-smart-contracts/contracts-common" } nym-mixnet-contract-common = { path = "../../common/cosmwasm-smart-contracts/mixnet-contract" } From 93214cabbb89f150f5863a69a1df09f6ac08c104 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Tue, 1 Aug 2023 11:40:07 +0100 Subject: [PATCH 07/24] deprecating wasm mockups to remember to revisit them --- common/bandwidth-controller/src/lib.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/common/bandwidth-controller/src/lib.rs b/common/bandwidth-controller/src/lib.rs index be4142c60a..1c5cf83613 100644 --- a/common/bandwidth-controller/src/lib.rs +++ b/common/bandwidth-controller/src/lib.rs @@ -17,12 +17,15 @@ use { #[cfg(not(target_arch = "wasm32"))] use nym_validator_client::nyxd::contract_traits::DkgQueryClient; +#[deprecated] #[cfg(target_arch = "wasm32")] use crate::wasm_mockups::DkgQueryClient; #[cfg(not(target_arch = "wasm32"))] pub mod acquire; pub mod error; + +#[deprecated] #[cfg(target_arch = "wasm32")] pub mod wasm_mockups; From dbe2790ba02a14726160036a1d580b8171b0ba08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Tue, 1 Aug 2023 13:37:50 +0100 Subject: [PATCH 08/24] restored signing contract traits --- .../validator-client/src/client.rs | 3 - .../coconut_bandwidth_signing_client.rs | 118 +++-- .../contract_traits/dkg_signing_client.rs | 117 ++--- .../contract_traits/group_signing_client.rs | 67 +++ .../contract_traits/mixnet_signing_client.rs | 58 ++- .../src/nyxd/contract_traits/mod.rs | 53 +- .../multisig_signing_client.rs | 152 +++--- .../name_service_signing_client.rs | 53 +- .../sp_directory_signing_client.rs | 61 ++- .../contract_traits/vesting_signing_client.rs | 473 ++++++------------ .../client_traits/signing_client.rs | 5 +- .../src/nyxd/cosmwasm_client/mod.rs | 30 +- .../validator-client/src/nyxd/mod.rs | 48 +- .../validator-client/src/signing/signer.rs | 10 + .../validator-client/src/signing/tx_signer.rs | 5 + 15 files changed, 611 insertions(+), 642 deletions(-) create mode 100644 common/client-libs/validator-client/src/nyxd/contract_traits/group_signing_client.rs diff --git a/common/client-libs/validator-client/src/client.rs b/common/client-libs/validator-client/src/client.rs index 0b2ecd01f6..473da007e8 100644 --- a/common/client-libs/validator-client/src/client.rs +++ b/common/client-libs/validator-client/src/client.rs @@ -23,9 +23,6 @@ pub use nym_mixnet_contract_common::{ // re-export the type to not break existing imports pub use crate::coconut::CoconutApiClient; -#[cfg(feature = "direct-secp256k1-wallet")] -use crate::signing::direct_wallet::DirectSecp256k1HdWallet; - #[cfg(feature = "http-client")] use tendermint_rpc::HttpClient; diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/coconut_bandwidth_signing_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/coconut_bandwidth_signing_client.rs index 1efb4bf494..edf2ac176f 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/coconut_bandwidth_signing_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/coconut_bandwidth_signing_client.rs @@ -1,36 +1,27 @@ // Copyright 2022 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -pub use crate::nyxd::cosmwasm_client::signing_client::SigningCosmWasmClient; +use crate::nyxd::contract_traits::NymContractsProvider; use crate::nyxd::cosmwasm_client::types::ExecuteResult; use crate::nyxd::error::NyxdError; -use crate::nyxd::{Coin, Fee, NyxdClient}; -use nym_coconut_bandwidth_contract_common::spend_credential::SpendCredentialData; -use nym_coconut_bandwidth_contract_common::{deposit::DepositData, msg::ExecuteMsg}; - +use crate::nyxd::{Coin, Fee, SigningCosmWasmClient}; +use crate::signing::signer::OfflineSigner; use async_trait::async_trait; +use nym_coconut_bandwidth_contract_common::spend_credential::SpendCredentialData; +use nym_coconut_bandwidth_contract_common::{ + deposit::DepositData, msg::ExecuteMsg as CoconutBandwidthExecuteMsg, +}; #[async_trait] pub trait CoconutBandwidthSigningClient { - async fn deposit( + async fn execute_coconut_bandwidth_contract( &self, - amount: Coin, - info: String, - verification_key: String, - encryption_key: String, fee: Option, + msg: CoconutBandwidthExecuteMsg, + memo: String, + funds: Vec, ) -> Result; - async fn spend_credential( - &self, - funds: Coin, - blinded_serial_number: String, - gateway_cosmos_address: String, - fee: Option, - ) -> Result; -} -#[async_trait] -impl CoconutBandwidthSigningClient for NyxdClient { async fn deposit( &self, amount: Coin, @@ -39,21 +30,18 @@ impl CoconutBandwidthSigningClient for N encryption_key: String, fee: Option, ) -> Result { - let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier))); - let req = ExecuteMsg::DepositFunds { + let req = CoconutBandwidthExecuteMsg::DepositFunds { data: DepositData::new(info.to_string(), verification_key, encryption_key), }; - self.client - .execute( - self.address(), - self.coconut_bandwidth_contract_address(), - &req, - fee, - "CoconutBandwidth::Deposit", - vec![amount], - ) - .await + self.execute_coconut_bandwidth_contract( + fee, + req, + "CoconutBandwidth::Deposit".to_string(), + vec![amount], + ) + .await } + async fn spend_credential( &self, funds: Coin, @@ -61,23 +49,65 @@ impl CoconutBandwidthSigningClient for N gateway_cosmos_address: String, fee: Option, ) -> Result { - let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier))); - let req = ExecuteMsg::SpendCredential { + let req = CoconutBandwidthExecuteMsg::SpendCredential { data: SpendCredentialData::new( funds.into(), blinded_serial_number, gateway_cosmos_address, ), }; - self.client - .execute( - self.address(), - self.coconut_bandwidth_contract_address(), - &req, - fee, - "CoconutBandwidth::SpendCredential", - vec![], - ) - .await + self.execute_coconut_bandwidth_contract( + fee, + req, + "CoconutBandwidth::SpendCredential".to_string(), + vec![], + ) + .await + } +} + +#[async_trait] +impl CoconutBandwidthSigningClient for C +where + C: SigningCosmWasmClient + NymContractsProvider + Sync, + NyxdError: From<::Error>, +{ + async fn execute_coconut_bandwidth_contract( + &self, + fee: Option, + msg: CoconutBandwidthExecuteMsg, + memo: String, + funds: Vec, + ) -> Result { + let coconut_bandwidth_contract_address = self + .coconut_bandwidth_contract_address() + .ok_or_else(|| NyxdError::unavailable_contract_address("coconut bandwidth contract"))?; + + let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier()))); + let signer_address = &self.signer_addresses()?[0]; + + self.execute( + signer_address, + coconut_bandwidth_contract_address, + &msg, + fee, + memo, + funds, + ) + .await + } +} + +#[cfg(test)] +mod tests { + use super::*; + + // it's enough that this compiles + #[deprecated] + async fn all_execute_variants_are_covered( + client: C, + msg: CoconutBandwidthExecuteMsg, + ) { + unimplemented!() } } diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/dkg_signing_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/dkg_signing_client.rs index c35747f40f..a0fac3a036 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/dkg_signing_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/dkg_signing_client.rs @@ -1,9 +1,11 @@ // Copyright 2022 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 +use crate::nyxd::contract_traits::NymContractsProvider; use crate::nyxd::cosmwasm_client::types::ExecuteResult; use crate::nyxd::error::NyxdError; -use crate::nyxd::{Fee, NyxdClient, SigningCosmWasmClient}; +use crate::nyxd::{Coin, Fee, SigningCosmWasmClient}; +use crate::signing::signer::OfflineSigner; use async_trait::async_trait; use nym_coconut_dkg_common::msg::ExecuteMsg as DkgExecuteMsg; use nym_coconut_dkg_common::types::EncodedBTEPublicKeyWithProof; @@ -12,47 +14,18 @@ use nym_contracts_common::dealings::ContractSafeBytes; #[async_trait] pub trait DkgSigningClient { - async fn advance_dkg_epoch_state(&self, fee: Option) -> Result; - async fn register_dealer( + async fn execute_dkg_contract( &self, - bte_key: EncodedBTEPublicKeyWithProof, - announce_address: String, - resharing: bool, fee: Option, + msg: DkgExecuteMsg, + memo: String, + funds: Vec, ) -> Result; - async fn submit_dealing_bytes( - &self, - commitment: ContractSafeBytes, - resharing: bool, - fee: Option, - ) -> Result; - - async fn submit_verification_key_share( - &self, - share: VerificationKeyShare, - resharing: bool, - fee: Option, - ) -> Result; -} - -#[async_trait] -impl DkgSigningClient for NyxdClient -where - C: SigningCosmWasmClient + Send + Sync, -{ async fn advance_dkg_epoch_state(&self, fee: Option) -> Result { let req = DkgExecuteMsg::AdvanceEpochState {}; - self.client - .execute( - self.address(), - self.coconut_dkg_contract_address(), - &req, - fee.unwrap_or_default(), - "advancing DKG state", - vec![], - ) + self.execute_dkg_contract(fee, req, "advancing DKG state".to_string(), vec![]) .await } @@ -69,15 +42,7 @@ where resharing, }; - self.client - .execute( - self.address(), - self.coconut_dkg_contract_address(), - &req, - fee.unwrap_or_default(), - format!("registering {} as a dealer", self.address()), - vec![], - ) + self.execute_dkg_contract(fee, req, "registering as a dealer".to_string(), vec![]) .await } @@ -92,15 +57,7 @@ where resharing, }; - self.client - .execute( - self.address(), - self.coconut_dkg_contract_address(), - &req, - fee.unwrap_or_default(), - "dealing commitment", - vec![], - ) + self.execute_dkg_contract(fee, req, "dealing commitment".to_string(), vec![]) .await } @@ -112,15 +69,51 @@ where ) -> Result { let req = DkgExecuteMsg::CommitVerificationKeyShare { share, resharing }; - self.client - .execute( - self.address(), - self.coconut_dkg_contract_address(), - &req, - fee.unwrap_or_default(), - "verification key share commitment", - vec![], - ) + self.execute_dkg_contract( + fee, + req, + "verification key share commitment".to_string(), + vec![], + ) + .await + } +} + +#[async_trait] +impl DkgSigningClient for C +where + C: SigningCosmWasmClient + NymContractsProvider + Sync, + NyxdError: From<::Error>, +{ + async fn execute_dkg_contract( + &self, + fee: Option, + msg: DkgExecuteMsg, + memo: String, + funds: Vec, + ) -> Result { + let dkg_contract_address = self + .dkg_contract_address() + .ok_or_else(|| NyxdError::unavailable_contract_address("dkg contract"))?; + + let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier()))); + let signer_address = &self.signer_addresses()?[0]; + + self.execute(signer_address, dkg_contract_address, &msg, fee, memo, funds) .await } } + +#[cfg(test)] +mod tests { + use super::*; + + // it's enough that this compiles + #[deprecated] + async fn all_execute_variants_are_covered( + client: C, + msg: DkgExecuteMsg, + ) { + unimplemented!() + } +} diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/group_signing_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/group_signing_client.rs new file mode 100644 index 0000000000..e17de6ed08 --- /dev/null +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/group_signing_client.rs @@ -0,0 +1,67 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::nyxd::contract_traits::NymContractsProvider; +use crate::nyxd::cosmwasm_client::types::ExecuteResult; +use crate::nyxd::error::NyxdError; +use crate::nyxd::{Coin, Fee, SigningCosmWasmClient}; +use crate::signing::signer::OfflineSigner; +use async_trait::async_trait; +use nym_group_contract_common::msg::ExecuteMsg as GroupExecuteMsg; + +#[async_trait] +pub trait GroupSigningClient { + async fn execute_group_contract( + &self, + fee: Option, + msg: GroupExecuteMsg, + memo: String, + funds: Vec, + ) -> Result; +} + +#[async_trait] +impl GroupSigningClient for C +where + C: SigningCosmWasmClient + NymContractsProvider + Sync, + NyxdError: From<::Error>, +{ + async fn execute_group_contract( + &self, + fee: Option, + msg: GroupExecuteMsg, + memo: String, + funds: Vec, + ) -> Result { + let group_contract_address = self + .group_contract_address() + .ok_or_else(|| NyxdError::unavailable_contract_address("group contract"))?; + + let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier()))); + + let signer_address = &self.signer_addresses()?[0]; + self.execute( + signer_address, + group_contract_address, + &msg, + fee, + memo, + funds, + ) + .await + } +} + +#[cfg(test)] +mod tests { + use super::*; + + // it's enough that this compiles + #[deprecated] + async fn all_execute_variants_are_covered( + client: C, + msg: GroupExecuteMsg, + ) { + unimplemented!() + } +} diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/mixnet_signing_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/mixnet_signing_client.rs index 49fc651d5d..cc5e12e7e8 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/mixnet_signing_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/mixnet_signing_client.rs @@ -2,10 +2,11 @@ // SPDX-License-Identifier: Apache-2.0 use crate::nyxd::coin::Coin; -pub use crate::nyxd::cosmwasm_client::client::CosmWasmClient; +use crate::nyxd::contract_traits::NymContractsProvider; use crate::nyxd::cosmwasm_client::types::ExecuteResult; use crate::nyxd::error::NyxdError; -use crate::nyxd::{Fee, NyxdClient, SigningCosmWasmClient}; +use crate::nyxd::{Fee, SigningCosmWasmClient}; +use crate::signing::signer::OfflineSigner; use async_trait::async_trait; use cosmrs::AccountId; use nym_contracts_common::signing::MessageSignature; @@ -668,9 +669,10 @@ pub trait MixnetSigningClient { } #[async_trait] -impl MixnetSigningClient for NyxdClient +impl MixnetSigningClient for C where - C: SigningCosmWasmClient + Sync + Send, + C: SigningCosmWasmClient + NymContractsProvider + Sync, + NyxdError: From<::Error>, { async fn execute_mixnet_contract( &self, @@ -678,32 +680,36 @@ where msg: MixnetExecuteMsg, funds: Vec, ) -> Result { - let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier))); + let mixnet_contract_address = &self + .mixnet_contract_address() + .ok_or_else(|| NyxdError::unavailable_contract_address("mixnet contract"))?; + + let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier()))); let memo = msg.default_memo(); - self.client - .execute( - self.address(), - self.mixnet_contract_address(), - &msg, - fee, - memo, - funds, - ) - .await + + let signer_address = &self.signer_addresses()?[0]; + self.execute( + signer_address, + mixnet_contract_address, + &msg, + fee, + memo, + funds, + ) + .await } } -#[async_trait] -impl MixnetSigningClient for crate::Client -where - C: SigningCosmWasmClient + Sync + Send + Clone, -{ - async fn execute_mixnet_contract( - &self, - fee: Option, +#[cfg(test)] +mod tests { + use super::*; + + // it's enough that this compiles + #[deprecated] + async fn all_execute_variants_are_covered( + client: C, msg: MixnetExecuteMsg, - funds: Vec, - ) -> Result { - self.nyxd.execute_mixnet_contract(fee, msg, funds).await + ) { + unimplemented!() } } diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/mod.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/mod.rs index 9906e7dbdb..8d49af5b55 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/mod.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/mod.rs @@ -7,6 +7,7 @@ use std::str::FromStr; // TODO: all of those could/should be derived via a macro +// query clients mod coconut_bandwidth_query_client; mod dkg_query_client; mod group_query_client; @@ -16,45 +17,37 @@ mod name_service_query_client; mod sp_directory_query_client; mod vesting_query_client; -// #[cfg(feature = "signing")] -// mod coconut_bandwidth_signing_client; -// #[cfg(feature = "signing")] -// mod dkg_signing_client; -// #[cfg(feature = "signing")] -// mod mixnet_signing_client; -// #[cfg(feature = "signing")] -// mod multisig_signing_client; -// #[cfg(feature = "signing")] -// mod name_service_signing_client; -// #[cfg(feature = "signing")] -// mod sp_directory_signing_client; -// #[cfg(feature = "signing")] -// mod vesting_signing_client; +// signing clients +mod coconut_bandwidth_signing_client; +mod dkg_signing_client; +mod group_signing_client; +mod mixnet_signing_client; +mod multisig_signing_client; +mod name_service_signing_client; +mod sp_directory_signing_client; +mod vesting_signing_client; +// re-export query traits pub use coconut_bandwidth_query_client::CoconutBandwidthQueryClient; -pub use dkg_query_client::DkgQueryClient; +pub use dkg_query_client::{DkgQueryClient, PagedDkgQueryClient}; pub use group_query_client::GroupQueryClient; -pub use mixnet_query_client::MixnetQueryClient; +pub use mixnet_query_client::{MixnetQueryClient, PagedMixnetQueryClient}; pub use multisig_query_client::MultisigQueryClient; pub use name_service_query_client::NameServiceQueryClient; pub use sp_directory_query_client::SpDirectoryQueryClient; pub use vesting_query_client::VestingQueryClient; -// #[cfg(feature = "signing")] -// pub use coconut_bandwidth_signing_client::CoconutBandwidthSigningClient; -// #[cfg(feature = "signing")] -// pub use dkg_signing_client::DkgSigningClient; -// #[cfg(feature = "signing")] -// pub use mixnet_signing_client::MixnetSigningClient; -// #[cfg(feature = "signing")] -// pub use multisig_signing_client::MultisigSigningClient; -// #[cfg(feature = "signing")] -// pub use name_service_signing_client::NameServiceSigningClient; -// #[cfg(feature = "signing")] -// pub use sp_directory_signing_client::SpDirectorySigningClient; -// #[cfg(feature = "signing")] -// pub use vesting_signing_client::VestingSigningClient; +// re-export signing traits +pub use coconut_bandwidth_signing_client::CoconutBandwidthSigningClient; +pub use dkg_signing_client::DkgSigningClient; +pub use group_signing_client::GroupSigningClient; +pub use mixnet_signing_client::MixnetSigningClient; +pub use multisig_signing_client::MultisigSigningClient; +pub use name_service_signing_client::NameServiceSigningClient; +pub use sp_directory_signing_client::SpDirectorySigningClient; +pub use vesting_signing_client::VestingSigningClient; +// helper for providing blanket implementation for query clients pub trait NymContractsProvider { // main fn mixnet_contract_address(&self) -> Option<&AccountId>; diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/multisig_signing_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/multisig_signing_client.rs index b5ad0a8e96..b19f5de10c 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/multisig_signing_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/multisig_signing_client.rs @@ -1,79 +1,59 @@ // Copyright 2022 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -pub use crate::nyxd::cosmwasm_client::signing_client::SigningCosmWasmClient; +use crate::nyxd::contract_traits::NymContractsProvider; use crate::nyxd::cosmwasm_client::types::ExecuteResult; use crate::nyxd::error::NyxdError; -use crate::nyxd::{Fee, NyxdClient}; - +use crate::nyxd::{Coin, Fee, SigningCosmWasmClient}; +use crate::signing::signer::OfflineSigner; +use async_trait::async_trait; +use cosmwasm_std::{to_binary, CosmosMsg, WasmMsg}; use cw3::Vote; use nym_coconut_bandwidth_contract_common::msg::ExecuteMsg as CoconutBandwidthExecuteMsg; -use nym_multisig_contract_common::msg::ExecuteMsg; - -use async_trait::async_trait; -use cosmwasm_std::{to_binary, Coin, CosmosMsg, WasmMsg}; +use nym_multisig_contract_common::msg::ExecuteMsg as MultisigExecuteMsg; #[async_trait] -pub trait MultisigSigningClient { +pub trait MultisigSigningClient: NymContractsProvider { + async fn execute_multisig_contract( + &self, + fee: Option, + msg: MultisigExecuteMsg, + memo: String, + funds: Vec, + ) -> Result; + async fn propose_release_funds( &self, title: String, blinded_serial_number: String, - voucher_value: u128, - fee: Option, - ) -> Result; - - async fn vote_proposal( - &self, - proposal_id: u64, - yes: bool, - fee: Option, - ) -> Result; - - async fn execute_proposal( - &self, - proposal_id: u64, - fee: Option, - ) -> Result; -} - -#[async_trait] -impl MultisigSigningClient for NyxdClient { - async fn propose_release_funds( - &self, - title: String, - blinded_serial_number: String, - voucher_value: u128, + voucher_value: Coin, fee: Option, ) -> Result { - let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier))); + let coconut_bandwidth_contract_address = self + .coconut_bandwidth_contract_address() + .ok_or_else(|| NyxdError::unavailable_contract_address("coconut bandwidth contract"))?; + let release_funds_req = CoconutBandwidthExecuteMsg::ReleaseFunds { - funds: Coin::new( - voucher_value, - self.config.chain_details.mix_denom.base.clone(), - ), + funds: voucher_value.into(), }; let release_funds_msg = CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: self.coconut_bandwidth_contract_address().to_string(), + contract_addr: coconut_bandwidth_contract_address.to_string(), msg: to_binary(&release_funds_req)?, funds: vec![], }); - let req = ExecuteMsg::Propose { + let req = MultisigExecuteMsg::Propose { title, description: blinded_serial_number, msgs: vec![release_funds_msg], latest: None, }; - self.client - .execute( - self.address(), - self.multisig_contract_address(), - &req, - fee, - "Multisig::Propose::Execute::ReleaseFunds", - vec![], - ) - .await + self.execute_multisig_contract( + fee, + req, + "Multisig::Propose::Execute::ReleaseFunds".to_string(), + vec![], + ) + .await } async fn vote_proposal( @@ -82,18 +62,9 @@ impl MultisigSigningClient for NyxdClien vote_yes: bool, fee: Option, ) -> Result { - let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier))); let vote = if vote_yes { Vote::Yes } else { Vote::No }; - let req = ExecuteMsg::Vote { proposal_id, vote }; - self.client - .execute( - self.address(), - self.multisig_contract_address(), - &req, - fee, - "Multisig::Vote", - vec![], - ) + let req = MultisigExecuteMsg::Vote { proposal_id, vote }; + self.execute_multisig_contract(fee, req, "Multisig::Vote".to_string(), vec![]) .await } @@ -102,17 +73,54 @@ impl MultisigSigningClient for NyxdClien proposal_id: u64, fee: Option, ) -> Result { - let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier))); - let req = ExecuteMsg::Execute { proposal_id }; - self.client - .execute( - self.address(), - self.multisig_contract_address(), - &req, - fee, - "Multisig::Execute", - vec![], - ) + let req = MultisigExecuteMsg::Execute { proposal_id }; + self.execute_multisig_contract(fee, req, "Multisig::Execute".to_string(), vec![]) .await } } + +#[async_trait] +impl MultisigSigningClient for C +where + C: SigningCosmWasmClient + NymContractsProvider + Sync, + NyxdError: From<::Error>, +{ + async fn execute_multisig_contract( + &self, + fee: Option, + msg: MultisigExecuteMsg, + memo: String, + funds: Vec, + ) -> Result { + let multisig_contract_address = self + .multisig_contract_address() + .ok_or_else(|| NyxdError::unavailable_contract_address("multisig contract"))?; + + let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier()))); + + let signer_address = &self.signer_addresses()?[0]; + self.execute( + signer_address, + multisig_contract_address, + &msg, + fee, + memo, + funds, + ) + .await + } +} + +#[cfg(test)] +mod tests { + use super::*; + + // it's enough that this compiles + #[deprecated] + async fn all_execute_variants_are_covered( + client: C, + msg: MultisigExecuteMsg, + ) { + unimplemented!() + } +} diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/name_service_signing_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/name_service_signing_client.rs index 1235043094..63dde6dd0d 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/name_service_signing_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/name_service_signing_client.rs @@ -5,10 +5,11 @@ use async_trait::async_trait; use nym_contracts_common::signing::MessageSignature; use nym_name_service_common::{msg::ExecuteMsg as NameExecuteMsg, NameDetails, NameId, NymName}; +use crate::nyxd::contract_traits::NymContractsProvider; use crate::nyxd::{ - coin::Coin, cosmwasm_client::types::ExecuteResult, error::NyxdError, Fee, NyxdClient, - SigningCosmWasmClient, + coin::Coin, cosmwasm_client::types::ExecuteResult, error::NyxdError, Fee, SigningCosmWasmClient, }; +use crate::signing::signer::OfflineSigner; #[async_trait] pub trait NameServiceSigningClient { @@ -72,9 +73,10 @@ pub trait NameServiceSigningClient { } #[async_trait] -impl NameServiceSigningClient for NyxdClient +impl NameServiceSigningClient for C where - C: SigningCosmWasmClient + Sync + Send, + C: SigningCosmWasmClient + NymContractsProvider + Sync, + NyxdError: From<::Error>, { async fn execute_name_service_contract( &self, @@ -82,19 +84,36 @@ where msg: NameExecuteMsg, funds: Vec, ) -> Result { - let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier))); + let name_service_contract_address = &self + .name_service_contract_address() + .ok_or_else(|| NyxdError::unavailable_contract_address("name service contract"))?; + + let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier()))); let memo = msg.default_memo(); - self.client - .execute( - self.address(), - self.name_service_contract_address().ok_or( - NyxdError::NoContractAddressAvailable("name service contract".to_string()), - )?, - &msg, - fee, - memo, - funds, - ) - .await + + let signer_address = &self.signer_addresses()?[0]; + self.execute( + signer_address, + name_service_contract_address, + &msg, + fee, + memo, + funds, + ) + .await + } +} + +#[cfg(test)] +mod tests { + use super::*; + + // it's enough that this compiles + #[deprecated] + async fn all_execute_variants_are_covered( + client: C, + msg: NameExecuteMsg, + ) { + unimplemented!() } } diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/sp_directory_signing_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/sp_directory_signing_client.rs index 31cf30839a..115c024d82 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/sp_directory_signing_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/sp_directory_signing_client.rs @@ -1,17 +1,17 @@ // Copyright 2023 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 +use crate::nyxd::contract_traits::NymContractsProvider; +use crate::nyxd::{ + coin::Coin, cosmwasm_client::types::ExecuteResult, error::NyxdError, Fee, SigningCosmWasmClient, +}; +use crate::signing::signer::OfflineSigner; use async_trait::async_trait; use nym_contracts_common::signing::MessageSignature; use nym_service_provider_directory_common::{ msg::ExecuteMsg as SpExecuteMsg, NymAddress, ServiceDetails, ServiceId, }; -use crate::nyxd::{ - coin::Coin, cosmwasm_client::types::ExecuteResult, error::NyxdError, Fee, NyxdClient, - SigningCosmWasmClient, -}; - #[async_trait] pub trait SpDirectorySigningClient { async fn execute_service_provider_directory_contract( @@ -82,9 +82,10 @@ pub trait SpDirectorySigningClient { } #[async_trait] -impl SpDirectorySigningClient for NyxdClient +impl SpDirectorySigningClient for C where - C: SigningCosmWasmClient + Sync + Send, + C: SigningCosmWasmClient + NymContractsProvider + Sync, + NyxdError: From<::Error>, { async fn execute_service_provider_directory_contract( &self, @@ -92,21 +93,37 @@ where msg: SpExecuteMsg, funds: Vec, ) -> Result { - let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier))); + let sp_directory_contract_address = + &self.service_provider_contract_address().ok_or_else(|| { + NyxdError::unavailable_contract_address("service provider directory contract") + })?; + + let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier()))); let memo = msg.default_memo(); - self.client - .execute( - self.address(), - self.service_provider_contract_address().ok_or( - NyxdError::NoContractAddressAvailable( - "service provider directory contract".to_string(), - ), - )?, - &msg, - fee, - memo, - funds, - ) - .await + + let signer_address = &self.signer_addresses()?[0]; + self.execute( + signer_address, + sp_directory_contract_address, + &msg, + fee, + memo, + funds, + ) + .await + } +} + +#[cfg(test)] +mod tests { + use super::*; + + // it's enough that this compiles + #[deprecated] + async fn all_execute_variants_are_covered( + client: C, + msg: SpExecuteMsg, + ) { + unimplemented!() } } diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/vesting_signing_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/vesting_signing_client.rs index f1354566dd..b43876d6fb 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/vesting_signing_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/vesting_signing_client.rs @@ -1,10 +1,11 @@ -// Copyright 2021 - Nym Technologies SA +// Copyright 2021-2023 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -pub use crate::nyxd::cosmwasm_client::signing_client::SigningCosmWasmClient; +use crate::nyxd::contract_traits::NymContractsProvider; use crate::nyxd::cosmwasm_client::types::ExecuteResult; use crate::nyxd::error::NyxdError; -use crate::nyxd::{Coin, Fee, NyxdClient}; +use crate::nyxd::{Coin, Fee, SigningCosmWasmClient}; +use crate::signing::signer::OfflineSigner; use async_trait::async_trait; use cosmrs::AccountId; use nym_contracts_common::signing::MessageSignature; @@ -28,25 +29,47 @@ pub trait VestingSigningClient { &self, new_costs: MixNodeCostParams, fee: Option, - ) -> Result; + ) -> Result { + self.execute_vesting_contract( + fee, + VestingExecuteMsg::UpdateMixnodeCostParams { new_costs }, + vec![], + ) + .await + } async fn vesting_update_mixnode_config( &self, new_config: MixNodeConfigUpdate, fee: Option, - ) -> Result; + ) -> Result { + let req = VestingExecuteMsg::UpdateMixnodeConfig { new_config }; + self.execute_vesting_contract(fee, req, vec![]).await + } async fn vesting_update_gateway_config( &self, new_config: GatewayConfigUpdate, fee: Option, - ) -> Result; + ) -> Result { + self.execute_vesting_contract( + fee, + VestingExecuteMsg::UpdateGatewayConfig { new_config }, + vec![], + ) + .await + } async fn update_mixnet_address( &self, address: &str, fee: Option, - ) -> Result; + ) -> Result { + let req = VestingExecuteMsg::UpdateMixnetAddress { + address: address.to_string(), + }; + self.execute_vesting_contract(fee, req, vec![]).await + } async fn vesting_bond_gateway( &self, @@ -54,16 +77,31 @@ pub trait VestingSigningClient { owner_signature: MessageSignature, pledge: Coin, fee: Option, - ) -> Result; - - async fn vesting_unbond_gateway(&self, fee: Option) -> Result; + ) -> Result { + let req = VestingExecuteMsg::BondGateway { + gateway, + owner_signature, + amount: pledge.into(), + }; + self.execute_vesting_contract(fee, req, vec![]).await + } + async fn vesting_unbond_gateway(&self, fee: Option) -> Result { + let req = VestingExecuteMsg::UnbondGateway {}; + self.execute_vesting_contract(fee, req, vec![]).await + } async fn vesting_track_unbond_gateway( &self, owner: &str, amount: Coin, fee: Option, - ) -> Result; + ) -> Result { + let req = VestingExecuteMsg::TrackUnbondGateway { + owner: owner.to_string(), + amount: amount.into(), + }; + self.execute_vesting_contract(fee, req, vec![]).await + } async fn vesting_bond_mixnode( &self, @@ -72,7 +110,19 @@ pub trait VestingSigningClient { owner_signature: MessageSignature, pledge: Coin, fee: Option, - ) -> Result; + ) -> Result { + self.execute_vesting_contract( + fee, + VestingExecuteMsg::BondMixnode { + mix_node, + cost_params, + owner_signature, + amount: pledge.into(), + }, + vec![], + ) + .await + } async fn vesting_pledge_more( &self, @@ -104,20 +154,34 @@ pub trait VestingSigningClient { .await } - async fn vesting_unbond_mixnode(&self, fee: Option) -> Result; + async fn vesting_unbond_mixnode(&self, fee: Option) -> Result { + let req = VestingExecuteMsg::UnbondMixnode {}; + self.execute_vesting_contract(fee, req, vec![]).await + } async fn vesting_track_unbond_mixnode( &self, owner: &str, amount: Coin, fee: Option, - ) -> Result; + ) -> Result { + let req = VestingExecuteMsg::TrackUnbondMixnode { + owner: owner.to_string(), + amount: amount.into(), + }; + self.execute_vesting_contract(fee, req, vec![]).await + } async fn withdraw_vested_coins( &self, amount: Coin, fee: Option, - ) -> Result; + ) -> Result { + let req = VestingExecuteMsg::WithdrawVestedCoins { + amount: amount.into(), + }; + self.execute_vesting_contract(fee, req, vec![]).await + } async fn vesting_track_undelegation( &self, @@ -125,7 +189,18 @@ pub trait VestingSigningClient { mix_id: MixId, amount: Coin, fee: Option, - ) -> Result; + ) -> Result { + self.execute_vesting_contract( + fee, + VestingExecuteMsg::TrackUndelegation { + owner: address.to_string(), + mix_id, + amount: amount.into(), + }, + vec![], + ) + .await + } async fn vesting_delegate_to_mixnode( &self, @@ -133,14 +208,35 @@ pub trait VestingSigningClient { amount: Coin, on_behalf_of: Option, fee: Option, - ) -> Result; + ) -> Result { + self.execute_vesting_contract( + fee, + VestingExecuteMsg::DelegateToMixnode { + mix_id, + amount: amount.into(), + on_behalf_of, + }, + vec![], + ) + .await + } async fn vesting_undelegate_from_mixnode( &self, mix_id: MixId, on_behalf_of: Option, fee: Option, - ) -> Result; + ) -> Result { + self.execute_vesting_contract( + fee, + VestingExecuteMsg::UndelegateFromMixnode { + mix_id, + on_behalf_of, + }, + vec![], + ) + .await + } async fn create_periodic_vesting_account( &self, @@ -150,7 +246,15 @@ pub trait VestingSigningClient { amount: Coin, cap: Option, fee: Option, - ) -> Result; + ) -> Result { + let req = VestingExecuteMsg::CreateAccount { + owner_address: owner_address.to_string(), + staking_address, + vesting_spec, + cap, + }; + self.execute_vesting_contract(fee, req, vec![amount]).await + } async fn vesting_withdraw_operator_reward( &self, @@ -236,316 +340,47 @@ pub trait VestingSigningClient { } #[async_trait] -impl VestingSigningClient for NyxdClient { +impl VestingSigningClient for C +where + C: SigningCosmWasmClient + NymContractsProvider + Sync, + NyxdError: From<::Error>, +{ async fn execute_vesting_contract( &self, fee: Option, msg: VestingExecuteMsg, funds: Vec, ) -> Result { - let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier))); + let vesting_contract_address = &self + .vesting_contract_address() + .ok_or_else(|| NyxdError::unavailable_contract_address("vesting contract"))?; + + let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier()))); let memo = msg.name().to_string(); - self.client - .execute( - self.address(), - self.vesting_contract_address(), - &msg, - fee, - memo, - funds, - ) - .await - } - async fn vesting_update_mixnode_cost_params( - &self, - new_costs: MixNodeCostParams, - fee: Option, - ) -> Result { - self.execute_vesting_contract( + let signer_address = &self.signer_addresses()?[0]; + self.execute( + signer_address, + vesting_contract_address, + &msg, fee, - VestingExecuteMsg::UpdateMixnodeCostParams { new_costs }, - vec![], + memo, + funds, ) .await } - - async fn vesting_update_mixnode_config( - &self, - new_config: MixNodeConfigUpdate, - fee: Option, - ) -> Result { - let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier))); - let req = VestingExecuteMsg::UpdateMixnodeConfig { new_config }; - self.client - .execute( - self.address(), - self.vesting_contract_address(), - &req, - fee, - "VestingContract::UpdateMixnetConfig", - vec![], - ) - .await - } - - async fn vesting_update_gateway_config( - &self, - new_config: GatewayConfigUpdate, - fee: Option, - ) -> Result { - self.execute_vesting_contract( - fee, - VestingExecuteMsg::UpdateGatewayConfig { new_config }, - vec![], - ) - .await - } - - async fn update_mixnet_address( - &self, - address: &str, - fee: Option, - ) -> Result { - let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier))); - let req = VestingExecuteMsg::UpdateMixnetAddress { - address: address.to_string(), - }; - self.client - .execute( - self.address(), - self.vesting_contract_address(), - &req, - fee, - "VestingContract::UpdateMixnetAddress", - vec![], - ) - .await - } - - async fn vesting_bond_gateway( - &self, - gateway: Gateway, - owner_signature: MessageSignature, - pledge: Coin, - fee: Option, - ) -> Result { - let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier))); - let req = VestingExecuteMsg::BondGateway { - gateway, - owner_signature, - amount: pledge.into(), - }; - self.client - .execute( - self.address(), - self.vesting_contract_address(), - &req, - fee, - "VestingContract::BondGateway", - vec![], - ) - .await - } - - async fn vesting_unbond_gateway(&self, fee: Option) -> Result { - let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier))); - let req = VestingExecuteMsg::UnbondGateway {}; - self.client - .execute( - self.address(), - self.vesting_contract_address(), - &req, - fee, - "VestingContract::UnbondGateway", - vec![], - ) - .await - } - - async fn vesting_track_unbond_gateway( - &self, - owner: &str, - amount: Coin, - fee: Option, - ) -> Result { - let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier))); - let req = VestingExecuteMsg::TrackUnbondGateway { - owner: owner.to_string(), - amount: amount.into(), - }; - self.client - .execute( - self.address(), - self.vesting_contract_address(), - &req, - fee, - "VestingContract::TrackUnbondGateway", - vec![], - ) - .await - } - - async fn vesting_bond_mixnode( - &self, - mix_node: MixNode, - cost_params: MixNodeCostParams, - owner_signature: MessageSignature, - pledge: Coin, - fee: Option, - ) -> Result { - self.execute_vesting_contract( - fee, - VestingExecuteMsg::BondMixnode { - mix_node, - cost_params, - owner_signature, - amount: pledge.into(), - }, - vec![], - ) - .await - } - - async fn vesting_unbond_mixnode(&self, fee: Option) -> Result { - let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier))); - let req = VestingExecuteMsg::UnbondMixnode {}; - self.client - .execute( - self.address(), - self.vesting_contract_address(), - &req, - fee, - "VestingContract::UnbondMixnode", - vec![], - ) - .await - } - - async fn vesting_track_unbond_mixnode( - &self, - owner: &str, - amount: Coin, - fee: Option, - ) -> Result { - let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier))); - let req = VestingExecuteMsg::TrackUnbondMixnode { - owner: owner.to_string(), - amount: amount.into(), - }; - self.client - .execute( - self.address(), - self.vesting_contract_address(), - &req, - fee, - "VestingContract::TrackUnbondMixnode", - vec![], - ) - .await - } - - async fn withdraw_vested_coins( - &self, - amount: Coin, - fee: Option, - ) -> Result { - let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier))); - let req = VestingExecuteMsg::WithdrawVestedCoins { - amount: amount.into(), - }; - self.client - .execute( - self.address(), - self.vesting_contract_address(), - &req, - fee, - "VestingContract::WithdrawVested", - vec![], - ) - .await - } - - async fn vesting_track_undelegation( - &self, - address: &str, - mix_id: MixId, - amount: Coin, - fee: Option, - ) -> Result { - self.execute_vesting_contract( - fee, - VestingExecuteMsg::TrackUndelegation { - owner: address.to_string(), - mix_id, - amount: amount.into(), - }, - vec![], - ) - .await - } - - async fn vesting_delegate_to_mixnode( - &self, - mix_id: MixId, - amount: Coin, - on_behalf_of: Option, - fee: Option, - ) -> Result { - self.execute_vesting_contract( - fee, - VestingExecuteMsg::DelegateToMixnode { - mix_id, - amount: amount.into(), - on_behalf_of, - }, - vec![], - ) - .await - } - - async fn vesting_undelegate_from_mixnode( - &self, - mix_id: MixId, - on_behalf_of: Option, - fee: Option, - ) -> Result { - self.execute_vesting_contract( - fee, - VestingExecuteMsg::UndelegateFromMixnode { - mix_id, - on_behalf_of, - }, - vec![], - ) - .await - } - - async fn create_periodic_vesting_account( - &self, - owner_address: &str, - staking_address: Option, - vesting_spec: Option, - amount: Coin, - cap: Option, - fee: Option, - ) -> Result { - let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier))); - let req = VestingExecuteMsg::CreateAccount { - owner_address: owner_address.to_string(), - staking_address, - vesting_spec, - cap, - }; - self.client - .execute( - self.address(), - self.vesting_contract_address(), - &req, - fee, - "VestingContract::CreatePeriodicVestingAccount", - vec![amount], - ) - .await - } +} + +#[cfg(test)] +mod tests { + use super::*; + + // it's enough that this compiles + #[deprecated] + async fn all_execute_variants_are_covered( + client: C, + msg: VestingExecuteMsg, + ) { + unimplemented!() + } } 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 a73f987936..4f6f3a9772 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 @@ -62,10 +62,7 @@ where // blanket implementation for anything that provides CosmWasmClient + TxSigner? fn gas_price(&self) -> &GasPrice; - fn signer_public_key(&self, signer_address: &AccountId) -> Option { - let account = self.find_account(signer_address).ok()?; - Some(account.public_key().into()) - } + fn simulated_gas_multiplier(&self) -> f32; async fn simulate( &self, 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 e8c78c1884..51dc9f3181 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 @@ -5,7 +5,6 @@ use crate::nyxd::cosmwasm_client::client_traits::{CosmWasmClient, SigningCosmWas use crate::nyxd::error::NyxdError; use crate::nyxd::{Config, GasPrice, TendermintClient}; use async_trait::async_trait; -use cosmrs::AccountId; use tendermint_rpc::{Error as TendermintRpcError, SimpleRequest}; #[cfg(feature = "http-client")] @@ -25,12 +24,14 @@ pub mod types; #[derive(Debug)] pub(crate) struct SigningClientOptions { gas_price: GasPrice, + simulated_gas_multiplier: f32, } impl<'a> From<&'a Config> for SigningClientOptions { fn from(value: &'a Config) -> Self { SigningClientOptions { gas_price: value.gas_price.clone(), + simulated_gas_multiplier: value.simulated_gas_multiplier, } } } @@ -41,7 +42,6 @@ pub(crate) struct MaybeSigningClient { client: C, signer: S, opts: SigningClientOptions, - derived_addresses: Option>, } impl MaybeSigningClient { @@ -50,36 +50,20 @@ impl MaybeSigningClient { client, signer: Default::default(), opts, - derived_addresses: None, } } } impl MaybeSigningClient { - pub(crate) fn new_signing( - client: C, - signer: S, - opts: SigningClientOptions, - ) -> Result + pub(crate) fn new_signing(client: C, signer: S, opts: SigningClientOptions) -> Self where S: OfflineSigner, { - let derived_addresses = signer - .get_accounts()? - .into_iter() - .map(|account| account.address) - .collect(); - Ok(MaybeSigningClient { + MaybeSigningClient { client, signer, opts, - derived_addresses: Some(derived_addresses), - }) - } - - pub(crate) fn derived_addresses(&self) -> &[AccountId] { - // the unwrap is fine here as you can't construct a signing client without setting the addresses - self.derived_addresses.as_ref().unwrap() + } } } @@ -145,6 +129,10 @@ where fn gas_price(&self) -> &GasPrice { &self.opts.gas_price } + + fn simulated_gas_multiplier(&self) -> f32 { + self.opts.simulated_gas_multiplier + } } // diff --git a/common/client-libs/validator-client/src/nyxd/mod.rs b/common/client-libs/validator-client/src/nyxd/mod.rs index df671473ac..09ffa02562 100644 --- a/common/client-libs/validator-client/src/nyxd/mod.rs +++ b/common/client-libs/validator-client/src/nyxd/mod.rs @@ -43,9 +43,6 @@ use std::time::SystemTime; #[cfg(feature = "http-client")] use cosmrs::rpc::{HttpClient, HttpClientUrl}; -#[cfg(feature = "direct-secp256k1-wallet")] -use crate::signing::direct_wallet::DirectSecp256k1HdWallet; - use crate::nyxd::contract_traits::{NymContractsProvider, TypedNymContracts}; use crate::nyxd::cosmwasm_client::MaybeSigningClient; use crate::nyxd::fee::DEFAULT_SIMULATED_GAS_MULTIPLIER; @@ -58,8 +55,10 @@ pub mod error; pub mod fee; // helper types -#[cfg(all(feature = "direct-secp256k1-wallet", feature = "http-client"))] -pub type DirectSigningHttpNyxdClient = NyxdClient; +#[cfg(feature = "http-client")] +pub type DirectSigningHttpNyxdClient = + NyxdClient; + #[cfg(feature = "http-client")] pub type QueryHttpNyxdClient = NyxdClient; @@ -177,7 +176,7 @@ where { let client = HttpClient::new(endpoint)?; Ok(NyxdClient { - client: MaybeSigningClient::new_signing(client, signer, (&config).into())?, + client: MaybeSigningClient::new_signing(client, signer, (&config).into()), config, }) } @@ -348,8 +347,13 @@ where NyxdError: From<::Error>, NyxdError: From<::Error>, { - pub fn address(&self) -> &AccountId { - &self.client.derived_addresses()[0] + pub fn address(&self) -> AccountId { + match self.client.signer_addresses() { + Ok(addresses) => addresses[0].clone(), + Err(_) => { + panic!("key derivation failure") + } + } } pub fn cw_address(&self) -> Addr { @@ -359,7 +363,7 @@ where } pub async fn account_sequence(&self) -> Result { - self.client.get_sequence(self.address()).await + self.client.get_sequence(&self.address()).await } pub fn wrap_contract_execute_message( @@ -372,7 +376,7 @@ where M: ?Sized + Serialize, { Ok(cosmwasm::MsgExecuteContract { - sender: self.address().clone(), + sender: self.address(), contract: contract_address.clone(), msg: serde_json::to_vec(msg)?, funds: funds.into_iter().map(Into::into).collect(), @@ -386,7 +390,7 @@ where { self.client .simulate( - self.address(), + &self.address(), messages .into_iter() .map(|msg| msg.into_any()) @@ -409,7 +413,7 @@ where ) -> Result { let fee = fee.unwrap_or(Fee::Auto(Some(self.config.simulated_gas_multiplier))); self.client - .send_tokens(self.address(), recipient, amount, fee, memo) + .send_tokens(&self.address(), recipient, amount, fee, memo) .await } @@ -422,7 +426,7 @@ where ) -> Result { let fee = fee.unwrap_or(Fee::Auto(Some(self.config.simulated_gas_multiplier))); self.client - .send_tokens_multiple(self.address(), msgs, fee, memo) + .send_tokens_multiple(&self.address(), msgs, fee, memo) .await } @@ -439,7 +443,7 @@ where let fee = fee.unwrap_or(Fee::Auto(Some(self.config.simulated_gas_multiplier))); self.client .grant_allowance( - self.address(), + &self.address(), grantee, spend_limit, expiration, @@ -459,7 +463,7 @@ where ) -> Result { let fee = fee.unwrap_or(Fee::Auto(Some(self.config.simulated_gas_multiplier))); self.client - .revoke_allowance(self.address(), grantee, fee, memo) + .revoke_allowance(&self.address(), grantee, fee, memo) .await } @@ -476,7 +480,7 @@ where { let fee = fee.unwrap_or(Fee::Auto(Some(self.config.simulated_gas_multiplier))); self.client - .execute(self.address(), contract_address, msg, fee, memo, funds) + .execute(&self.address(), contract_address, msg, fee, memo, funds) .await } @@ -493,7 +497,7 @@ where { let fee = fee.unwrap_or(Fee::Auto(Some(self.config.simulated_gas_multiplier))); self.client - .execute_multiple(self.address(), contract_address, msgs, fee, memo) + .execute_multiple(&self.address(), contract_address, msgs, fee, memo) .await } @@ -505,7 +509,7 @@ where ) -> Result { let fee = fee.unwrap_or(Fee::Auto(Some(self.config.simulated_gas_multiplier))); self.client - .upload(self.address(), wasm_code, fee, memo) + .upload(&self.address(), wasm_code, fee, memo) .await } @@ -523,7 +527,7 @@ where { let fee = fee.unwrap_or(Fee::Auto(Some(self.config.simulated_gas_multiplier))); self.client - .instantiate(self.address(), code_id, msg, label, fee, memo, options) + .instantiate(&self.address(), code_id, msg, label, fee, memo, options) .await } @@ -536,7 +540,7 @@ where ) -> Result { let fee = fee.unwrap_or(Fee::Auto(Some(self.config.simulated_gas_multiplier))); self.client - .update_admin(self.address(), contract_address, new_admin, fee, memo) + .update_admin(&self.address(), contract_address, new_admin, fee, memo) .await } @@ -548,7 +552,7 @@ where ) -> Result { let fee = fee.unwrap_or(Fee::Auto(Some(self.config.simulated_gas_multiplier))); self.client - .clear_admin(self.address(), contract_address, fee, memo) + .clear_admin(&self.address(), contract_address, fee, memo) .await } @@ -565,7 +569,7 @@ where { let fee = fee.unwrap_or(Fee::Auto(Some(self.config.simulated_gas_multiplier))); self.client - .migrate(self.address(), contract_address, code_id, fee, msg, memo) + .migrate(&self.address(), contract_address, code_id, fee, msg, memo) .await } } diff --git a/common/client-libs/validator-client/src/signing/signer.rs b/common/client-libs/validator-client/src/signing/signer.rs index d4fd30d58b..4b620291fe 100644 --- a/common/client-libs/validator-client/src/signing/signer.rs +++ b/common/client-libs/validator-client/src/signing/signer.rs @@ -33,6 +33,16 @@ pub enum SignerType { pub trait OfflineSigner { type Error: From; + // I really dislike existence of this function because it makes you re-derive your key **twice** for each contract transaction + fn signer_addresses(&self) -> Result, Self::Error> { + let derived_addresses = self + .get_accounts()? + .into_iter() + .map(|account| account.address) + .collect(); + Ok(derived_addresses) + } + fn get_accounts(&self) -> Result, Self::Error>; fn find_account(&self, signer_address: &AccountId) -> Result { diff --git a/common/client-libs/validator-client/src/signing/tx_signer.rs b/common/client-libs/validator-client/src/signing/tx_signer.rs index 7db9a7617e..b8869ec578 100644 --- a/common/client-libs/validator-client/src/signing/tx_signer.rs +++ b/common/client-libs/validator-client/src/signing/tx_signer.rs @@ -77,6 +77,11 @@ use cosmrs::{tx, AccountId, Any}; // extension trait for the OfflineSigner to allow to sign transactions pub trait TxSigner: OfflineSigner { + fn signer_public_key(&self, signer_address: &AccountId) -> Option { + let account = self.find_account(signer_address).ok()?; + Some(account.public_key().into()) + } + fn sign_amino( &self, _signer_address: &AccountId, From c41e377c69214f1f5add1873a6f845e774903d43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Tue, 1 Aug 2023 16:23:58 +0100 Subject: [PATCH 09/24] wip in making the rest of the codebase compile again --- Cargo.lock | 12 +- common/bandwidth-controller/Cargo.toml | 1 + .../bandwidth-controller/src/acquire/mod.rs | 7 +- common/bandwidth-controller/src/error.rs | 5 +- common/bandwidth-controller/src/lib.rs | 24 +- .../bandwidth-controller/src/wasm_mockups.rs | 17 -- common/client-core/Cargo.toml | 3 - .../client-core/src/client/base_client/mod.rs | 11 +- .../client/base_client/non_wasm_helpers.rs | 17 +- common/client-core/src/client/mix_traffic.rs | 7 +- common/client-core/src/init/helpers.rs | 2 +- common/client-libs/gateway-client/Cargo.toml | 2 +- .../client-libs/gateway-client/src/client.rs | 10 +- .../validator-client/src/coconut/mod.rs | 49 ++-- .../validator-client/src/connection_tester.rs | 16 +- .../client-libs/validator-client/src/lib.rs | 27 ++- .../src/nyxd/contract_traits/mod.rs | 2 +- .../contract_traits/multisig_query_client.rs | 9 + .../src/nyxd/cosmwasm_client/mod.rs | 28 +-- .../validator-client/src/nyxd/mod.rs | 155 ++++++------ .../validator-client/src/signing/tx_signer.rs | 2 + common/credentials/Cargo.toml | 2 +- explorer-api/src/client.rs | 6 +- explorer-api/src/mix_node/delegations.rs | 4 +- explorer-api/src/tasks.rs | 8 +- .../connection_handler/authenticated.rs | 4 + .../websocket/connection_handler/coconut.rs | 34 +-- gateway/src/node/mod.rs | 24 +- .../src/circulating_supply_api/cache/mod.rs | 4 +- nym-api/src/coconut/comm.rs | 6 +- nym-api/src/coconut/error.rs | 4 + nym-api/src/support/nyxd/mod.rs | 221 ++++++------------ nym-connect/desktop/Cargo.lock | 6 +- 33 files changed, 318 insertions(+), 411 deletions(-) delete mode 100644 common/bandwidth-controller/src/wasm_mockups.rs diff --git a/Cargo.lock b/Cargo.lock index 47bd947773..81db4b247a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3965,7 +3965,7 @@ version = "0.1.0" dependencies = [ "async-trait", "log", - "sqlx 0.5.13", + "sqlx 0.5.11", "thiserror", "tokio", ] @@ -4092,7 +4092,7 @@ dependencies = [ "rand 0.7.3", "serde", "serde_json", - "sqlx 0.5.13", + "sqlx 0.5.11", "subtle-encoding", "thiserror", "tokio", @@ -4384,7 +4384,7 @@ dependencies = [ "pretty_env_logger", "rocket", "serde", - "sqlx 0.5.13", + "sqlx 0.5.11", "thiserror", "tokio", ] @@ -4801,7 +4801,7 @@ dependencies = [ "reqwest", "serde", "serde_json", - "sqlx 0.5.13", + "sqlx 0.5.11", "thiserror", "tokio", ] @@ -6846,9 +6846,9 @@ dependencies = [ [[package]] name = "sqlx" -version = "0.5.13" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "551873805652ba0d912fec5bbb0f8b4cdd96baf8e2ebf5970e5671092966019b" +checksum = "fc15591eb44ffb5816a4a70a7efd5dd87bfd3aa84c4c200401c4396140525826" dependencies = [ "sqlx-core 0.5.13", "sqlx-macros 0.5.13", diff --git a/common/bandwidth-controller/Cargo.toml b/common/bandwidth-controller/Cargo.toml index 9c57b20a08..7c372063de 100644 --- a/common/bandwidth-controller/Cargo.toml +++ b/common/bandwidth-controller/Cargo.toml @@ -20,3 +20,4 @@ nym-validator-client = { path = "../client-libs/validator-client", default-featu [target."cfg(not(target_arch = \"wasm32\"))".dependencies.nym-validator-client] path = "../client-libs/validator-client" +features = ["http-client"] diff --git a/common/bandwidth-controller/src/acquire/mod.rs b/common/bandwidth-controller/src/acquire/mod.rs index 04665967ac..c03ae8e90a 100644 --- a/common/bandwidth-controller/src/acquire/mod.rs +++ b/common/bandwidth-controller/src/acquire/mod.rs @@ -8,11 +8,11 @@ use nym_credentials::coconut::bandwidth::{BandwidthVoucher, TOTAL_ATTRIBUTES}; use nym_credentials::coconut::utils::obtain_aggregate_signature; use nym_crypto::asymmetric::{encryption, identity}; use nym_network_defaults::VOUCHER_INFO; +use nym_validator_client::coconut::all_coconut_api_clients; use nym_validator_client::nyxd::contract_traits::CoconutBandwidthSigningClient; use nym_validator_client::nyxd::contract_traits::DkgQueryClient; use nym_validator_client::nyxd::Coin; use nym_validator_client::nyxd::Hash; -use nym_validator_client::CoconutApiClient; use rand::rngs::OsRng; use state::{KeyPair, State}; use std::str::FromStr; @@ -21,7 +21,7 @@ pub mod state; pub async fn deposit(client: &C, amount: Coin) -> Result where - C: CoconutBandwidthSigningClient, + C: CoconutBandwidthSigningClient + Sync, { let mut rng = OsRng; let signing_keypair = KeyPair::from(identity::KeyPair::new(&mut rng)); @@ -70,7 +70,8 @@ where .get_current_epoch_threshold() .await? .ok_or(BandwidthControllerError::NoThreshold)?; - let coconut_api_clients = CoconutApiClient::all_coconut_api_clients(client, epoch_id).await?; + + let coconut_api_clients = all_coconut_api_clients(client, epoch_id).await?; let signature = obtain_aggregate_signature( &state.params, diff --git a/common/bandwidth-controller/src/error.rs b/common/bandwidth-controller/src/error.rs index e9a862ebff..5f464c82e5 100644 --- a/common/bandwidth-controller/src/error.rs +++ b/common/bandwidth-controller/src/error.rs @@ -6,15 +6,18 @@ use nym_credential_storage::error::StorageError; use nym_credentials::error::Error as CredentialsError; use nym_crypto::asymmetric::encryption::KeyRecoveryError; use nym_crypto::asymmetric::identity::Ed25519RecoveryError; +use nym_validator_client::coconut::CoconutApiError; use nym_validator_client::error::ValidatorClientError; use thiserror::Error; #[derive(Debug, Error)] pub enum BandwidthControllerError { - #[cfg(not(target_arch = "wasm32"))] #[error("Nyxd error: {0}")] Nyxd(#[from] nym_validator_client::nyxd::error::NyxdError), + #[error("coconut api query failure: {0}")] + CoconutApiError(#[from] CoconutApiError), + #[error("There was a credential storage error - {0}")] CredentialStorageError(Box), diff --git a/common/bandwidth-controller/src/lib.rs b/common/bandwidth-controller/src/lib.rs index 1c5cf83613..d9a714b263 100644 --- a/common/bandwidth-controller/src/lib.rs +++ b/common/bandwidth-controller/src/lib.rs @@ -2,10 +2,10 @@ // SPDX-License-Identifier: Apache-2.0 use crate::error::BandwidthControllerError; - use nym_credential_storage::error::StorageError; use nym_credential_storage::storage::Storage; - +use nym_validator_client::coconut::all_coconut_api_clients; +use nym_validator_client::nyxd::contract_traits::DkgQueryClient; use std::str::FromStr; use { nym_coconut_interface::Base58, @@ -14,21 +14,9 @@ use { }, }; -#[cfg(not(target_arch = "wasm32"))] -use nym_validator_client::nyxd::contract_traits::DkgQueryClient; - -#[deprecated] -#[cfg(target_arch = "wasm32")] -use crate::wasm_mockups::DkgQueryClient; - -#[cfg(not(target_arch = "wasm32"))] pub mod acquire; pub mod error; -#[deprecated] -#[cfg(target_arch = "wasm32")] -pub mod wasm_mockups; - pub struct BandwidthController { storage: St, client: C, @@ -67,12 +55,8 @@ impl BandwidthController { let epoch_id = u64::from_str(&bandwidth_credential.epoch_id) .map_err(|_| StorageError::InconsistentData)?; - #[cfg(not(target_arch = "wasm32"))] - let coconut_api_clients = - nym_validator_client::CoconutApiClient::all_coconut_api_clients(&self.client, epoch_id) - .await?; - #[cfg(target_arch = "wasm32")] - let coconut_api_clients = vec![]; + let coconut_api_clients = all_coconut_api_clients(&self.client, epoch_id).await?; + let verification_key = obtain_aggregate_verification_key(&coconut_api_clients).await?; // the below would only be executed once we know where we want to spend it (i.e. which gateway and stuff) diff --git a/common/bandwidth-controller/src/wasm_mockups.rs b/common/bandwidth-controller/src/wasm_mockups.rs deleted file mode 100644 index be7ee06a79..0000000000 --- a/common/bandwidth-controller/src/wasm_mockups.rs +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2022-2023 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 - -use std::marker::PhantomData; - -pub struct DirectSigningNyxdClient {} - -pub trait DkgQueryClient {} - -// impl CosmWasmClient for DirectSigningNyxdClient {} - -#[derive(Clone)] -pub struct Client { - _phantom: PhantomData, -} - -impl DkgQueryClient for Client {} diff --git a/common/client-core/Cargo.toml b/common/client-core/Cargo.toml index 3281272c5e..af45a71737 100644 --- a/common/client-core/Cargo.toml +++ b/common/client-core/Cargo.toml @@ -45,9 +45,6 @@ nym-task = { path = "../task" } nym-credential-storage = { path = "../credential-storage" } nym-network-defaults = { path = "../network-defaults" } -[target."cfg(not(target_arch = \"wasm32\"))".dependencies.nym-validator-client] -path = "../client-libs/validator-client" - [target."cfg(not(target_arch = \"wasm32\"))".dependencies.tokio-stream] version = "0.1.11" features = ["time"] diff --git a/common/client-core/src/client/base_client/mod.rs b/common/client-core/src/client/base_client/mod.rs index b5c87e2860..37f57fa601 100644 --- a/common/client-core/src/client/base_client/mod.rs +++ b/common/client-core/src/client/base_client/mod.rs @@ -3,6 +3,7 @@ use super::received_buffer::ReceivedBufferMessage; use super::topology_control::geo_aware_provider::GeoAwareTopologyProvider; +use crate::client::base_client::storage::gateway_details::GatewayDetailsStore; use crate::client::base_client::storage::MixnetClientStorage; use crate::client::cover_traffic_stream::LoopCoverTrafficStream; use crate::client::inbound_messages::{InputMessage, InputMessageReceiver, InputMessageSender}; @@ -24,6 +25,7 @@ use crate::client::topology_control::{ }; use crate::config::{Config, DebugConfig}; use crate::error::ClientCoreError; +use crate::init::{setup_gateway, GatewaySetup, InitialisationDetails}; use crate::{config, spawn_future}; use futures::channel::mpsc; use log::{debug, info}; @@ -42,18 +44,11 @@ use nym_sphinx::receiver::{ReconstructedMessage, SphinxMessageReceiver}; use nym_task::connections::{ConnectionCommandReceiver, ConnectionCommandSender, LaneQueueLengths}; use nym_task::{TaskClient, TaskManager}; use nym_topology::provider_trait::TopologyProvider; +use nym_validator_client::nyxd::contract_traits::DkgQueryClient; use std::sync::Arc; use tap::TapFallible; use url::Url; -#[cfg(target_arch = "wasm32")] -use nym_bandwidth_controller::wasm_mockups::DkgQueryClient; - -use crate::client::base_client::storage::gateway_details::GatewayDetailsStore; -use crate::init::{setup_gateway, GatewaySetup, InitialisationDetails, InitialisationResult}; -#[cfg(not(target_arch = "wasm32"))] -use nym_validator_client::nyxd::contract_traits::DkgQueryClient; - #[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))] pub mod non_wasm_helpers; diff --git a/common/client-core/src/client/base_client/non_wasm_helpers.rs b/common/client-core/src/client/base_client/non_wasm_helpers.rs index 6b901f0f82..e060d3e8fe 100644 --- a/common/client-core/src/client/base_client/non_wasm_helpers.rs +++ b/common/client-core/src/client/base_client/non_wasm_helpers.rs @@ -10,8 +10,8 @@ use crate::error::ClientCoreError; use log::{error, info}; use nym_bandwidth_controller::BandwidthController; use nym_credential_storage::storage::Storage as CredentialStorage; -use nym_validator_client::nyxd::QueryNyxdClient; -use nym_validator_client::Client; +use nym_validator_client::nyxd; +use nym_validator_client::QueryHttpRpcNyxdClient; use std::path::Path; use std::{fs, io}; use time::OffsetDateTime; @@ -104,7 +104,7 @@ pub async fn setup_fs_reply_surb_backend>( pub fn create_bandwidth_controller( config: &Config, storage: St, -) -> BandwidthController, St> { +) -> BandwidthController { let nyxd_url = config .get_validator_endpoints() .pop() @@ -121,13 +121,13 @@ pub fn create_bandwidth_controller_with_urls( nyxd_url: Url, nym_api_url: Url, storage: St, -) -> BandwidthController, St> { +) -> BandwidthController { let client = default_query_dkg_client(nyxd_url, nym_api_url); BandwidthController::new(storage, client) } -pub fn default_query_dkg_client_from_config(config: &Config) -> Client { +pub fn default_query_dkg_client_from_config(config: &Config) -> QueryHttpRpcNyxdClient { let nyxd_url = config .get_validator_endpoints() .pop() @@ -140,12 +140,11 @@ pub fn default_query_dkg_client_from_config(config: &Config) -> Client Client { +pub fn default_query_dkg_client(nyxd_url: Url) -> QueryHttpRpcNyxdClient { let details = nym_network_defaults::NymNetworkDetails::new_from_env(); - let mut client_config = nym_validator_client::Config::try_from_nym_network_details(&details) + let client_config = nyxd::Config::try_from_nym_network_details(&details) .expect("failed to construct validator client config"); // overwrite env configuration with config URLs - client_config = client_config.with_urls(nyxd_url, nym_api_url); - nym_validator_client::Client::new_query(client_config) + QueryHttpRpcNyxdClient::connect(client_config, nyxd_url.as_str()) .expect("Could not construct query client") } diff --git a/common/client-core/src/client/mix_traffic.rs b/common/client-core/src/client/mix_traffic.rs index dedb31bc84..cb12a55d85 100644 --- a/common/client-core/src/client/mix_traffic.rs +++ b/common/client-core/src/client/mix_traffic.rs @@ -3,16 +3,11 @@ use crate::spawn_future; use log::*; +use nym_credential_storage::storage::Storage; use nym_gateway_client::GatewayClient; use nym_sphinx::forwarding::packet::MixPacket; - -use nym_credential_storage::storage::Storage; -#[cfg(not(target_arch = "wasm32"))] use nym_validator_client::nyxd::contract_traits::DkgQueryClient; -#[cfg(target_arch = "wasm32")] -use nym_bandwidth_controller::wasm_mockups::DkgQueryClient; - pub type BatchMixMessageSender = tokio::sync::mpsc::Sender>; pub type BatchMixMessageReceiver = tokio::sync::mpsc::Receiver>; diff --git a/common/client-core/src/init/helpers.rs b/common/client-core/src/init/helpers.rs index 8541bf5ad0..adfd9ad623 100644 --- a/common/client-core/src/init/helpers.rs +++ b/common/client-core/src/init/helpers.rs @@ -3,6 +3,7 @@ use crate::config::GatewayEndpointConfig; use crate::error::ClientCoreError; +use crate::init::RegistrationResult; use futures::{SinkExt, StreamExt}; use log::{debug, info, trace, warn}; use nym_crypto::asymmetric::identity; @@ -27,7 +28,6 @@ type WsConn = WebSocketStream>; #[cfg(not(target_arch = "wasm32"))] use tokio::time::sleep; -use crate::init::RegistrationResult; #[cfg(target_arch = "wasm32")] use wasm_utils::websocket::JSWebsocket; #[cfg(target_arch = "wasm32")] diff --git a/common/client-libs/gateway-client/Cargo.toml b/common/client-libs/gateway-client/Cargo.toml index 197acdadef..ef8d324531 100644 --- a/common/client-libs/gateway-client/Cargo.toml +++ b/common/client-libs/gateway-client/Cargo.toml @@ -25,7 +25,7 @@ nym-gateway-requests = { path = "../../../gateway/gateway-requests" } nym-network-defaults = { path = "../../network-defaults" } nym-sphinx = { path = "../../nymsphinx" } nym-pemstore = { path = "../../pemstore" } -nym-validator-client = { path = "../validator-client" } +nym-validator-client = { path = "../validator-client", default-features = false } nym-task = { path = "../../task" } serde = { workspace = true, features = ["derive"] } diff --git a/common/client-libs/gateway-client/src/client.rs b/common/client-libs/gateway-client/src/client.rs index 0816d26a39..188d84e2c9 100644 --- a/common/client-libs/gateway-client/src/client.rs +++ b/common/client-libs/gateway-client/src/client.rs @@ -1,4 +1,4 @@ -// Copyright 2021 - Nym Technologies SA +// Copyright 2021-2023 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 use crate::error::GatewayClientError; @@ -22,21 +22,18 @@ use nym_gateway_requests::{BinaryRequest, ClientControlRequest, ServerResponse, use nym_network_defaults::{REMAINING_BANDWIDTH_THRESHOLD, TOKENS_TO_BURN}; use nym_sphinx::forwarding::packet::MixPacket; use nym_task::TaskClient; +use nym_validator_client::nyxd::contract_traits::DkgQueryClient; use rand::rngs::OsRng; use std::convert::TryFrom; use std::sync::Arc; use std::time::Duration; use tungstenite::protocol::Message; -#[cfg(not(target_arch = "wasm32"))] -use nym_validator_client::nyxd::contract_traits::DkgQueryClient; #[cfg(not(target_arch = "wasm32"))] use tokio::time::sleep; #[cfg(not(target_arch = "wasm32"))] use tokio_tungstenite::connect_async; -#[cfg(target_arch = "wasm32")] -use nym_bandwidth_controller::wasm_mockups::DkgQueryClient; #[cfg(target_arch = "wasm32")] use wasm_utils::websocket::JSWebsocket; #[cfg(target_arch = "wasm32")] @@ -199,7 +196,6 @@ impl GatewayClient { return Ok(()); } - #[cfg(not(target_arch = "wasm32"))] sleep(self.reconnection_backoff).await; } @@ -782,7 +778,7 @@ impl GatewayClient { let shutdown = TaskClient::dummy(); let packet_router = PacketRouter::new(ack_tx, mix_tx, shutdown.clone()); - GatewayClient:: { + GatewayClient { authenticated: false, disabled_credentials_mode: true, bandwidth_remaining: 0, diff --git a/common/client-libs/validator-client/src/coconut/mod.rs b/common/client-libs/validator-client/src/coconut/mod.rs index 640000189b..97ac95cad7 100644 --- a/common/client-libs/validator-client/src/coconut/mod.rs +++ b/common/client-libs/validator-client/src/coconut/mod.rs @@ -1,8 +1,10 @@ // Copyright 2023 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 +use crate::nyxd::contract_traits::{DkgQueryClient, PagedDkgQueryClient}; +use crate::nyxd::error::NyxdError; use crate::NymApiClient; -use nym_coconut_dkg_common::types::NodeIndex; +use nym_coconut_dkg_common::types::{EpochId, NodeIndex}; use nym_coconut_dkg_common::verification_key::ContractVKShare; use nym_coconut_interface::{Base58, CoconutError, VerificationKey}; use thiserror::Error; @@ -26,6 +28,12 @@ pub enum CoconutApiError { #[error("the provided key share hasn't been verified")] UnverifiedShare, + #[error("failed to query the contract: {source}")] + ContractQueryFailure { + #[from] + source: NyxdError, + }, + #[error("the provided announce address is malformed: {source}")] MalformedAnnounceAddress { #[from] @@ -64,19 +72,26 @@ impl TryFrom for CoconutApiClient { } } -// impl CoconutApiClient { -// // pub async fn all_coconut_api_clients( -// // client: &C, -// // epoch_id: EpochId, -// // ) -> Result, ValidatorClientError> -// // where -// // C: DkgQueryClient + Sync + Send, -// // { -// // Ok(client -// // .get_all_verification_key_shares(epoch_id) -// // .await? -// // .into_iter() -// // .filter_map(Self::try_from) -// // .collect()) -// // } -// } +pub async fn all_coconut_api_clients( + client: &C, + epoch_id: EpochId, +) -> Result, CoconutApiError> +where + C: DkgQueryClient + Sync + Send, +{ + // TODO: this will error out if there's an invalid share out there. is that what we want? + client + .get_all_verification_key_shares(epoch_id) + .await? + .into_iter() + .map(TryInto::try_into) + .collect::, _>>() + + // ... if not, let's switch to the below: + // client + // .get_all_verification_key_shares(epoch_id) + // .await? + // .into_iter() + // .filter_map(TryInto::try_into) + // .collect::, _>>() +} diff --git a/common/client-libs/validator-client/src/connection_tester.rs b/common/client-libs/validator-client/src/connection_tester.rs index 1eb0c50914..15d2efe250 100644 --- a/common/client-libs/validator-client/src/connection_tester.rs +++ b/common/client-libs/validator-client/src/connection_tester.rs @@ -1,9 +1,7 @@ -use crate::nyxd::error::NyxdError; -use crate::nyxd::{Config as ClientConfig, QueryHttpNyxdClient}; -use crate::{NymApiClient, ValidatorClientError}; - -// use crate::nyxd::contract_traits::MixnetQueryClient; use crate::nyxd::contract_traits::MixnetQueryClient; +use crate::nyxd::error::NyxdError; +use crate::nyxd::Config as ClientConfig; +use crate::{NymApiClient, QueryHttpRpcNyxdClient, ValidatorClientError}; use colored::Colorize; use core::fmt; use itertools::Itertools; @@ -54,7 +52,7 @@ pub async fn test_nyxd_url_connection( let config = ClientConfig::try_from_nym_network_details(&network) .expect("failed to create valid nyxd client config"); - let mut nyxd_client = QueryHttpNyxdClient::connect(config, nyxd_url.as_str())?; + let mut nyxd_client = QueryHttpRpcNyxdClient::connect(config, nyxd_url.as_str())?; // possibly redundant, but lets just leave it here nyxd_client.set_mixnet_contract_address(address); match test_nyxd_connection(network, &nyxd_url, &nyxd_client).await { @@ -76,7 +74,7 @@ fn setup_connection_tests( let config = ClientConfig::try_from_nym_network_details(&network) .expect("failed to create valid nyxd client config"); - if let Ok(mut client) = QueryHttpNyxdClient::connect(config, url.as_str()) { + if let Ok(mut client) = QueryHttpRpcNyxdClient::connect(config, url.as_str()) { // possibly redundant, but lets just leave it here client.set_mixnet_contract_address(address); Some(ClientForConnectionTest::Nyxd( @@ -113,7 +111,7 @@ fn extract_and_collect_results_into_map( async fn test_nyxd_connection( network: NymNetworkDetails, url: &Url, - client: &QueryHttpNyxdClient, + client: &QueryHttpRpcNyxdClient, ) -> ConnectionResult { let result = match timeout( Duration::from_secs(CONNECTION_TEST_TIMEOUT_SEC), @@ -187,7 +185,7 @@ async fn test_nym_api_connection( } enum ClientForConnectionTest { - Nyxd(NymNetworkDetails, Url, Box), + Nyxd(NymNetworkDetails, Url, Box), Api(NymNetworkDetails, Url, NymApiClient), } diff --git a/common/client-libs/validator-client/src/lib.rs b/common/client-libs/validator-client/src/lib.rs index a3d5422b99..cd94926f02 100644 --- a/common/client-libs/validator-client/src/lib.rs +++ b/common/client-libs/validator-client/src/lib.rs @@ -2,17 +2,38 @@ // SPDX-License-Identifier: Apache-2.0 pub mod client; +pub mod coconut; #[cfg(feature = "http-client")] pub mod connection_tester; pub mod error; pub mod nym_api; pub mod nyxd; - -pub mod coconut; pub mod signing; pub use crate::error::ValidatorClientError; pub use client::NymApiClient; +pub use client::{Client, CoconutApiClient, Config}; pub use nym_api_requests::*; -pub use client::{Client, CoconutApiClient, Config}; +// some type aliasing + +pub type ValidatorClient = Client; +pub type SigningValidatorClient = Client; + +#[cfg(feature = "http-client")] +pub use cosmrs::rpc::HttpClient as HttpRpcClient; + +#[cfg(feature = "http-client")] +use crate::signing::direct_wallet::DirectSecp256k1HdWallet; + +#[cfg(feature = "http-client")] +pub type QueryHttpRpcValidatorClient = Client; +#[cfg(feature = "http-client")] +pub type QueryHttpRpcNyxdClient = nyxd::NyxdClient; + +#[cfg(feature = "http-client")] +pub type DirectSigningHttpRpcValidatorClient = Client; +#[cfg(feature = "http-client")] +pub type DirectSigningHttpRpcNyxdClient = nyxd::NyxdClient; + +// TODO: the same for reqwest client (once implemented) diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/mod.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/mod.rs index 8d49af5b55..b2e4d44405 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/mod.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/mod.rs @@ -32,7 +32,7 @@ pub use coconut_bandwidth_query_client::CoconutBandwidthQueryClient; pub use dkg_query_client::{DkgQueryClient, PagedDkgQueryClient}; pub use group_query_client::GroupQueryClient; pub use mixnet_query_client::{MixnetQueryClient, PagedMixnetQueryClient}; -pub use multisig_query_client::MultisigQueryClient; +pub use multisig_query_client::{MultisigQueryClient, PagedMultisigQueryClient}; pub use name_service_query_client::NameServiceQueryClient; pub use sp_directory_query_client::SpDirectoryQueryClient; pub use vesting_query_client::VestingQueryClient; diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/multisig_query_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/multisig_query_client.rs index f25a4f9a64..b2aa0154c5 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/multisig_query_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/multisig_query_client.rs @@ -88,7 +88,13 @@ pub trait MultisigQueryClient { async fn query_config(&self) -> Result<(), NyxdError> { unimplemented!() } +} +// extension trait to the query client to deal with the paged queries +// (it didn't feel appropriate to combine it with the existing trait +#[async_trait] +pub trait PagedMultisigQueryClient: MultisigQueryClient { + // can't use the macro due to different paging behaviour async fn get_all_proposals(&self) -> Result, NyxdError> { let mut proposals = Vec::new(); let mut start_after = None; @@ -110,6 +116,9 @@ pub trait MultisigQueryClient { } } +#[async_trait] +impl PagedMultisigQueryClient for T where T: MultisigQueryClient {} + #[async_trait] impl MultisigQueryClient for C where 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 51dc9f3181..55e98a0de3 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 @@ -4,18 +4,16 @@ use crate::nyxd::cosmwasm_client::client_traits::{CosmWasmClient, SigningCosmWasmClient}; use crate::nyxd::error::NyxdError; use crate::nyxd::{Config, GasPrice, TendermintClient}; +use crate::signing::{ + signer::{NoSigner, OfflineSigner}, + AccountData, +}; use async_trait::async_trait; use tendermint_rpc::{Error as TendermintRpcError, SimpleRequest}; #[cfg(feature = "http-client")] use cosmrs::rpc::{HttpClient, HttpClientUrl}; -use crate::signing::{ - signer::{NoSigner, OfflineSigner}, - tx_signer::TxSigner, - AccountData, -}; - pub mod client_traits; mod helpers; pub mod logs; @@ -92,17 +90,8 @@ where } } -#[async_trait] -impl CosmWasmClient for MaybeSigningClient -where - C: CosmWasmClient + Send + Sync, - S: Send + Sync, -{ -} - impl OfflineSigner for MaybeSigningClient where - C: CosmWasmClient, S: OfflineSigner, { type Error = S::Error; @@ -112,17 +101,18 @@ where } } -impl TxSigner for MaybeSigningClient +#[async_trait] +impl CosmWasmClient for MaybeSigningClient where - C: CosmWasmClient, - S: OfflineSigner, + C: TendermintClient + Send + Sync, + S: Send + Sync, { } #[async_trait] impl SigningCosmWasmClient for MaybeSigningClient where - C: CosmWasmClient + Send + Sync, + C: TendermintClient + Send + Sync, S: OfflineSigner + Send + Sync, NyxdError: From, { diff --git a/common/client-libs/validator-client/src/nyxd/mod.rs b/common/client-libs/validator-client/src/nyxd/mod.rs index 09ffa02562..fd3017db89 100644 --- a/common/client-libs/validator-client/src/nyxd/mod.rs +++ b/common/client-libs/validator-client/src/nyxd/mod.rs @@ -1,11 +1,26 @@ // Copyright 2021 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 +use crate::nyxd::contract_traits::{NymContractsProvider, TypedNymContracts}; +use crate::nyxd::cosmwasm_client::types::{ + ChangeAdminResult, ContractCodeId, ExecuteResult, InstantiateOptions, InstantiateResult, + MigrateResult, SequenceResponse, SimulateResponse, UploadResult, +}; +use crate::nyxd::cosmwasm_client::MaybeSigningClient; use crate::nyxd::error::NyxdError; +use crate::nyxd::fee::DEFAULT_SIMULATED_GAS_MULTIPLIER; +use crate::signing::signer::NoSigner; +use crate::signing::signer::OfflineSigner; +use crate::signing::tx_signer::TxSigner; +use crate::signing::AccountData; use async_trait::async_trait; +use cosmrs::cosmwasm; +use cosmrs::tx::Msg; +use cosmwasm_std::Addr; use log::{debug, trace}; use nym_network_defaults::{ChainDetails, NymNetworkDetails}; use serde::Serialize; +use std::time::SystemTime; use tendermint_rpc::endpoint::block::Response as BlockResponse; use tendermint_rpc::Error as TendermintRpcError; @@ -30,38 +45,19 @@ pub use tendermint_rpc::{ Paging, }; -use crate::nyxd::cosmwasm_client::types::{ - ChangeAdminResult, ContractCodeId, ExecuteResult, InstantiateOptions, InstantiateResult, - MigrateResult, SequenceResponse, SimulateResponse, UploadResult, -}; -use crate::signing::signer::OfflineSigner; -use cosmrs::cosmwasm; -use cosmrs::tx::Msg; -use cosmwasm_std::Addr; -use std::time::SystemTime; - +#[cfg(feature = "http-client")] +use crate::signing::direct_wallet::DirectSecp256k1HdWallet; +#[cfg(feature = "http-client")] +use crate::{DirectSigningHttpRpcNyxdClient, QueryHttpRpcNyxdClient}; #[cfg(feature = "http-client")] use cosmrs::rpc::{HttpClient, HttpClientUrl}; -use crate::nyxd::contract_traits::{NymContractsProvider, TypedNymContracts}; -use crate::nyxd::cosmwasm_client::MaybeSigningClient; -use crate::nyxd::fee::DEFAULT_SIMULATED_GAS_MULTIPLIER; -use crate::signing::signer::NoSigner; - pub mod coin; pub mod contract_traits; pub mod cosmwasm_client; pub mod error; pub mod fee; -// helper types -#[cfg(feature = "http-client")] -pub type DirectSigningHttpNyxdClient = - NyxdClient; - -#[cfg(feature = "http-client")] -pub type QueryHttpNyxdClient = NyxdClient; - // TODO: reqwest based for wasm #[derive(Debug, Clone)] @@ -129,7 +125,7 @@ pub struct NyxdClient { #[cfg(feature = "http-client")] impl NyxdClient { - pub fn connect(config: Config, endpoint: U) -> Result + pub fn connect(config: Config, endpoint: U) -> Result where U: TryInto, { @@ -142,14 +138,14 @@ impl NyxdClient { } } -#[cfg(all(feature = "direct-secp256k1-wallet", feature = "http-client"))] +#[cfg(feature = "http-client")] impl NyxdClient { // TODO: rename this one - pub fn connect_with_mnemonic( + pub fn connect_with_mnemonic( config: Config, endpoint: U, mnemonic: bip39::Mnemonic, - ) -> Result + ) -> Result where U: TryInto, { @@ -166,7 +162,7 @@ where // I have no idea why S::Error: Into bound wouldn't do the trick NyxdError: From, { - pub fn connect_with_signer( + pub fn connect_with_signer( config: Config, endpoint: U, signer: S, @@ -272,52 +268,25 @@ impl NymContractsProvider for NyxdClient { // queries impl NyxdClient where - C: CosmWasmClient + Send + Sync, + C: TendermintClient + Send + Sync, S: Send + Sync, { - pub async fn get_account_public_key( - &self, - address: &AccountId, - ) -> Result, NyxdError> - where - C: CosmWasmClient + Sync, - { - if let Some(account) = self.client.get_account(address).await? { - let base_account = account.try_get_base_account()?; - return Ok(base_account.pubkey); - } - - Ok(None) - } - - pub async fn get_current_block_timestamp(&self) -> Result - where - C: CosmWasmClient + Sync, - { + pub async fn get_current_block_timestamp(&self) -> Result { self.get_block_timestamp(None).await } pub async fn get_block_timestamp( &self, height: Option, - ) -> Result - where - C: CosmWasmClient + Sync, - { + ) -> Result { Ok(self.client.get_block(height).await?.block.header.time) } - pub async fn get_block(&self, height: Option) -> Result - where - C: CosmWasmClient + Sync, - { + pub async fn get_block(&self, height: Option) -> Result { self.client.get_block(height).await } - pub async fn get_current_block_height(&self) -> Result - where - C: CosmWasmClient + Sync, - { + pub async fn get_current_block_height(&self) -> Result { self.client.get_height().await } @@ -326,10 +295,7 @@ where /// # Arguments /// /// * `height`: height of the block for which we want to obtain the hash. - pub async fn get_block_hash(&self, height: u32) -> Result - where - C: CosmWasmClient + Sync, - { + pub async fn get_block_hash(&self, height: u32) -> Result { self.client .get_block(Some(height)) .await @@ -340,13 +306,22 @@ where // signing impl NyxdClient where - C: SigningCosmWasmClient + Send + Sync, + C: TendermintClient + Send + Sync, S: OfflineSigner + Send + Sync, - - // TODO: figure out those trait bounds lol NyxdError: From<::Error>, - NyxdError: From<::Error>, { + pub async fn get_account_public_key( + &self, + address: &AccountId, + ) -> Result, NyxdError> { + if let Some(account) = self.client.get_account(address).await? { + let base_account = account.try_get_base_account()?; + return Ok(base_account.pubkey); + } + + Ok(None) + } + pub fn address(&self) -> AccountId { match self.client.signer_addresses() { Ok(addresses) => addresses[0].clone(), @@ -574,10 +549,13 @@ where } } +// ugh. is there a way to avoid that nasty trait implementation? + #[async_trait] -impl TendermintClient for NyxdClient +impl TendermintClient for NyxdClient where C: TendermintClient + Send + Sync, + S: Send + Sync, { async fn perform(&self, request: R) -> Result where @@ -588,11 +566,36 @@ where } #[async_trait] -impl CosmWasmClient for NyxdClient where C: CosmWasmClient + Send + Sync {} +impl CosmWasmClient for NyxdClient +where + C: TendermintClient + Send + Sync, + S: Send + Sync, +{ +} -// #[async_trait] -// impl SigningCosmWasmClient for NyxdClient where C: SigningCosmWasmClient + Send + Sync { -// fn gas_price(&self) -> &GasPrice { -// self.client.gas_price() -// } -// } +impl OfflineSigner for NyxdClient +where + S: OfflineSigner, +{ + type Error = S::Error; + + fn get_accounts(&self) -> Result, Self::Error> { + self.client.get_accounts() + } +} + +#[async_trait] +impl SigningCosmWasmClient for NyxdClient +where + C: TendermintClient + Send + Sync, + S: TxSigner + Send + Sync, + NyxdError: From, +{ + fn gas_price(&self) -> &GasPrice { + self.client.gas_price() + } + + fn simulated_gas_multiplier(&self) -> f32 { + self.client.simulated_gas_multiplier() + } +} diff --git a/common/client-libs/validator-client/src/signing/tx_signer.rs b/common/client-libs/validator-client/src/signing/tx_signer.rs index b8869ec578..f5e2dd91ba 100644 --- a/common/client-libs/validator-client/src/signing/tx_signer.rs +++ b/common/client-libs/validator-client/src/signing/tx_signer.rs @@ -122,3 +122,5 @@ pub trait TxSigner: OfflineSigner { self.sign_direct_with_account(&account_from_signer, sign_doc) } } + +impl TxSigner for T where T: OfflineSigner {} diff --git a/common/credentials/Cargo.toml b/common/credentials/Cargo.toml index 6bb10d5cb6..1f4c444b31 100644 --- a/common/credentials/Cargo.toml +++ b/common/credentials/Cargo.toml @@ -14,7 +14,7 @@ thiserror = "1.0" nym-coconut-interface = { path = "../coconut-interface" } nym-crypto = { path = "../crypto", features = ["rand", "asymmetric", "symmetric", "hashing"] } nym-api-requests = { path = "../../nym-api/nym-api-requests" } -nym-validator-client = { path = "../client-libs/validator-client" } +nym-validator-client = { path = "../client-libs/validator-client", default-features = false } [dev-dependencies] rand = "0.7.3" diff --git a/explorer-api/src/client.rs b/explorer-api/src/client.rs index 9b345e4cf6..1b565fcd60 100644 --- a/explorer-api/src/client.rs +++ b/explorer-api/src/client.rs @@ -2,7 +2,7 @@ use nym_network_defaults::{ var_names::{NYM_API, NYXD}, NymNetworkDetails, }; -use nym_validator_client::nyxd::QueryNyxdClient; +use nym_validator_client::QueryHttpRpcValidatorClient; use reqwest::Url; use std::{str::FromStr, sync::Arc}; @@ -11,9 +11,7 @@ use std::{str::FromStr, sync::Arc}; // when that becomes a requirement, we would simply put an extra RwLock (or Mutex) in here #[derive(Clone)] -pub(crate) struct ThreadsafeValidatorClient( - pub(crate) Arc>, -); +pub(crate) struct ThreadsafeValidatorClient(pub(crate) Arc); impl ThreadsafeValidatorClient { pub(crate) fn new() -> Self { diff --git a/explorer-api/src/mix_node/delegations.rs b/explorer-api/src/mix_node/delegations.rs index d9c151214d..feaefcf5c0 100644 --- a/explorer-api/src/mix_node/delegations.rs +++ b/explorer-api/src/mix_node/delegations.rs @@ -5,6 +5,7 @@ use super::models::SummedDelegations; use crate::client::ThreadsafeValidatorClient; use itertools::Itertools; use nym_mixnet_contract_common::{Delegation, MixId}; +use nym_validator_client::nyxd::contract_traits::PagedMixnetQueryClient; pub(crate) async fn get_single_mixnode_delegations( client: &ThreadsafeValidatorClient, @@ -12,7 +13,8 @@ pub(crate) async fn get_single_mixnode_delegations( ) -> Vec { match client .0 - .get_all_nyxd_single_mixnode_delegations(mix_id) + .nyxd + .get_all_single_mixnode_delegations(mix_id) .await { Ok(result) => result, diff --git a/explorer-api/src/tasks.rs b/explorer-api/src/tasks.rs index 548d1f1a0a..7e4ea329fa 100644 --- a/explorer-api/src/tasks.rs +++ b/explorer-api/src/tasks.rs @@ -7,8 +7,8 @@ use nym_mixnet_contract_common::GatewayBond; use nym_task::TaskClient; use nym_validator_client::models::MixNodeBondAnnotated; use nym_validator_client::nyxd::error::NyxdError; -use nym_validator_client::nyxd::{Paging, QueryNyxdClient, ValidatorResponse}; -use nym_validator_client::ValidatorClientError; +use nym_validator_client::nyxd::{Paging, TendermintClient, ValidatorResponse}; +use nym_validator_client::{QueryHttpRpcValidatorClient, ValidatorClientError}; use crate::mix_nodes::CACHE_REFRESH_RATE; use crate::state::ExplorerApiStateContext; @@ -26,7 +26,7 @@ impl ExplorerApiTasks { // a helper to remove duplicate code when grabbing active/rewarded/all mixnodes async fn retrieve_mixnodes<'a, F, Fut>(&'a self, f: F) -> Vec where - F: FnOnce(&'a nym_validator_client::Client) -> Fut, + F: FnOnce(&'a QueryHttpRpcValidatorClient) -> Fut, Fut: Future, ValidatorClientError>>, { let bonds = match f(&self.state.inner.validator_client.0).await { @@ -75,7 +75,7 @@ impl ExplorerApiTasks { .validator_client .0 .nyxd - .get_validators(height.value(), Paging::All) + .validators(height, Paging::All) .await?; info!("Fetched {} validators", response.validators.len()); Ok(response) diff --git a/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs b/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs index 1a41937c4b..0fe930a96d 100644 --- a/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs +++ b/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs @@ -22,6 +22,7 @@ use crate::node::client_handling::bandwidth::Bandwidth; use crate::node::client_handling::FREE_TESTNET_BANDWIDTH_VALUE; use nym_gateway_requests::iv::IV; use nym_task::TaskClient; +use nym_validator_client::coconut::CoconutApiError; #[derive(Debug, Error)] pub(crate) enum RequestHandlingError { @@ -64,6 +65,9 @@ pub(crate) enum RequestHandlingError { #[error("Coconut interface error - {0}")] CoconutInterfaceError(#[from] nym_coconut_interface::error::CoconutInterfaceError), + #[error("coconut api query failure: {0}")] + CoconutApiError(#[from] CoconutApiError), + #[error("Credential error - {0}")] CredentialError(#[from] nym_credentials::error::Error), } diff --git a/gateway/src/node/client_handling/websocket/connection_handler/coconut.rs b/gateway/src/node/client_handling/websocket/connection_handler/coconut.rs index da9e7fd217..356a884161 100644 --- a/gateway/src/node/client_handling/websocket/connection_handler/coconut.rs +++ b/gateway/src/node/client_handling/websocket/connection_handler/coconut.rs @@ -4,6 +4,7 @@ use super::authenticated::RequestHandlingError; use log::*; use nym_coconut_interface::Credential; +use nym_validator_client::coconut::all_coconut_api_clients; use nym_validator_client::{ nyxd::{ contract_traits::{ @@ -11,9 +12,9 @@ use nym_validator_client::{ MultisigSigningClient, }, cosmwasm_client::logs::{find_attribute, BANDWIDTH_PROPOSAL_ID}, - Coin, DirectSigningNyxdClient, Fee, + Coin, Fee, }, - Client, CoconutApiClient, + CoconutApiClient, DirectSigningHttpRpcNyxdClient, }; use std::time::{Duration, SystemTime}; @@ -21,18 +22,13 @@ const ONE_HOUR_SEC: u64 = 3600; const MAX_FEEGRANT_UNYM: u128 = 10000; pub(crate) struct CoconutVerifier { - nyxd_client: Client, + nyxd_client: DirectSigningHttpRpcNyxdClient, mix_denom_base: String, } impl CoconutVerifier { - pub fn new(nyxd_client: Client) -> Self { - let mix_denom_base = nyxd_client - .nyxd - .current_chain_details() - .mix_denom - .base - .clone(); + pub fn new(nyxd_client: DirectSigningHttpRpcNyxdClient) -> Self { + let mix_denom_base = nyxd_client.current_chain_details().mix_denom.base.clone(); CoconutVerifier { nyxd_client, @@ -43,7 +39,7 @@ impl CoconutVerifier { pub async fn all_current_coconut_api_clients( &self, ) -> Result, RequestHandlingError> { - let epoch_id = self.nyxd_client.nyxd.get_current_epoch().await?.epoch_id; + let epoch_id = self.nyxd_client.get_current_epoch().await?.epoch_id; self.all_coconut_api_clients(epoch_id).await } @@ -51,7 +47,7 @@ impl CoconutVerifier { &self, epoch_id: u64, ) -> Result, RequestHandlingError> { - Ok(CoconutApiClient::all_coconut_api_clients(&self.nyxd_client, epoch_id).await?) + Ok(all_coconut_api_clients(&self.nyxd_client, epoch_id).await?) } pub async fn release_funds( @@ -65,14 +61,13 @@ impl CoconutVerifier { let res = self .nyxd_client - .nyxd .spend_credential( Coin::new( credential.voucher_value().into(), self.mix_denom_base.clone(), ), credential.blinded_serial_number(), - self.nyxd_client.nyxd.address().to_string(), + self.nyxd_client.address().to_string(), None, ) .await?; @@ -86,7 +81,7 @@ impl CoconutVerifier { reason: String::from("proposal id could not be parsed to u64"), })?; - let proposal = self.nyxd_client.nyxd.get_proposal(proposal_id).await?; + let proposal = self.nyxd_client.query_proposal(proposal_id).await?; if !credential.has_blinded_serial_number(&proposal.description)? { return Err(RequestHandlingError::ProposalIdError { reason: String::from("proposal has different serial number"), @@ -96,11 +91,10 @@ impl CoconutVerifier { let req = nym_api_requests::coconut::VerifyCredentialBody::new( credential.clone(), proposal_id, - self.nyxd_client.nyxd.address().clone(), + self.nyxd_client.address().clone(), ); for client in api_clients { self.nyxd_client - .nyxd .grant_allowance( &client.cosmos_address, vec![Coin::new(MAX_FEEGRANT_UNYM, self.mix_denom_base.clone())], @@ -113,7 +107,6 @@ impl CoconutVerifier { .await?; let ret = client.api_client.verify_bandwidth_credential(&req).await; self.nyxd_client - .nyxd .revoke_allowance( &client.cosmos_address, "Cleanup the previous allowance for releasing funds".to_string(), @@ -132,10 +125,7 @@ impl CoconutVerifier { } } - self.nyxd_client - .nyxd - .execute_proposal(proposal_id, None) - .await?; + self.nyxd_client.execute_proposal(proposal_id, None).await?; Ok(()) } diff --git a/gateway/src/node/mod.rs b/gateway/src/node/mod.rs index 8487e6c99f..93bce3a6fd 100644 --- a/gateway/src/node/mod.rs +++ b/gateway/src/node/mod.rs @@ -17,7 +17,7 @@ use nym_mixnet_client::forwarder::{MixForwardingSender, PacketForwarder}; use nym_network_defaults::NymNetworkDetails; use nym_statistics_common::collector::StatisticsSender; use nym_task::{TaskClient, TaskManager}; -use nym_validator_client::Client; +use nym_validator_client::{nyxd, DirectSigningHttpRpcNyxdClient}; use rand::seq::SliceRandom; use rand::thread_rng; use std::error::Error; @@ -212,26 +212,22 @@ impl Gateway { nym_validator_client::NymApiClient::new(nym_api.clone()) } - fn random_nyxd_client( - &self, - ) -> nym_validator_client::Client { + fn random_nyxd_client(&self) -> DirectSigningHttpRpcNyxdClient { let endpoints = self.config.get_nyxd_urls(); let validator_nyxd = endpoints .choose(&mut thread_rng()) .expect("The list of validators is empty"); let network_details = NymNetworkDetails::new_from_env(); - let client_config = nym_validator_client::Config::try_from_nym_network_details( - &network_details, - ) - .expect("failed to construct valid validator client config with the provided network"); + let client_config = nyxd::Config::try_from_nym_network_details(&network_details) + .expect("failed to construct valid validator client config with the provided network"); - let mut client = Client::new_signing(client_config, self.config.get_cosmos_mnemonic()) - .expect("Could not connect with mnemonic"); - client - .change_nyxd(validator_nyxd.clone()) - .expect("Could not use the random nyxd URL"); - client + DirectSigningHttpRpcNyxdClient::connect_with_mnemonic( + client_config, + validator_nyxd.as_ref(), + self.config.get_cosmos_mnemonic(), + ) + .expect("Could not connect with mnemonic") } async fn check_if_bonded(&self) -> Result { diff --git a/nym-api/src/circulating_supply_api/cache/mod.rs b/nym-api/src/circulating_supply_api/cache/mod.rs index 003d25feb4..70794bc72e 100644 --- a/nym-api/src/circulating_supply_api/cache/mod.rs +++ b/nym-api/src/circulating_supply_api/cache/mod.rs @@ -4,8 +4,8 @@ use self::data::CirculatingSupplyCacheData; use cosmwasm_std::Addr; use nym_api_requests::models::CirculatingSupplyResponse; +use nym_validator_client::nyxd::error::NyxdError; use nym_validator_client::nyxd::Coin; -use nym_validator_client::ValidatorClientError; use rocket::fairing::AdHoc; use std::ops::Deref; use std::{ @@ -34,7 +34,7 @@ enum CirculatingSupplyCacheError { #[error(transparent)] ClientError { #[from] - source: ValidatorClientError, + source: NyxdError, }, } diff --git a/nym-api/src/coconut/comm.rs b/nym-api/src/coconut/comm.rs index 04e53c2c02..cf671defa1 100644 --- a/nym-api/src/coconut/comm.rs +++ b/nym-api/src/coconut/comm.rs @@ -6,7 +6,8 @@ use crate::nyxd; use nym_coconut_dkg_common::types::EpochId; use nym_coconut_interface::VerificationKey; use nym_credentials::coconut::utils::obtain_aggregate_verification_key; -use nym_validator_client::CoconutApiClient; +use nym_validator_client::coconut::all_coconut_api_clients; +use std::ops::Deref; #[async_trait] pub trait APICommunicationChannel { @@ -27,8 +28,7 @@ impl QueryCommunicationChannel { impl APICommunicationChannel for QueryCommunicationChannel { async fn aggregated_verification_key(&self, epoch_id: EpochId) -> Result { let client = self.nyxd_client.0.read().await; - let coconut_api_clients = - CoconutApiClient::all_coconut_api_clients(&client.nyxd, epoch_id).await?; + let coconut_api_clients = all_coconut_api_clients(client.deref(), epoch_id).await?; let vk = obtain_aggregate_verification_key(&coconut_api_clients).await?; Ok(vk) } diff --git a/nym-api/src/coconut/error.rs b/nym-api/src/coconut/error.rs index c540bc62d1..e038e74723 100644 --- a/nym-api/src/coconut/error.rs +++ b/nym-api/src/coconut/error.rs @@ -12,6 +12,7 @@ use nym_crypto::asymmetric::{ identity::{Ed25519RecoveryError, SignatureError}, }; use nym_dkg::error::DkgError; +use nym_validator_client::coconut::CoconutApiError; use nym_validator_client::nyxd::error::NyxdError; use crate::node_status_api::models::NymApiStorageError; @@ -23,6 +24,9 @@ pub enum CoconutError { #[error(transparent)] IOError(#[from] std::io::Error), + #[error("coconut api query failure: {0}")] + CoconutApiError(#[from] CoconutApiError), + #[error(transparent)] SerdeJsonError(#[from] serde_json::Error), diff --git a/nym-api/src/support/nyxd/mod.rs b/nym-api/src/support/nyxd/mod.rs index b3aa95b209..5e252a1b95 100644 --- a/nym-api/src/support/nyxd/mod.rs +++ b/nym-api/src/support/nyxd/mod.rs @@ -9,16 +9,15 @@ use async_trait::async_trait; use cw3::ProposalResponse; use cw4::MemberResponse; use nym_coconut_bandwidth_contract_common::spend_credential::SpendCredentialResponse; -use nym_coconut_dkg_common::msg::QueryMsg as DkgQueryMsg; use nym_coconut_dkg_common::types::InitialReplacementData; use nym_coconut_dkg_common::{ dealer::{ContractDealing, DealerDetails, DealerDetailsResponse}, types::{EncodedBTEPublicKeyWithProof, Epoch, EpochId}, verification_key::{ContractVKShare, VerificationKeyShare}, }; -use nym_config::defaults::{ChainDetails, NymNetworkDetails, DEFAULT_NYM_API_PORT}; +use nym_config::defaults::{ChainDetails, NymNetworkDetails}; use nym_contracts_common::dealings::ContractSafeBytes; -use nym_mixnet_contract_common::families::{Family, FamilyHead}; +use nym_mixnet_contract_common::families::FamilyHead; use nym_mixnet_contract_common::mixnode::MixNodeDetails; use nym_mixnet_contract_common::reward_params::RewardingParams; use nym_mixnet_contract_common::{ @@ -27,29 +26,29 @@ use nym_mixnet_contract_common::{ }; use nym_name_service_common::msg::QueryMsg as NameServiceQueryMsg; use nym_service_provider_directory_common::msg::QueryMsg as SpQueryMsg; +use nym_validator_client::nyxd::contract_traits::{NameServiceQueryClient, PagedDkgQueryClient}; use nym_validator_client::nyxd::error::NyxdError; use nym_validator_client::nyxd::{ contract_traits::{ CoconutBandwidthQueryClient, DkgQueryClient, DkgSigningClient, GroupQueryClient, MixnetQueryClient, MixnetSigningClient, MultisigQueryClient, MultisigSigningClient, - NameServiceQueryClient, SpDirectoryQueryClient, VestingQueryClient, + NymContractsProvider, PagedMixnetQueryClient, PagedMultisigQueryClient, + SpDirectoryQueryClient, VestingQueryClient, }, cosmwasm_client::types::ExecuteResult, - Fee, + CosmWasmClient, Fee, }; use nym_validator_client::nyxd::{ hash::{Hash, SHA256_HASH_SIZE}, - AccountId, Coin, DirectSigningNyxdClient, TendermintTime, + AccountId, Coin, TendermintTime, }; -use nym_validator_client::ValidatorClientError; +use nym_validator_client::{nyxd, DirectSigningHttpRpcNyxdClient}; use nym_vesting_contract_common::AccountVestingCoins; use serde::Deserialize; use std::sync::Arc; use tokio::sync::RwLock; -pub(crate) struct Client( - pub(crate) Arc>>, -); +pub(crate) struct Client(pub(crate) Arc>); impl Clone for Client { fn clone(&self) -> Self { @@ -59,45 +58,40 @@ impl Clone for Client { impl Client { pub(crate) fn new(config: &Config) -> Self { - // the api address is irrelevant here as **WE ARE THE API** - // and we won't be talking on the socket here. - let api_url = format!("http://localhost:{}", DEFAULT_NYM_API_PORT) - .parse() - .unwrap(); let nyxd_url = config.get_nyxd_url(); let details = NymNetworkDetails::new_from_env() .with_mixnet_contract(Some(config.get_mixnet_contract_address().as_ref())) .with_vesting_contract(Some(config.get_vesting_contract_address().as_ref())); - let client_config = nym_validator_client::Config::try_from_nym_network_details(&details) - .expect("failed to construct valid validator client config with the provided network") - .with_urls(nyxd_url, api_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.get_mnemonic(); - let inner = nym_validator_client::Client::new_signing(client_config, mnemonic) - .expect("Failed to connect to nyxd!"); + let inner = DirectSigningHttpRpcNyxdClient::connect_with_mnemonic( + client_config, + nyxd_url.as_str(), + mnemonic, + ) + .expect("Failed to connect to nyxd!"); Client(Arc::new(RwLock::new(inner))) } pub(crate) async fn client_address(&self) -> AccountId { - self.0.read().await.nyxd.address().clone() + self.0.read().await.address() } pub(crate) async fn chain_details(&self) -> ChainDetails { - self.0.read().await.nyxd.current_chain_details().clone() + self.0.read().await.current_chain_details().clone() } - pub(crate) async fn get_rewarding_validator_address( - &self, - ) -> Result { + pub(crate) async fn get_rewarding_validator_address(&self) -> Result { let cosmwasm_addr = self .0 .read() .await - .nyxd .get_mixnet_contract_state() .await? .rewarding_validator_address @@ -116,16 +110,8 @@ impl Client { // a helper function for the future to obtain the current block timestamp #[allow(dead_code)] - pub(crate) async fn current_block_timestamp( - &self, - ) -> Result { - let time = self - .0 - .read() - .await - .nyxd - .get_current_block_timestamp() - .await?; + pub(crate) async fn current_block_timestamp(&self) -> Result { + let time = self.0.read().await.get_current_block_timestamp().await?; Ok(time) } @@ -140,8 +126,8 @@ impl Client { pub(crate) async fn get_block_hash( &self, height: u32, - ) -> Result, ValidatorClientError> { - let hash = match self.0.read().await.nyxd.get_block_hash(height).await? { + ) -> Result, NyxdError> { + let hash = match self.0.read().await.get_block_hash(height).await? { Hash::Sha256(hash) => Some(hash), Hash::None => None, }; @@ -149,50 +135,43 @@ impl Client { Ok(hash) } - pub(crate) async fn get_mixnodes(&self) -> Result, ValidatorClientError> { - self.0.read().await.get_all_nyxd_mixnodes_detailed().await + pub(crate) async fn get_mixnodes(&self) -> Result, NyxdError> { + self.0.read().await.get_all_mixnodes_detailed().await } - pub(crate) async fn get_gateways(&self) -> Result, ValidatorClientError> { - self.0.read().await.get_all_nyxd_gateways().await + pub(crate) async fn get_gateways(&self) -> Result, NyxdError> { + self.0.read().await.get_all_gateways().await } - pub(crate) async fn get_current_interval( - &self, - ) -> Result { + pub(crate) async fn get_current_interval(&self) -> Result { Ok(self.0.read().await.get_current_interval_details().await?) } - pub(crate) async fn get_current_epoch_status( - &self, - ) -> Result { - Ok(self.0.read().await.nyxd.get_current_epoch_status().await?) + pub(crate) async fn get_current_epoch_status(&self) -> Result { + Ok(self.0.read().await.get_current_epoch_status().await?) } pub(crate) async fn get_current_rewarding_parameters( &self, - ) -> Result { + ) -> Result { Ok(self.0.read().await.get_rewarding_parameters().await?) } pub(crate) async fn get_rewarded_set_mixnodes( &self, - ) -> Result, ValidatorClientError> { - self.0 - .read() - .await - .get_all_nyxd_rewarded_set_mixnodes() - .await + ) -> Result, NyxdError> { + self.0.read().await.get_all_rewarded_set_mixnodes().await } - pub(crate) async fn get_current_vesting_account_storage_key( - &self, - ) -> Result { + pub(crate) async fn get_current_vesting_account_storage_key(&self) -> Result { let guard = self.0.read().await; - let vesting_contract = guard.nyxd.vesting_contract_address(); + + // the expect is fine as we always construct the client with the vesting contract explicitly set + let vesting_contract = guard + .vesting_contract_address() + .expect("vesting contract address is not available"); // TODO: I don't like the usage of the hardcoded value here let res = guard - .nyxd .query_contract_raw(vesting_contract, b"key".to_vec()) .await?; if res.is_empty() { @@ -204,46 +183,30 @@ impl Client { pub(crate) async fn get_all_vesting_coins( &self, - ) -> Result, ValidatorClientError> { - Ok(self - .0 - .read() - .await - .nyxd - .get_all_accounts_vesting_coins() - .await?) - } - - #[allow(dead_code)] - pub(crate) async fn get_all_node_families(&self) -> Result, ValidatorClientError> { - self.0.read().await.get_all_node_families().await + ) -> Result, NyxdError> { + Ok(self.0.read().await.get_all_accounts_vesting_coins().await?) } pub(crate) async fn get_all_family_members( &self, - ) -> Result, ValidatorClientError> { + ) -> Result, NyxdError> { self.0.read().await.get_all_family_members().await } - pub(crate) async fn get_pending_events_count(&self) -> Result { + pub(crate) async fn get_pending_events_count(&self) -> Result { let pending = self.0.read().await.get_number_of_pending_events().await?; Ok(pending.epoch_events + pending.interval_events) } - pub(crate) async fn begin_epoch_transition(&self) -> Result<(), ValidatorClientError> { - self.0 - .write() - .await - .nyxd - .begin_epoch_transition(None) - .await?; + pub(crate) async fn begin_epoch_transition(&self) -> Result<(), NyxdError> { + self.0.write().await.begin_epoch_transition(None).await?; Ok(()) } pub(crate) async fn send_rewarding_messages( &self, nodes: &[MixnodeWithPerformance], - ) -> Result<(), ValidatorClientError> { + ) -> Result<(), NyxdError> { // for some reason, compiler complains if this is explicitly inline in code ¯\_(ツ)_/¯ #[inline] #[allow(unused_variables)] @@ -263,16 +226,21 @@ impl Client { } } - let contract = self.0.read().await.get_mixnet_contract_address(); + // "technically" we don't need a write access to the client, + // but we REALLY don't want to accidentally send any transactions while we're sending rewarding messages + // as that would have messed up sequence numbers + let guard = self.0.write().await; + + // the expect is fine as we always construct the client with the mixnet contract explicitly set + let mixnet_contract = guard + .mixnet_contract_address() + .expect("mixnet contract address is not available"); let msgs = generate_reward_messages(nodes); - self.0 - .write() - .await - .nyxd + guard .execute_multiple( - &contract, + &mixnet_contract, msgs, Default::default(), format!("rewarding {} mixnodes", nodes.len()), @@ -285,24 +253,19 @@ impl Client { &self, new_rewarded_set: Vec, expected_active_set_size: u32, - ) -> Result<(), ValidatorClientError> { + ) -> Result<(), NyxdError> { self.0 .write() .await - .nyxd .advance_current_epoch(new_rewarded_set, expected_active_set_size, None) .await?; Ok(()) } - pub(crate) async fn reconcile_epoch_events( - &self, - limit: Option, - ) -> Result<(), ValidatorClientError> { + pub(crate) async fn reconcile_epoch_events(&self, limit: Option) -> Result<(), NyxdError> { self.0 .write() .await - .nyxd .reconcile_epoch_events(limit, None) .await?; Ok(()) @@ -315,25 +278,22 @@ impl crate::coconut::client::Client for Client { self.client_address().await } - async fn get_tx( - &self, - tx_hash: &str, - ) -> crate::coconut::error::Result { + async fn get_tx(&self, tx_hash: &str) -> crate::coconut::error::Result { let tx_hash: Hash = tx_hash .parse() .map_err(|_| CoconutError::TxHashParseError)?; - Ok(self.0.read().await.nyxd.get_tx(tx_hash).await?) + Ok(self.0.read().await.get_tx(tx_hash).await?) } async fn get_proposal( &self, proposal_id: u64, ) -> crate::coconut::error::Result { - Ok(self.0.read().await.nyxd.get_proposal(proposal_id).await?) + Ok(self.0.read().await.query_proposal(proposal_id).await?) } async fn list_proposals(&self) -> crate::coconut::error::Result> { - Ok(self.0.read().await.nyxd.get_all_proposals().await?) + Ok(self.0.read().await.get_all_proposals().await?) } async fn get_spent_credential( @@ -344,48 +304,35 @@ impl crate::coconut::client::Client for Client { .0 .read() .await - .nyxd .get_spent_credential(blinded_serial_number) .await?) } async fn get_current_epoch(&self) -> crate::coconut::error::Result { - Ok(self.0.read().await.nyxd.get_current_epoch().await?) + Ok(self.0.read().await.get_current_epoch().await?) } async fn group_member(&self, addr: String) -> crate::coconut::error::Result { - Ok(self.0.read().await.nyxd.member(addr).await?) + Ok(self.0.read().await.member(addr, None).await?) } async fn get_current_epoch_threshold( &self, ) -> crate::coconut::error::Result> { - Ok(self - .0 - .read() - .await - .nyxd - .get_current_epoch_threshold() - .await?) + Ok(self.0.read().await.get_current_epoch_threshold().await?) } async fn get_initial_dealers( &self, ) -> crate::coconut::error::Result> { - Ok(self.0.read().await.nyxd.get_initial_dealers().await?) + Ok(self.0.read().await.get_initial_dealers().await?) } async fn get_self_registered_dealer_details( &self, ) -> crate::coconut::error::Result { let self_address = &self.address().await; - Ok(self - .0 - .read() - .await - .nyxd - .get_dealer_details(self_address) - .await?) + Ok(self.0.read().await.get_dealer_details(self_address).await?) } async fn get_current_dealers(&self) -> crate::coconut::error::Result> { @@ -420,7 +367,6 @@ impl crate::coconut::client::Client for Client { self.0 .read() .await - .nyxd .vote_proposal(proposal_id, vote_yes, fee) .await?; Ok(()) @@ -430,19 +376,13 @@ impl crate::coconut::client::Client for Client { self.0 .read() .await - .nyxd .execute_proposal(proposal_id, None) .await?; Ok(()) } async fn advance_epoch_state(&self) -> crate::coconut::error::Result<()> { - self.0 - .write() - .await - .nyxd - .advance_dkg_epoch_state(None) - .await?; + self.0.write().await.advance_dkg_epoch_state(None).await?; Ok(()) } @@ -456,7 +396,6 @@ impl crate::coconut::client::Client for Client { .0 .write() .await - .nyxd .register_dealer(bte_key, announce_address, resharing, None) .await?) } @@ -470,7 +409,6 @@ impl crate::coconut::client::Client for Client { .0 .write() .await - .nyxd .submit_dealing_bytes(dealing_bytes, resharing, None) .await?) } @@ -484,22 +422,11 @@ impl crate::coconut::client::Client for Client { .0 .write() .await - .nyxd .submit_verification_key_share(share, resharing, None) .await?) } } -#[async_trait] -impl DkgQueryClient for Client { - async fn query_dkg_contract(&self, query: DkgQueryMsg) -> std::result::Result - where - for<'a> T: Deserialize<'a>, - { - self.0.read().await.nyxd.query_dkg_contract(query).await - } -} - #[async_trait] impl SpDirectoryQueryClient for Client { async fn query_service_provider_contract( @@ -512,7 +439,6 @@ impl SpDirectoryQueryClient for Client { self.0 .read() .await - .nyxd .query_service_provider_contract(query) .await } @@ -527,11 +453,6 @@ impl NameServiceQueryClient for Client { where for<'a> T: Deserialize<'a>, { - self.0 - .read() - .await - .nyxd - .query_name_service_contract(query) - .await + self.0.read().await.query_name_service_contract(query).await } } diff --git a/nym-connect/desktop/Cargo.lock b/nym-connect/desktop/Cargo.lock index d30e02be2f..5be85f5cda 100644 --- a/nym-connect/desktop/Cargo.lock +++ b/nym-connect/desktop/Cargo.lock @@ -4056,7 +4056,7 @@ version = "0.1.0" dependencies = [ "async-trait", "log", - "sqlx 0.5.13", + "sqlx 0.5.11", "thiserror", "tokio", ] @@ -6487,9 +6487,9 @@ dependencies = [ [[package]] name = "sqlx" -version = "0.5.13" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "551873805652ba0d912fec5bbb0f8b4cdd96baf8e2ebf5970e5671092966019b" +checksum = "fc15591eb44ffb5816a4a70a7efd5dd87bfd3aa84c4c200401c4396140525826" dependencies = [ "sqlx-core 0.5.13", "sqlx-macros 0.5.13", From 8ef956084362a7aa9102dfececbdda7fed4cb611 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Tue, 1 Aug 2023 16:58:58 +0100 Subject: [PATCH 10/24] all binaries compiling --- clients/native/src/client/mod.rs | 5 ++--- .../client/base_client/non_wasm_helpers.rs | 15 +++------------ nym-api/src/support/nyxd/mod.rs | 11 +++++++++++ sdk/rust/nym-sdk/src/bandwidth/client.rs | 19 ++++++++++++------- sdk/rust/nym-sdk/src/error.rs | 3 ++- sdk/rust/nym-sdk/src/mixnet/client.rs | 13 +++++++------ 6 files changed, 37 insertions(+), 29 deletions(-) diff --git a/clients/native/src/client/mod.rs b/clients/native/src/client/mod.rs index 8457268d79..6f3982038f 100644 --- a/clients/native/src/client/mod.rs +++ b/clients/native/src/client/mod.rs @@ -19,8 +19,7 @@ use nym_sphinx::anonymous_replies::requests::AnonymousSenderTag; use nym_sphinx::params::PacketType; use nym_task::connections::TransmissionLane; use nym_task::TaskManager; -use nym_validator_client::nyxd::QueryNyxdClient; -use nym_validator_client::Client; +use nym_validator_client::QueryHttpRpcNyxdClient; use std::error::Error; use tokio::sync::watch::error::SendError; @@ -29,7 +28,7 @@ pub use nym_sphinx::receiver::ReconstructedMessage; pub mod config; -type NativeClientBuilder<'a> = BaseClientBuilder<'a, Client, OnDiskPersistent>; +type NativeClientBuilder<'a> = BaseClientBuilder<'a, QueryHttpRpcNyxdClient, OnDiskPersistent>; pub struct SocketClient { /// Client configuration options, including, among other things, packet sending rates, diff --git a/common/client-core/src/client/base_client/non_wasm_helpers.rs b/common/client-core/src/client/base_client/non_wasm_helpers.rs index e060d3e8fe..d0d2d5a058 100644 --- a/common/client-core/src/client/base_client/non_wasm_helpers.rs +++ b/common/client-core/src/client/base_client/non_wasm_helpers.rs @@ -109,20 +109,15 @@ pub fn create_bandwidth_controller( .get_validator_endpoints() .pop() .expect("No nyxd validator endpoint provided"); - let api_url = config - .get_nym_api_endpoints() - .pop() - .expect("No validator api endpoint provided"); - create_bandwidth_controller_with_urls(nyxd_url, api_url, storage) + create_bandwidth_controller_with_urls(nyxd_url, storage) } pub fn create_bandwidth_controller_with_urls( nyxd_url: Url, - nym_api_url: Url, storage: St, ) -> BandwidthController { - let client = default_query_dkg_client(nyxd_url, nym_api_url); + let client = default_query_dkg_client(nyxd_url); BandwidthController::new(storage, client) } @@ -132,12 +127,8 @@ pub fn default_query_dkg_client_from_config(config: &Config) -> QueryHttpRpcNyxd .get_validator_endpoints() .pop() .expect("No nyxd validator endpoint provided"); - let api_url = config - .get_nym_api_endpoints() - .pop() - .expect("No validator api endpoint provided"); - default_query_dkg_client(nyxd_url, api_url) + default_query_dkg_client(nyxd_url) } pub fn default_query_dkg_client(nyxd_url: Url) -> QueryHttpRpcNyxdClient { diff --git a/nym-api/src/support/nyxd/mod.rs b/nym-api/src/support/nyxd/mod.rs index 5e252a1b95..ec0359c31b 100644 --- a/nym-api/src/support/nyxd/mod.rs +++ b/nym-api/src/support/nyxd/mod.rs @@ -9,6 +9,7 @@ use async_trait::async_trait; use cw3::ProposalResponse; use cw4::MemberResponse; use nym_coconut_bandwidth_contract_common::spend_credential::SpendCredentialResponse; +use nym_coconut_dkg_common::msg::QueryMsg as DkgQueryMsg; use nym_coconut_dkg_common::types::InitialReplacementData; use nym_coconut_dkg_common::{ dealer::{ContractDealing, DealerDetails, DealerDetailsResponse}, @@ -427,6 +428,16 @@ impl crate::coconut::client::Client for Client { } } +#[async_trait] +impl DkgQueryClient for Client { + async fn query_dkg_contract(&self, query: DkgQueryMsg) -> std::result::Result + where + for<'a> T: Deserialize<'a>, + { + self.0.read().await.query_dkg_contract(query).await + } +} + #[async_trait] impl SpDirectoryQueryClient for Client { async fn query_service_provider_contract( diff --git a/sdk/rust/nym-sdk/src/bandwidth/client.rs b/sdk/rust/nym-sdk/src/bandwidth/client.rs index 3be519bf49..7171282a71 100644 --- a/sdk/rust/nym-sdk/src/bandwidth/client.rs +++ b/sdk/rust/nym-sdk/src/bandwidth/client.rs @@ -6,9 +6,8 @@ use nym_bandwidth_controller::acquire::state::State; use nym_credential_storage::storage::Storage; use nym_credentials::coconut::bandwidth::BandwidthVoucher; use nym_network_defaults::NymNetworkDetails; -use nym_validator_client::nyxd::{Coin, SigningNyxdClient}; -use nym_validator_client::signing::direct_wallet::DirectSecp256k1HdWallet; -use nym_validator_client::{Client, Config}; +use nym_validator_client::nyxd::Coin; +use nym_validator_client::{nyxd, DirectSigningHttpRpcNyxdClient}; /// The serialized version of the yet untransformed bandwidth voucher. It can be used to complete /// the acquirement process of a bandwidth credential. @@ -22,7 +21,7 @@ pub type VoucherBlob = Vec; /// client. pub struct BandwidthAcquireClient<'a, St: Storage> { network_details: NymNetworkDetails, - client: Client>, + client: DirectSigningHttpRpcNyxdClient, storage: &'a St, } @@ -36,8 +35,14 @@ where mnemonic: String, storage: &'a St, ) -> Result { - let config = Config::try_from_nym_network_details(&network_details)?; - let client = nym_validator_client::Client::new_signing(config, mnemonic.parse()?)?; + let nyxd_url = network_details.endpoints[0].nyxd_url.as_str(); + let config = nyxd::Config::try_from_nym_network_details(&network_details)?; + + let client = DirectSigningHttpRpcNyxdClient::connect_with_mnemonic( + config, + nyxd_url, + mnemonic.parse()?, + )?; Ok(Self { network_details, client, @@ -51,7 +56,7 @@ where /// associated bandwidth credential, using [`Self::recover`]. pub async fn acquire(&self, amount: u128) -> Result<()> { let amount = Coin::new(amount, &self.network_details.chain_details.mix_denom.base); - let state = nym_bandwidth_controller::acquire::deposit(&self.client.nyxd, amount).await?; + let state = nym_bandwidth_controller::acquire::deposit(&self.client, amount).await?; nym_bandwidth_controller::acquire::get_credential(&state, &self.client, self.storage) .await .map_err(|reason| Error::UnconvertedDeposit { diff --git a/sdk/rust/nym-sdk/src/error.rs b/sdk/rust/nym-sdk/src/error.rs index 48469271e4..84283bc9a2 100644 --- a/sdk/rust/nym-sdk/src/error.rs +++ b/sdk/rust/nym-sdk/src/error.rs @@ -1,3 +1,4 @@ +use nym_validator_client::nyxd::error::NyxdError; use std::path::PathBuf; /// Top-level Error enum for the mixnet client and its relevant types. @@ -46,7 +47,7 @@ pub enum Error { DisabledCredentialsMode, #[error("bad validator details: {0}")] - BadValidatorDetails(#[from] nym_validator_client::ValidatorClientError), + BadValidatorDetails(#[from] NyxdError), #[error("socks5 configuration set: {}, but expected to be {}", set, !set)] Socks5Config { set: bool }, diff --git a/sdk/rust/nym-sdk/src/mixnet/client.rs b/sdk/rust/nym-sdk/src/mixnet/client.rs index 8f19074605..212c192f72 100644 --- a/sdk/rust/nym-sdk/src/mixnet/client.rs +++ b/sdk/rust/nym-sdk/src/mixnet/client.rs @@ -24,8 +24,7 @@ use nym_network_defaults::NymNetworkDetails; use nym_socks5_client_core::config::Socks5; use nym_task::manager::TaskStatus; use nym_topology::provider_trait::TopologyProvider; -use nym_validator_client::nyxd::QueryNyxdClient; -use nym_validator_client::Client; +use nym_validator_client::{nyxd, QueryHttpRpcNyxdClient}; use std::path::Path; use std::path::PathBuf; use url::Url; @@ -214,7 +213,7 @@ where /// In the case of enabled credentials, a client instance responsible for querying the state of the /// dkg and coconut contracts - dkg_query_client: Option>, + dkg_query_client: Option, /// Alternative provider of network topology used for constructing sphinx packets. custom_topology_provider: Option>, @@ -244,10 +243,12 @@ where ) -> Result> { // don't create dkg client for the bandwidth controller if credentials are disabled let dkg_query_client = if config.enabled_credentials_mode { - let client_config = nym_validator_client::Config::try_from_nym_network_details( - &config.network_details, + let client_config = + nyxd::Config::try_from_nym_network_details(&config.network_details)?; + let client = QueryHttpRpcNyxdClient::connect( + client_config, + config.network_details.endpoints[0].nyxd_url.as_str(), )?; - let client = nym_validator_client::Client::new_query(client_config)?; Some(client) } else { None From 3c8dd7a72b3a371da8905db94fb2b792bb99805d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Tue, 1 Aug 2023 17:55:59 +0100 Subject: [PATCH 11/24] all crates building --- clients/credential/src/main.rs | 23 +++-- clients/webassembly/Cargo.lock | 1 + clients/webassembly/src/client/mod.rs | 8 +- clients/webassembly/src/lib.rs | 18 ++-- clients/webassembly/src/tester/mod.rs | 8 +- .../examples/offline_signing.rs | 2 +- .../validator-client/src/client.rs | 11 ++- .../client-libs/validator-client/src/lib.rs | 15 ++- .../validator-client/src/nyxd/mod.rs | 93 ++++++++++++------- .../validator-client/src/nyxd/wasm.rs | 20 ++++ .../validator-client/src/signing/tx_signer.rs | 69 -------------- common/commands/src/context/mod.rs | 16 ++-- .../commands/src/validator/account/balance.rs | 2 +- .../commands/src/validator/account/pubkey.rs | 4 +- .../delegators/query_for_delegations.rs | 7 +- .../gateway/gateway_bonding_sign_payload.rs | 10 +- .../gateway/settings/update_config.rs | 2 +- .../gateway/settings/vesting_update_config.rs | 2 +- .../create_family_join_permit_sign_payload.rs | 8 +- .../mixnode/mixnode_bonding_sign_payload.rs | 10 +- .../mixnode/settings/update_config.rs | 2 +- .../mixnode/settings/vesting_update_config.rs | 2 +- .../service/announce_sign_payload.rs | 4 +- .../validator/transactions/get_transaction.rs | 1 + .../transactions/query_transactions.rs | 1 + .../commands/src/validator/vesting/balance.rs | 2 +- .../vesting/query_vesting_schedule.rs | 2 +- .../src/validator/vesting/withdraw_vested.rs | 6 +- .../src-tauri/src/operations/helpers.rs | 17 ++-- .../src/operations/mixnet/account.rs | 13 +-- .../src-tauri/src/operations/mixnet/bond.rs | 15 ++- .../src/operations/mixnet/delegate.rs | 21 +++-- .../src/operations/mixnet/interval.rs | 6 +- .../src/operations/mixnet/rewards.rs | 20 +++- .../src/operations/signatures/sign.rs | 22 ++--- .../src/operations/simulate/admin.rs | 6 +- .../src/operations/simulate/mixnet.rs | 6 +- .../src/operations/simulate/vesting.rs | 6 +- nym-wallet/src-tauri/src/state.rs | 20 ++-- nym-wallet/src-tauri/src/utils.rs | 4 +- 40 files changed, 275 insertions(+), 230 deletions(-) create mode 100644 common/client-libs/validator-client/src/nyxd/wasm.rs diff --git a/clients/credential/src/main.rs b/clients/credential/src/main.rs index a3975c9166..982ef02823 100644 --- a/clients/credential/src/main.rs +++ b/clients/credential/src/main.rs @@ -18,8 +18,8 @@ use clap::{CommandFactory, Parser}; use nym_bin_common::logging::setup_logging; use nym_client_core::config::disk_persistence::CommonClientPaths; use nym_validator_client::nyxd::contract_traits::DkgQueryClient; -use nym_validator_client::nyxd::{Coin, CosmWasmClient}; -use nym_validator_client::Config; +use nym_validator_client::nyxd::{Coin, Config}; +use nym_validator_client::DirectSigningHttpRpcNyxdClient; const SAFETY_BUFFER_SECS: u64 = 60; // 1 minute @@ -34,11 +34,11 @@ struct Cli { pub(crate) command: Command, } -async fn block_until_coconut_is_available( - client: &nym_validator_client::Client, +async fn block_until_coconut_is_available( + client: &C, ) -> Result<()> { loop { - let epoch = client.nyxd.get_current_epoch().await?; + let epoch = client.get_current_epoch().await?; let current_timestamp_secs = SystemTime::now() .duration_since(SystemTime::UNIX_EPOCH)? .as_secs(); @@ -89,15 +89,18 @@ async fn main() -> Result<()> { r.amount as u128, network_details.chain_details.mix_denom.base, ); - let client = - nym_validator_client::Client::new_signing(config, r.mnemonic.parse().unwrap())?; + let endpoint = network_details.endpoints[0].nyxd_url.as_str(); + let client = DirectSigningHttpRpcNyxdClient::connect_with_mnemonic( + config, + endpoint, + r.mnemonic.parse().unwrap(), + )?; block_until_coconut_is_available(&client).await?; info!("Starting depositing funds, don't kill the process"); if !r.recovery_mode { - let state = - nym_bandwidth_controller::acquire::deposit(&client.nyxd, amount).await?; + let state = nym_bandwidth_controller::acquire::deposit(&client, amount).await?; if nym_bandwidth_controller::acquire::get_credential( &state, &client, @@ -117,7 +120,7 @@ async fn main() -> Result<()> { } } } else { - recover_credentials(&client.nyxd, &recovery_storage, &shared_storage).await?; + recover_credentials(&client, &recovery_storage, &shared_storage).await?; } } Command::Completions(c) => c.generate(&mut Cli::command(), bin_name), diff --git a/clients/webassembly/Cargo.lock b/clients/webassembly/Cargo.lock index 3f21d6f932..eb5217315e 100644 --- a/clients/webassembly/Cargo.lock +++ b/clients/webassembly/Cargo.lock @@ -3128,6 +3128,7 @@ dependencies = [ "colored", "cosmrs", "cosmwasm-std", + "cw-utils", "cw3", "cw4", "eyre", diff --git a/clients/webassembly/src/client/mod.rs b/clients/webassembly/src/client/mod.rs index 74af0c2c8e..05e3809498 100644 --- a/clients/webassembly/src/client/mod.rs +++ b/clients/webassembly/src/client/mod.rs @@ -14,7 +14,6 @@ use crate::storage::traits::FullWasmClientStorage; use crate::storage::ClientStorage; use crate::topology::WasmNymTopology; use js_sys::Promise; -use nym_bandwidth_controller::wasm_mockups::{Client as FakeClient, DirectSigningNyxdClient}; use nym_client_core::client::base_client::{ BaseClientBuilder, ClientInput, ClientOutput, ClientState, }; @@ -26,6 +25,7 @@ use nym_task::TaskManager; use nym_topology::provider_trait::{HardcodedTopologyProvider, TopologyProvider}; use nym_topology::NymTopology; use nym_validator_client::client::IdentityKey; +use nym_validator_client::QueryWasmRpcNyxdClient; use rand::rngs::OsRng; use rand::RngCore; use std::sync::Arc; @@ -152,11 +152,7 @@ impl NymClientBuilder { let maybe_topology_provider = self.topology_provider(); let mut base_builder: BaseClientBuilder<_, FullWasmClientStorage> = - BaseClientBuilder::, _>::new( - &self.config.base, - storage, - None, - ); + BaseClientBuilder::::new(&self.config.base, storage, None); if let Some(topology_provider) = maybe_topology_provider { base_builder = base_builder.with_topology_provider(topology_provider); } diff --git a/clients/webassembly/src/lib.rs b/clients/webassembly/src/lib.rs index af6d657940..f8dd2d629e 100644 --- a/clients/webassembly/src/lib.rs +++ b/clients/webassembly/src/lib.rs @@ -3,24 +3,24 @@ use wasm_bindgen::prelude::*; -#[cfg(target_arch = "wasm32")] +// #[cfg(target_arch = "wasm32")] mod client; -#[cfg(target_arch = "wasm32")] +// #[cfg(target_arch = "wasm32")] pub mod encoded_payload_helper; -#[cfg(target_arch = "wasm32")] +// #[cfg(target_arch = "wasm32")] pub mod error; -#[cfg(target_arch = "wasm32")] +// #[cfg(target_arch = "wasm32")] pub mod gateway_selector; -#[cfg(target_arch = "wasm32")] +// #[cfg(target_arch = "wasm32")] pub mod storage; -#[cfg(target_arch = "wasm32")] +// #[cfg(target_arch = "wasm32")] pub mod tester; -#[cfg(target_arch = "wasm32")] +// #[cfg(target_arch = "wasm32")] pub mod topology; -#[cfg(target_arch = "wasm32")] +// #[cfg(target_arch = "wasm32")] pub mod validation; -#[cfg(target_arch = "wasm32")] +// #[cfg(target_arch = "wasm32")] mod helpers; mod constants; diff --git a/clients/webassembly/src/tester/mod.rs b/clients/webassembly/src/tester/mod.rs index 71f985feca..c7d397f322 100644 --- a/clients/webassembly/src/tester/mod.rs +++ b/clients/webassembly/src/tester/mod.rs @@ -12,7 +12,6 @@ use crate::tester::helpers::{ use crate::topology::WasmNymTopology; use futures::channel::mpsc; use js_sys::Promise; -use nym_bandwidth_controller::wasm_mockups::{Client as FakeClient, DirectSigningNyxdClient}; use nym_bandwidth_controller::BandwidthController; use nym_client_core::client::key_manager::ManagedKeys; use nym_client_core::init::{InitialisationDetails, InitialisationResult}; @@ -27,6 +26,7 @@ use nym_sphinx::preparer::PreparedFragment; use nym_task::TaskManager; use nym_topology::NymTopology; use nym_validator_client::client::IdentityKey; +use nym_validator_client::QueryWasmRpcNyxdClient; use rand::rngs::OsRng; use std::collections::HashSet; use std::sync::atomic::{AtomicBool, AtomicU32, Ordering}; @@ -41,8 +41,7 @@ mod ephemeral_receiver; pub(crate) mod helpers; pub type NodeTestMessage = TestMessage; -type LockedGatewayClient = - Arc, EphemeralStorage>>>; +type LockedGatewayClient = Arc>>; pub(crate) const DEFAULT_TEST_TIMEOUT: Duration = Duration::from_secs(10); pub(crate) const DEFAULT_TEST_PACKETS: u32 = 20; @@ -78,8 +77,7 @@ pub struct NymNodeTesterBuilder { base_topology: NymTopology, // unimplemented - bandwidth_controller: - Option, EphemeralStorage>>, + bandwidth_controller: Option>, } fn address(keys: &ManagedKeys, gateway_identity: NodeIdentity) -> Recipient { diff --git a/common/client-libs/validator-client/examples/offline_signing.rs b/common/client-libs/validator-client/examples/offline_signing.rs index a21bfa4475..baa2d10035 100644 --- a/common/client-libs/validator-client/examples/offline_signing.rs +++ b/common/client-libs/validator-client/examples/offline_signing.rs @@ -23,7 +23,7 @@ async fn main() { let signer_address = signer.try_derive_accounts().unwrap()[0].address().clone(); // local 'client' ONLY signing messages - let tx_signer = TxSigner::new(signer); + let tx_signer = signer; // possibly remote client that doesn't do ANY signing // (only broadcasts + queries for sequence numbers) diff --git a/common/client-libs/validator-client/src/client.rs b/common/client-libs/validator-client/src/client.rs index 473da007e8..5106c1c9ae 100644 --- a/common/client-libs/validator-client/src/client.rs +++ b/common/client-libs/validator-client/src/client.rs @@ -23,6 +23,8 @@ pub use nym_mixnet_contract_common::{ // re-export the type to not break existing imports pub use crate::coconut::CoconutApiClient; +#[cfg(feature = "http-client")] +use crate::signing::direct_wallet::DirectSecp256k1HdWallet; #[cfg(feature = "http-client")] use tendermint_rpc::HttpClient; @@ -73,6 +75,11 @@ impl Config { self.nyxd_url = nyxd_url; self } + + pub fn with_simulated_gas_multiplier(mut self, gas_multiplier: f32) -> Self { + self.nyxd_config.simulated_gas_multiplier = gas_multiplier; + self + } } pub struct Client { @@ -81,7 +88,7 @@ pub struct Client { pub nyxd: NyxdClient, } -#[cfg(all(feature = "direct-secp256k1-wallet", feature = "http-client"))] +#[cfg(feature = "http-client")] impl Client { pub fn new_signing( config: Config, @@ -147,7 +154,7 @@ impl Client { } // validator-api wrappers -impl Client { +impl Client { pub fn change_nym_api(&mut self, new_endpoint: Url) { self.nym_api.change_url(new_endpoint) } diff --git a/common/client-libs/validator-client/src/lib.rs b/common/client-libs/validator-client/src/lib.rs index cd94926f02..86989833f5 100644 --- a/common/client-libs/validator-client/src/lib.rs +++ b/common/client-libs/validator-client/src/lib.rs @@ -23,7 +23,9 @@ pub type SigningValidatorClient = Client; #[cfg(feature = "http-client")] pub use cosmrs::rpc::HttpClient as HttpRpcClient; -#[cfg(feature = "http-client")] +#[cfg(target_arch = "wasm32")] +pub use crate::nyxd::wasm::WasmRpcClient; + use crate::signing::direct_wallet::DirectSecp256k1HdWallet; #[cfg(feature = "http-client")] @@ -37,3 +39,14 @@ pub type DirectSigningHttpRpcValidatorClient = Client; // TODO: the same for reqwest client (once implemented) + +// TODO: rename it to whatever we end up using in wasm +#[cfg(target_arch = "wasm32")] +pub type QueryWasmRpcValidatorClient = Client; +#[cfg(target_arch = "wasm32")] +pub type QueryWasmRpcNyxdClient = nyxd::NyxdClient; + +#[cfg(target_arch = "wasm32")] +pub type DirectSigningWasmRpcValidatorClient = Client; +#[cfg(target_arch = "wasm32")] +pub type DirectSigningWasmRpcNyxdClient = nyxd::NyxdClient; diff --git a/common/client-libs/validator-client/src/nyxd/mod.rs b/common/client-libs/validator-client/src/nyxd/mod.rs index fd3017db89..cde1d182fe 100644 --- a/common/client-libs/validator-client/src/nyxd/mod.rs +++ b/common/client-libs/validator-client/src/nyxd/mod.rs @@ -17,7 +17,6 @@ use async_trait::async_trait; use cosmrs::cosmwasm; use cosmrs::tx::Msg; use cosmwasm_std::Addr; -use log::{debug, trace}; use nym_network_defaults::{ChainDetails, NymNetworkDetails}; use serde::Serialize; use std::time::SystemTime; @@ -58,6 +57,9 @@ pub mod cosmwasm_client; pub mod error; pub mod fee; +#[cfg(target_arch = "wasm32")] +pub mod wasm; + // TODO: reqwest based for wasm #[derive(Debug, Clone)] @@ -69,29 +71,29 @@ pub struct Config { } impl Config { - fn parse_optional_account( - raw: Option<&String>, - expected_prefix: &str, - ) -> Result, NyxdError> { - if let Some(address) = raw { - trace!("Raw address:{:?}", raw); - trace!("Expected prefix:{:?}", expected_prefix); - let parsed: AccountId = address - .parse() - .map_err(|_| NyxdError::MalformedAccountAddress(address.clone()))?; - debug!("Parsed prefix:{:?}", parsed); - if parsed.prefix() != expected_prefix { - Err(NyxdError::UnexpectedBech32Prefix { - got: parsed.prefix().into(), - expected: expected_prefix.into(), - }) - } else { - Ok(Some(parsed)) - } - } else { - Ok(None) - } - } + // fn parse_optional_account( + // raw: Option<&String>, + // expected_prefix: &str, + // ) -> Result, NyxdError> { + // if let Some(address) = raw { + // trace!("Raw address:{:?}", raw); + // trace!("Expected prefix:{:?}", expected_prefix); + // let parsed: AccountId = address + // .parse() + // .map_err(|_| NyxdError::MalformedAccountAddress(address.clone()))?; + // debug!("Parsed prefix:{:?}", parsed); + // if parsed.prefix() != expected_prefix { + // Err(NyxdError::UnexpectedBech32Prefix { + // got: parsed.prefix().into(), + // expected: expected_prefix.into(), + // }) + // } else { + // Ok(Some(parsed)) + // } + // } else { + // Ok(None) + // } + // } pub fn try_from_nym_network_details(details: &NymNetworkDetails) -> Result { Ok(Config { @@ -188,8 +190,27 @@ impl NyxdClient { } } +impl NyxdClient { + pub fn new(config: Config, client: C) -> Self { + NyxdClient { + client: MaybeSigningClient::new(client, (&config).into()), + config, + } + } +} + // no trait bounds impl NyxdClient { + pub fn new_signing(config: Config, client: C, signer: S) -> Self + where + S: OfflineSigner, + { + NyxdClient { + client: MaybeSigningClient::new_signing(client, signer, (&config).into()), + config, + } + } + pub fn current_config(&self) -> &Config { &self.config } @@ -271,6 +292,18 @@ where C: TendermintClient + Send + Sync, S: Send + Sync, { + pub async fn get_account_public_key( + &self, + address: &AccountId, + ) -> Result, NyxdError> { + if let Some(account) = self.client.get_account(address).await? { + let base_account = account.try_get_base_account()?; + return Ok(base_account.pubkey); + } + + Ok(None) + } + pub async fn get_current_block_timestamp(&self) -> Result { self.get_block_timestamp(None).await } @@ -310,18 +343,6 @@ where S: OfflineSigner + Send + Sync, NyxdError: From<::Error>, { - pub async fn get_account_public_key( - &self, - address: &AccountId, - ) -> Result, NyxdError> { - if let Some(account) = self.client.get_account(address).await? { - let base_account = account.try_get_base_account()?; - return Ok(base_account.pubkey); - } - - Ok(None) - } - pub fn address(&self) -> AccountId { match self.client.signer_addresses() { Ok(addresses) => addresses[0].clone(), diff --git a/common/client-libs/validator-client/src/nyxd/wasm.rs b/common/client-libs/validator-client/src/nyxd/wasm.rs new file mode 100644 index 0000000000..4186fc54fa --- /dev/null +++ b/common/client-libs/validator-client/src/nyxd/wasm.rs @@ -0,0 +1,20 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::nyxd::TendermintClient; +use async_trait::async_trait; +use tendermint_rpc::{Error, SimpleRequest}; + +pub struct WasmRpcClient { + // +} + +#[async_trait] +impl TendermintClient for WasmRpcClient { + async fn perform(&self, _request: R) -> Result + where + R: SimpleRequest, + { + todo!() + } +} diff --git a/common/client-libs/validator-client/src/signing/tx_signer.rs b/common/client-libs/validator-client/src/signing/tx_signer.rs index f5e2dd91ba..f04047c39e 100644 --- a/common/client-libs/validator-client/src/signing/tx_signer.rs +++ b/common/client-libs/validator-client/src/signing/tx_signer.rs @@ -5,75 +5,6 @@ use crate::signing::signer::{OfflineSigner, SigningError}; use crate::signing::SignerData; use cosmrs::tx::{SignDoc, SignerInfo}; use cosmrs::{tx, AccountId, Any}; -// -// #[derive(Debug)] -// /// A client that has only one responsibility - sign transactions -// /// and not touch chain. -// pub struct TxSigner { -// signer: S, -// } -// -// impl TxSigner { -// pub fn new(signer: S) -> Self { -// TxSigner { signer } -// } -// -// pub fn signer(&self) -> &S { -// &self.signer -// } -// -// pub fn into_inner_signer(self) -> S { -// self.signer -// } -// -// pub fn sign_amino( -// &self, -// _signer_address: &AccountId, -// _messages: Vec, -// _fee: tx::Fee, -// _memo: impl Into + Send + 'static, -// _signer_data: SignerData, -// ) -> Result -// where -// S: OfflineSigner, -// { -// unimplemented!() -// } -// -// // TODO: change this sucker to use the trait better -// pub fn sign_direct( -// &self, -// signer_address: &AccountId, -// messages: Vec, -// fee: tx::Fee, -// memo: impl Into + Send + 'static, -// signer_data: SignerData, -// ) -> Result -// where -// S: OfflineSigner, -// { -// let account_from_signer = self.signer.find_account(signer_address)?; -// -// // TODO: experiment with this field -// let timeout_height = 0u32; -// -// let tx_body = tx::Body::new(messages, memo, timeout_height); -// let signer_info = -// SignerInfo::single_direct(Some(account_from_signer.public_key), signer_data.sequence); -// let auth_info = signer_info.auth_info(fee); -// -// let sign_doc = SignDoc::new( -// &tx_body, -// &auth_info, -// &signer_data.chain_id, -// signer_data.account_number, -// ) -// .map_err(|source| SigningError::SignDocFailure { source })?; -// -// self.signer -// .sign_direct_with_account(&account_from_signer, sign_doc) -// } -// } // extension trait for the OfflineSigner to allow to sign transactions pub trait TxSigner: OfflineSigner { diff --git a/common/commands/src/context/mod.rs b/common/commands/src/context/mod.rs index e2d648fbf0..db20ed0ac3 100644 --- a/common/commands/src/context/mod.rs +++ b/common/commands/src/context/mod.rs @@ -8,17 +8,19 @@ use nym_network_defaults::{ NymNetworkDetails, }; pub use nym_validator_client::nym_api::Client as NymApiClient; -use nym_validator_client::nyxd::{ - self, AccountId, DirectSigningNyxdClient, NyxdClient, QueryNyxdClient, +use nym_validator_client::nyxd::{self, AccountId, NyxdClient}; +use nym_validator_client::{ + DirectSigningHttpRpcNyxdClient, DirectSigningHttpRpcValidatorClient, QueryHttpRpcNyxdClient, + QueryHttpRpcValidatorClient, }; use tap::prelude::*; pub mod errors; -pub type SigningClient = nym_validator_client::nyxd::NyxdClient; -pub type QueryClient = nym_validator_client::nyxd::NyxdClient; -pub type SigningClientWithNyxd = nym_validator_client::Client; -pub type QueryClientWithNyxd = nym_validator_client::Client; +pub type SigningClient = DirectSigningHttpRpcNyxdClient; +pub type QueryClient = QueryHttpRpcNyxdClient; +pub type SigningClientWithNyxd = DirectSigningHttpRpcValidatorClient; +pub type QueryClientWithNyxd = QueryHttpRpcValidatorClient; #[derive(Debug)] pub struct ClientArgs { @@ -79,7 +81,7 @@ pub fn create_signing_client( .nyxd_url .as_str(); - match NyxdClient::connect_with_mnemonic(client_config, nyxd_url, mnemonic, None) { + match NyxdClient::connect_with_mnemonic(client_config, nyxd_url, mnemonic) { Ok(client) => Ok(client), Err(e) => Err(ContextError::NyxdError(format!("{e}"))), } diff --git a/common/commands/src/validator/account/balance.rs b/common/commands/src/validator/account/balance.rs index 8786470bd1..4e109ad7b3 100644 --- a/common/commands/src/validator/account/balance.rs +++ b/common/commands/src/validator/account/balance.rs @@ -4,7 +4,7 @@ use clap::Parser; use log::{error, info}; -use nym_validator_client::nyxd::AccountId; +use nym_validator_client::nyxd::{AccountId, CosmWasmClient}; use crate::context::QueryClient; use crate::utils::{pretty_coin, show_error}; diff --git a/common/commands/src/validator/account/pubkey.rs b/common/commands/src/validator/account/pubkey.rs index b1ed260568..6a7c3383d6 100644 --- a/common/commands/src/validator/account/pubkey.rs +++ b/common/commands/src/validator/account/pubkey.rs @@ -3,7 +3,7 @@ use clap::Parser; use log::{error, info}; -use nym_validator_client::nyxd::AccountId; +use nym_validator_client::nyxd::{AccountId, CosmWasmClient}; use nym_validator_client::signing::direct_wallet::DirectSecp256k1HdWallet; use crate::context::QueryClient; @@ -68,7 +68,7 @@ pub fn get_pubkey_from_mnemonic(address: AccountId, prefix: &str, mnemonic: bip3 pub async fn get_pubkey_from_chain(address: AccountId, client: &QueryClient) { info!("Getting public key for address {} from chain...", address); - match client.get_account_details(&address).await { + match client.get_account(&address).await { Ok(Some(account)) => { if let Ok(base_account) = account.try_get_base_account() { if let Some(pubkey) = base_account.pubkey { diff --git a/common/commands/src/validator/mixnet/delegators/query_for_delegations.rs b/common/commands/src/validator/mixnet/delegators/query_for_delegations.rs index 4e6d91926b..f29dae6db3 100644 --- a/common/commands/src/validator/mixnet/delegators/query_for_delegations.rs +++ b/common/commands/src/validator/mixnet/delegators/query_for_delegations.rs @@ -10,6 +10,7 @@ use crate::utils::{pretty_cosmwasm_coin, show_error_passthrough}; use comfy_table::Table; use cosmwasm_std::Addr; use nym_mixnet_contract_common::{Delegation, PendingEpochEvent, PendingEpochEventKind}; +use nym_validator_client::nyxd::contract_traits::PagedMixnetQueryClient; #[derive(Debug, Parser)] pub struct Args {} @@ -21,12 +22,14 @@ pub async fn execute(_args: Args, client: SigningClientWithNyxd) { ); let delegations = client - .get_all_delegator_delegations(client.nyxd.address()) + .nyxd + .get_all_delegator_delegations(&client.nyxd.address()) .await .map_err(show_error_passthrough); let mixnet_contract_events = client - .get_all_nyxd_pending_epoch_events() + .nyxd + .get_all_pending_epoch_events() .await .map_err(show_error_passthrough); diff --git a/common/commands/src/validator/mixnet/operators/gateway/gateway_bonding_sign_payload.rs b/common/commands/src/validator/mixnet/operators/gateway/gateway_bonding_sign_payload.rs index 9bc24ea0e0..3845a6c7ef 100644 --- a/common/commands/src/validator/mixnet/operators/gateway/gateway_bonding_sign_payload.rs +++ b/common/commands/src/validator/mixnet/operators/gateway/gateway_bonding_sign_payload.rs @@ -8,7 +8,7 @@ use cosmwasm_std::Coin; use nym_bin_common::output_format::OutputFormat; use nym_mixnet_contract_common::construct_gateway_bonding_sign_payload; use nym_network_defaults::{DEFAULT_CLIENT_LISTENING_PORT, DEFAULT_MIX_LISTENING_PORT}; -use nym_validator_client::nyxd::contract_traits::MixnetQueryClient; +use nym_validator_client::nyxd::contract_traits::{MixnetQueryClient, NymContractsProvider}; #[derive(Debug, Parser)] pub struct Args { @@ -62,7 +62,7 @@ pub async fn create_payload(args: Args, client: SigningClient) { let coin = Coin::new(args.amount, denom); - let nonce = match client.get_signing_nonce(client.address()).await { + let nonce = match client.get_signing_nonce(&client.address()).await { Ok(nonce) => nonce, Err(err) => { eprint!( @@ -73,9 +73,11 @@ pub async fn create_payload(args: Args, client: SigningClient) { } }; - let address = account_id_to_cw_addr(client.address()); + let address = account_id_to_cw_addr(&client.address()); let proxy = if args.with_vesting_account { - Some(account_id_to_cw_addr(client.vesting_contract_address())) + Some(account_id_to_cw_addr( + client.vesting_contract_address().unwrap(), + )) } else { None }; diff --git a/common/commands/src/validator/mixnet/operators/gateway/settings/update_config.rs b/common/commands/src/validator/mixnet/operators/gateway/settings/update_config.rs index 9b6cd07da3..c0cf879147 100644 --- a/common/commands/src/validator/mixnet/operators/gateway/settings/update_config.rs +++ b/common/commands/src/validator/mixnet/operators/gateway/settings/update_config.rs @@ -29,7 +29,7 @@ pub async fn update_config(args: Args, client: SigningClient) { info!("Update gateway config!"); let current_details = match client - .get_owned_gateway(client.address()) + .get_owned_gateway(&client.address()) .await .expect("failed to query the chain for gateway details") .gateway diff --git a/common/commands/src/validator/mixnet/operators/gateway/settings/vesting_update_config.rs b/common/commands/src/validator/mixnet/operators/gateway/settings/vesting_update_config.rs index 75aed1349d..346b652b2f 100644 --- a/common/commands/src/validator/mixnet/operators/gateway/settings/vesting_update_config.rs +++ b/common/commands/src/validator/mixnet/operators/gateway/settings/vesting_update_config.rs @@ -30,7 +30,7 @@ pub async fn vesting_update_config(args: Args, client: SigningClient) { info!("Update vesting gateway config!"); let current_details = match client - .get_owned_gateway(client.address()) + .get_owned_gateway(&client.address()) .await .expect("failed to query the chain for gateway details") .gateway diff --git a/common/commands/src/validator/mixnet/operators/mixnode/families/create_family_join_permit_sign_payload.rs b/common/commands/src/validator/mixnet/operators/mixnode/families/create_family_join_permit_sign_payload.rs index 9293f7188f..c81dc35f69 100644 --- a/common/commands/src/validator/mixnet/operators/mixnode/families/create_family_join_permit_sign_payload.rs +++ b/common/commands/src/validator/mixnet/operators/mixnode/families/create_family_join_permit_sign_payload.rs @@ -10,7 +10,7 @@ use nym_bin_common::output_format::OutputFormat; use nym_crypto::asymmetric::identity; use nym_mixnet_contract_common::construct_family_join_permit; use nym_mixnet_contract_common::families::FamilyHead; -use nym_validator_client::nyxd::contract_traits::MixnetQueryClient; +use nym_validator_client::nyxd::contract_traits::{MixnetQueryClient, NymContractsProvider}; #[derive(Debug, Parser)] pub struct Args { @@ -47,7 +47,7 @@ pub async fn create_family_join_permit_sign_payload(args: Args, client: QueryCli // make sure this mixnode is actually a family head if client - .get_node_family_by_head(mixnode.bond_information.identity()) + .get_node_family_by_head(mixnode.bond_information.identity().to_string()) .await .unwrap() .family @@ -70,7 +70,9 @@ pub async fn create_family_join_permit_sign_payload(args: Args, client: QueryCli // let address = account_id_to_cw_addr(&args.address); let proxy = if args.with_vesting_account { - Some(account_id_to_cw_addr(client.vesting_contract_address())) + Some(account_id_to_cw_addr( + client.vesting_contract_address().unwrap(), + )) } else { None }; diff --git a/common/commands/src/validator/mixnet/operators/mixnode/mixnode_bonding_sign_payload.rs b/common/commands/src/validator/mixnet/operators/mixnode/mixnode_bonding_sign_payload.rs index 4eacdcf4b4..332de7614e 100644 --- a/common/commands/src/validator/mixnet/operators/mixnode/mixnode_bonding_sign_payload.rs +++ b/common/commands/src/validator/mixnet/operators/mixnode/mixnode_bonding_sign_payload.rs @@ -11,7 +11,7 @@ use nym_mixnet_contract_common::{construct_mixnode_bonding_sign_payload, MixNode use nym_network_defaults::{ DEFAULT_HTTP_API_LISTENING_PORT, DEFAULT_MIX_LISTENING_PORT, DEFAULT_VERLOC_LISTENING_PORT, }; -use nym_validator_client::nyxd::contract_traits::MixnetQueryClient; +use nym_validator_client::nyxd::contract_traits::{MixnetQueryClient, NymContractsProvider}; use nym_validator_client::nyxd::CosmWasmCoin; #[derive(Debug, Parser)] @@ -88,7 +88,7 @@ pub async fn create_payload(args: Args, client: SigningClient) { }, }; - let nonce = match client.get_signing_nonce(client.address()).await { + let nonce = match client.get_signing_nonce(&client.address()).await { Ok(nonce) => nonce, Err(err) => { eprint!( @@ -99,9 +99,11 @@ pub async fn create_payload(args: Args, client: SigningClient) { } }; - let address = account_id_to_cw_addr(client.address()); + let address = account_id_to_cw_addr(&client.address()); let proxy = if args.with_vesting_account { - Some(account_id_to_cw_addr(client.vesting_contract_address())) + Some(account_id_to_cw_addr( + client.vesting_contract_address().unwrap(), + )) } else { None }; diff --git a/common/commands/src/validator/mixnet/operators/mixnode/settings/update_config.rs b/common/commands/src/validator/mixnet/operators/mixnode/settings/update_config.rs index dd7524bfdf..733dea04a1 100644 --- a/common/commands/src/validator/mixnet/operators/mixnode/settings/update_config.rs +++ b/common/commands/src/validator/mixnet/operators/mixnode/settings/update_config.rs @@ -29,7 +29,7 @@ pub async fn update_config(args: Args, client: SigningClient) { info!("Update mix node config!"); let current_details = match client - .get_owned_mixnode(client.address()) + .get_owned_mixnode(&client.address()) .await .expect("failed to query the chain for mixnode details") .mixnode_details diff --git a/common/commands/src/validator/mixnet/operators/mixnode/settings/vesting_update_config.rs b/common/commands/src/validator/mixnet/operators/mixnode/settings/vesting_update_config.rs index c7d1c96c01..a495c8f4b5 100644 --- a/common/commands/src/validator/mixnet/operators/mixnode/settings/vesting_update_config.rs +++ b/common/commands/src/validator/mixnet/operators/mixnode/settings/vesting_update_config.rs @@ -30,7 +30,7 @@ pub async fn vesting_update_config(client: SigningClient, args: Args) { info!("Update vesting mix node config!"); let current_details = match client - .get_owned_mixnode(client.address()) + .get_owned_mixnode(&client.address()) .await .expect("failed to query the chain for mixnode details") .mixnode_details diff --git a/common/commands/src/validator/mixnet/operators/service/announce_sign_payload.rs b/common/commands/src/validator/mixnet/operators/service/announce_sign_payload.rs index bda4e56b9d..f3dc4e5e66 100644 --- a/common/commands/src/validator/mixnet/operators/service/announce_sign_payload.rs +++ b/common/commands/src/validator/mixnet/operators/service/announce_sign_payload.rs @@ -42,7 +42,7 @@ pub async fn create_payload(args: Args, client: SigningClient) { let denom = client.current_chain_details().mix_denom.base.as_str(); let deposit = Coin::new(args.amount, denom); - let nonce = match client.get_service_signing_nonce(client.address()).await { + let nonce = match client.get_service_signing_nonce(&client.address()).await { Ok(nonce) => nonce, Err(err) => { eprint!( @@ -53,7 +53,7 @@ pub async fn create_payload(args: Args, client: SigningClient) { } }; - let address = account_id_to_cw_addr(client.address()); + let address = account_id_to_cw_addr(&client.address()); let payload = construct_service_provider_announce_sign_payload(nonce, address, deposit, service); let wrapper = DataWrapper::new(payload.to_base58_string().unwrap()); diff --git a/common/commands/src/validator/transactions/get_transaction.rs b/common/commands/src/validator/transactions/get_transaction.rs index 6ad1bbbd2f..62d829d52b 100644 --- a/common/commands/src/validator/transactions/get_transaction.rs +++ b/common/commands/src/validator/transactions/get_transaction.rs @@ -7,6 +7,7 @@ use std::str::FromStr; use crate::context::QueryClient; use crate::utils::show_error; use cosmrs::tendermint::Hash; +use nym_validator_client::nyxd::CosmWasmClient; use serde_json::json; #[derive(Debug, Parser)] diff --git a/common/commands/src/validator/transactions/query_transactions.rs b/common/commands/src/validator/transactions/query_transactions.rs index b8b341ec57..f109d9a07a 100644 --- a/common/commands/src/validator/transactions/query_transactions.rs +++ b/common/commands/src/validator/transactions/query_transactions.rs @@ -5,6 +5,7 @@ use std::str::FromStr; use clap::Parser; use cosmrs::rpc::query::Query; +use nym_validator_client::nyxd::CosmWasmClient; use serde_json::json; use crate::context::QueryClient; diff --git a/common/commands/src/validator/vesting/balance.rs b/common/commands/src/validator/vesting/balance.rs index 8208e1e2e4..ff8e2ee28c 100644 --- a/common/commands/src/validator/vesting/balance.rs +++ b/common/commands/src/validator/vesting/balance.rs @@ -5,7 +5,7 @@ use clap::Parser; use cosmrs::AccountId; use log::{error, info}; -use nym_validator_client::nyxd::{contract_traits::VestingQueryClient, Coin}; +use nym_validator_client::nyxd::{contract_traits::VestingQueryClient, Coin, CosmWasmClient}; use crate::context::QueryClient; use crate::utils::show_error; diff --git a/common/commands/src/validator/vesting/query_vesting_schedule.rs b/common/commands/src/validator/vesting/query_vesting_schedule.rs index 5c8b0bf153..0baca858f1 100644 --- a/common/commands/src/validator/vesting/query_vesting_schedule.rs +++ b/common/commands/src/validator/vesting/query_vesting_schedule.rs @@ -6,7 +6,7 @@ use cosmrs::AccountId; use cosmwasm_std::Coin as CosmWasmCoin; use log::{error, info}; -use nym_validator_client::nyxd::{contract_traits::VestingQueryClient, Coin}; +use nym_validator_client::nyxd::{contract_traits::VestingQueryClient, Coin, CosmWasmClient}; use crate::context::QueryClient; use crate::utils::show_error; diff --git a/common/commands/src/validator/vesting/withdraw_vested.rs b/common/commands/src/validator/vesting/withdraw_vested.rs index 8a0c3f3f9c..2c2bf254b9 100644 --- a/common/commands/src/validator/vesting/withdraw_vested.rs +++ b/common/commands/src/validator/vesting/withdraw_vested.rs @@ -6,7 +6,7 @@ use log::info; use nym_validator_client::nyxd::{ contract_traits::{VestingQueryClient, VestingSigningClient}, - Coin, + Coin, CosmWasmClient, }; use crate::context::SigningClient; @@ -39,7 +39,7 @@ pub async fn execute(args: Args, client: SigningClient) { .await .unwrap_or_else(|_| Coin::new(0u128, denom)); let liquid_account_balance = client - .get_balance(account_id, denom.to_string()) + .get_balance(&account_id, denom.to_string()) .await .unwrap_or(None) .unwrap_or_else(|| Coin::new(0u128, denom)); @@ -97,7 +97,7 @@ pub async fn execute(args: Args, client: SigningClient) { .unwrap_or_else(|_| Coin::new(0u128, denom)); let liquid_account_balance = client - .get_balance(account_id, denom.to_string()) + .get_balance(&account_id, denom.to_string()) .await .unwrap_or(None) .unwrap_or_else(|| Coin::new(0u128, denom)); diff --git a/nym-wallet/src-tauri/src/operations/helpers.rs b/nym-wallet/src-tauri/src/operations/helpers.rs index 35e59cca25..35dacbb190 100644 --- a/nym-wallet/src-tauri/src/operations/helpers.rs +++ b/nym-wallet/src-tauri/src/operations/helpers.rs @@ -12,10 +12,10 @@ use nym_mixnet_contract_common::{ construct_mixnode_bonding_sign_payload, Gateway, GatewayBondingPayload, MixNode, MixNodeCostParams, SignableGatewayBondingMsg, SignableMixNodeBondingMsg, }; -use nym_validator_client::nyxd::contract_traits::MixnetQueryClient; +use nym_validator_client::nyxd::contract_traits::{MixnetQueryClient, NymContractsProvider}; use nym_validator_client::nyxd::error::NyxdError; -use nym_validator_client::nyxd::{Coin, DirectSigningNyxdClient}; -use nym_validator_client::Client; +use nym_validator_client::nyxd::Coin; +use nym_validator_client::DirectSigningHttpRpcValidatorClient; // define this as a separate trait for mocking purposes #[async_trait] @@ -26,15 +26,20 @@ pub(crate) trait AddressAndNonceProvider { } #[async_trait] -impl AddressAndNonceProvider for Client { +impl AddressAndNonceProvider for DirectSigningHttpRpcValidatorClient { async fn get_signing_nonce(&self) -> Result { - self.nyxd.get_signing_nonce(self.nyxd.address()).await + self.nyxd.get_signing_nonce(&self.nyxd.address()).await } fn vesting_contract_address(&self) -> Addr { // the call to unchecked is fine here as we're converting directly from `AccountId` // which must have been a valid bech32 address - Addr::unchecked(self.nyxd.vesting_contract_address().as_ref()) + Addr::unchecked( + self.nyxd + .vesting_contract_address() + .expect("unknown vesting contract address") + .as_ref(), + ) } fn cw_address(&self) -> Addr { diff --git a/nym-wallet/src-tauri/src/operations/mixnet/account.rs b/nym-wallet/src-tauri/src/operations/mixnet/account.rs index 07f939ce95..4060b1e810 100644 --- a/nym-wallet/src-tauri/src/operations/mixnet/account.rs +++ b/nym-wallet/src-tauri/src/operations/mixnet/account.rs @@ -9,9 +9,10 @@ use cosmrs::bip32::DerivationPath; use itertools::Itertools; use nym_config::defaults::{NymNetworkDetails, COSMOS_DERIVATION_PATH}; use nym_types::account::{Account, AccountEntry, Balance}; +use nym_validator_client::nyxd::CosmWasmClient; use nym_validator_client::signing::direct_wallet::DirectSecp256k1HdWallet; use nym_validator_client::signing::AccountData; -use nym_validator_client::{nyxd::DirectSigningNyxdClient, Client}; +use nym_validator_client::DirectSigningHttpRpcValidatorClient; use nym_wallet_types::network::Network as WalletNetwork; use std::collections::HashMap; use strum::IntoEnumIterator; @@ -35,7 +36,7 @@ pub async fn get_balance(state: tauri::State<'_, WalletState>) -> Result { @@ -251,7 +252,7 @@ fn create_clients( default_api_urls: &HashMap, config: &Config, mnemonic: &Mnemonic, -) -> Result)>, BackendError> { +) -> Result, BackendError> { let mut clients = Vec::new(); for network in WalletNetwork::iter() { let nyxd_url = if let Some(url) = config.get_selected_validator_nyxd_url(network) { @@ -285,10 +286,10 @@ fn create_clients( .with_vesting_contract(Some(config.get_vesting_contract_address(network).as_ref())); let config = nym_validator_client::Config::try_from_nym_network_details(&network_details)? - .with_urls(nyxd_url, api_url); + .with_urls(nyxd_url, api_url) + .with_simulated_gas_multiplier(CUSTOM_SIMULATED_GAS_MULTIPLIER); - let mut client = nym_validator_client::Client::new_signing(config, mnemonic.clone())?; - client.set_nyxd_simulated_gas_multiplier(CUSTOM_SIMULATED_GAS_MULTIPLIER); + let client = nym_validator_client::Client::new_signing(config, mnemonic.clone())?; clients.push((network, client)); } Ok(clients) diff --git a/nym-wallet/src-tauri/src/operations/mixnet/bond.rs b/nym-wallet/src-tauri/src/operations/mixnet/bond.rs index 94ce11a815..896b62175a 100644 --- a/nym-wallet/src-tauri/src/operations/mixnet/bond.rs +++ b/nym-wallet/src-tauri/src/operations/mixnet/bond.rs @@ -337,7 +337,10 @@ pub async fn get_mixnode_avg_uptime( log::info!(">>> Get mixnode bond details"); let guard = state.read().await; let client = guard.current_client()?; - let res = client.nyxd.get_owned_mixnode(client.nyxd.address()).await?; + let res = client + .nyxd + .get_owned_mixnode(&client.nyxd.address()) + .await?; match res.mixnode_details { Some(details) => { @@ -363,7 +366,10 @@ pub async fn mixnode_bond_details( log::info!(">>> Get mixnode bond details"); let guard = state.read().await; let client = guard.current_client()?; - let res = client.nyxd.get_owned_mixnode(client.nyxd.address()).await?; + let res = client + .nyxd + .get_owned_mixnode(&client.nyxd.address()) + .await?; let details = res .mixnode_details .map(|details| { @@ -391,7 +397,10 @@ pub async fn gateway_bond_details( log::info!(">>> Get gateway bond details"); let guard = state.read().await; let client = guard.current_client()?; - let bond = client.nyxd.get_owned_gateway(client.nyxd.address()).await?; + let bond = client + .nyxd + .get_owned_gateway(&client.nyxd.address()) + .await?; let res = bond .gateway .map(|bond| { diff --git a/nym-wallet/src-tauri/src/operations/mixnet/delegate.rs b/nym-wallet/src-tauri/src/operations/mixnet/delegate.rs index e29dda737b..18bd72551f 100644 --- a/nym-wallet/src-tauri/src/operations/mixnet/delegate.rs +++ b/nym-wallet/src-tauri/src/operations/mixnet/delegate.rs @@ -13,7 +13,9 @@ use nym_types::deprecated::{ use nym_types::mixnode::MixNodeCostParams; use nym_types::pending_events::PendingEpochEvent; use nym_types::transaction::TransactionExecuteResult; -use nym_validator_client::nyxd::contract_traits::{MixnetQueryClient, MixnetSigningClient}; +use nym_validator_client::nyxd::contract_traits::{ + MixnetQueryClient, MixnetSigningClient, NymContractsProvider, PagedMixnetQueryClient, +}; use nym_validator_client::nyxd::Fee; #[tauri::command] @@ -25,7 +27,7 @@ pub async fn get_pending_delegation_events( let reg = guard.registered_coins()?; let client = guard.current_client()?; - let events = client.get_all_nyxd_pending_epoch_events().await?; + let events = client.nyxd.get_all_pending_epoch_events().await?; let converted = events .into_iter() .map(|e| PendingEpochEvent::try_from_mixnet_contract(e, reg)) @@ -156,10 +158,13 @@ pub async fn get_all_mix_delegations( let address = client.nyxd.address(); let network = guard.current_network(); let base_mix_denom = network.base_mix_denom().to_string(); - let vesting_contract = client.nyxd.vesting_contract_address(); + let vesting_contract = client + .nyxd + .vesting_contract_address() + .expect("vesting contract address is not available"); log::info!(" >>> Get delegations"); - let delegations = client.get_all_delegator_delegations(address).await?; + let delegations = client.nyxd.get_all_delegator_delegations(&address).await?; log::info!(" <<< {} delegations", delegations.len()); let pending_events_for_account = get_pending_delegation_events(state.clone()).await?; @@ -185,7 +190,11 @@ pub async fn get_all_mix_delegations( d.amount ); - let mixnode = client.get_mixnode_details(d.mix_id).await?.mixnode_details; + let mixnode = client + .nyxd + .get_mixnode_details(d.mix_id) + .await? + .mixnode_details; let accumulated_by_operator = mixnode .as_ref() @@ -214,7 +223,7 @@ pub async fn get_all_mix_delegations( log::trace!(" >>> Get accumulated rewards: address = {}", address); let pending_reward = client .nyxd - .get_pending_delegator_reward(address, d.mix_id, d.proxy.clone()) + .get_pending_delegator_reward(&address, d.mix_id, d.proxy.clone()) .await?; let accumulated_rewards = match &pending_reward.amount_earned { diff --git a/nym-wallet/src-tauri/src/operations/mixnet/interval.rs b/nym-wallet/src-tauri/src/operations/mixnet/interval.rs index 14a1d09699..05151d8a53 100644 --- a/nym-wallet/src-tauri/src/operations/mixnet/interval.rs +++ b/nym-wallet/src-tauri/src/operations/mixnet/interval.rs @@ -5,7 +5,7 @@ use crate::error::BackendError; use crate::nyxd_client; use crate::state::WalletState; use nym_types::pending_events::{PendingEpochEvent, PendingIntervalEvent}; -use nym_validator_client::nyxd::contract_traits::MixnetQueryClient; +use nym_validator_client::nyxd::contract_traits::{MixnetQueryClient, PagedMixnetQueryClient}; use nym_wallet_types::interval::Interval; #[tauri::command] @@ -26,7 +26,7 @@ pub async fn get_pending_epoch_events( let guard = state.read().await; let reg = guard.registered_coins()?; let client = guard.current_client()?; - let res = client.get_all_nyxd_pending_epoch_events().await?; + let res = client.nyxd.get_all_pending_epoch_events().await?; log::info!("<<< got = {:?} events", res.len()); @@ -46,7 +46,7 @@ pub async fn get_pending_interval_events( let guard = state.read().await; let reg = guard.registered_coins()?; let client = guard.current_client()?; - let res = client.get_all_nyxd_pending_interval_events().await?; + let res = client.nyxd.get_all_pending_interval_events().await?; log::info!("<<< got = {:?} events", res.len()); diff --git a/nym-wallet/src-tauri/src/operations/mixnet/rewards.rs b/nym-wallet/src-tauri/src/operations/mixnet/rewards.rs index 81da431443..266295c6e1 100644 --- a/nym-wallet/src-tauri/src/operations/mixnet/rewards.rs +++ b/nym-wallet/src-tauri/src/operations/mixnet/rewards.rs @@ -3,7 +3,9 @@ use crate::state::WalletState; use crate::vesting::rewards::vesting_claim_delegator_reward; use nym_mixnet_contract_common::{MixId, RewardingParams}; use nym_types::transaction::TransactionExecuteResult; -use nym_validator_client::nyxd::contract_traits::{MixnetQueryClient, MixnetSigningClient}; +use nym_validator_client::nyxd::contract_traits::{ + MixnetQueryClient, MixnetSigningClient, NymContractsProvider, PagedMixnetQueryClient, +}; use nym_validator_client::nyxd::Fee; #[tauri::command] @@ -64,13 +66,21 @@ pub async fn claim_locked_and_unlocked_delegator_reward( log::trace!(">>> Get delegations: mix_id = {}", mix_id); let address = client.nyxd.address(); - let delegations = client.get_all_delegator_delegations(address).await?; + let delegations = client.nyxd.get_all_delegator_delegations(&address).await?; log::trace!("<<< {} delegations", delegations.len()); - let vesting_contract = client.nyxd.vesting_contract_address().to_string(); - let liquid_delegation = client.get_delegation_details(mix_id, address, None).await?; + let vesting_contract = client + .nyxd + .vesting_contract_address() + .expect("vesting contract address is not available") + .to_string(); + let liquid_delegation = client + .nyxd + .get_delegation_details(mix_id, &address, None) + .await?; let vesting_delegation = client - .get_delegation_details(mix_id, address, Some(vesting_contract)) + .nyxd + .get_delegation_details(mix_id, &address, Some(vesting_contract)) .await?; drop(guard); diff --git a/nym-wallet/src-tauri/src/operations/signatures/sign.rs b/nym-wallet/src-tauri/src/operations/signatures/sign.rs index 24da5a0ca1..c494bc5b4f 100644 --- a/nym-wallet/src-tauri/src/operations/signatures/sign.rs +++ b/nym-wallet/src-tauri/src/operations/signatures/sign.rs @@ -4,6 +4,7 @@ use cosmrs::crypto::secp256k1::{Signature, VerifyingKey}; use cosmrs::crypto::PublicKey; use cosmrs::AccountId; use k256::ecdsa::signature::Verifier; +use nym_validator_client::nyxd::CosmWasmClient; use nym_validator_client::signing::signer::OfflineSigner; use serde::Serialize; use serde_json::json; @@ -23,15 +24,16 @@ pub async fn sign( ) -> Result { let guard = state.read().await; let client = guard.current_client()?; - let wallet = client.nyxd.signer(); - let derived_accounts = wallet.try_derive_accounts()?; + let derived_accounts = client.nyxd.get_accounts()?; let account = derived_accounts.first().ok_or_else(|| { log::error!(">>> Unable to derive account"); BackendError::SignatureError("unable to derive account".to_string()) })?; log::info!("<<< Signing message"); - let signature = wallet.sign_raw_with_account(account, message.as_bytes())?; + let signature = client + .nyxd + .sign_raw_with_account(account, message.as_bytes())?; let output = SignatureOutputJson { account_id: account.address().to_string(), public_key: account.public_key(), @@ -49,14 +51,10 @@ async fn get_pubkey_from_account_address( log::info!("Getting public key for address {} from chain...", address); let guard = state.read().await; let client = guard.current_client()?; - let account = client - .nyxd - .get_account_details(address) - .await? - .ok_or_else(|| { - log::error!("No account associated with address {}", address); - BackendError::SignatureError(format!("No account associated with address {address}")) - })?; + let account = client.nyxd.get_account(address).await?.ok_or_else(|| { + log::error!("No account associated with address {}", address); + BackendError::SignatureError(format!("No account associated with address {address}")) + })?; let base_account = account.try_get_base_account()?; base_account.pubkey.ok_or_else(|| { @@ -116,7 +114,7 @@ pub async fn verify( // get public key from current account address let guard = state.read().await; let client = guard.current_client()?; - let address = client.nyxd.address(); + let address = &client.nyxd.address(); get_pubkey_from_account_address(address, &state).await? } }; diff --git a/nym-wallet/src-tauri/src/operations/simulate/admin.rs b/nym-wallet/src-tauri/src/operations/simulate/admin.rs index f47b44e454..1884c7472e 100644 --- a/nym-wallet/src-tauri/src/operations/simulate/admin.rs +++ b/nym-wallet/src-tauri/src/operations/simulate/admin.rs @@ -5,6 +5,7 @@ use crate::error::BackendError; use crate::operations::simulate::FeeDetails; use crate::WalletState; use nym_mixnet_contract_common::{ContractStateParams, ExecuteMsg}; +use nym_validator_client::nyxd::contract_traits::NymContractsProvider; use nym_wallet_types::admin::TauriContractStateParams; #[tauri::command] @@ -18,7 +19,10 @@ pub async fn simulate_update_contract_settings( params.try_convert_to_mixnet_contract_params(reg)?; let client = guard.current_client()?; - let mixnet_contract = client.nyxd.mixnet_contract_address(); + let mixnet_contract = client + .nyxd + .mixnet_contract_address() + .expect("mixnet contract address is not available"); let msg = client.nyxd.wrap_contract_execute_message( mixnet_contract, diff --git a/nym-wallet/src-tauri/src/operations/simulate/mixnet.rs b/nym-wallet/src-tauri/src/operations/simulate/mixnet.rs index 332f0eeb43..11d360ef71 100644 --- a/nym-wallet/src-tauri/src/operations/simulate/mixnet.rs +++ b/nym-wallet/src-tauri/src/operations/simulate/mixnet.rs @@ -11,6 +11,7 @@ use nym_mixnet_contract_common::{ExecuteMsg, Gateway, MixId, MixNode}; use nym_mixnet_contract_common::{GatewayConfigUpdate, MixNodeConfigUpdate}; use nym_types::currency::DecCoin; use nym_types::mixnode::MixNodeCostParams; +use nym_validator_client::nyxd::contract_traits::NymContractsProvider; async fn simulate_mixnet_operation( msg: ExecuteMsg, @@ -28,7 +29,10 @@ async fn simulate_mixnet_operation( }; let client = guard.current_client()?; - let mixnet_contract = client.nyxd.mixnet_contract_address(); + let mixnet_contract = client + .nyxd + .mixnet_contract_address() + .expect("mixnet contract address is not available"); let msg = client .nyxd diff --git a/nym-wallet/src-tauri/src/operations/simulate/vesting.rs b/nym-wallet/src-tauri/src/operations/simulate/vesting.rs index 79e40ec792..b225aa9ff3 100644 --- a/nym-wallet/src-tauri/src/operations/simulate/vesting.rs +++ b/nym-wallet/src-tauri/src/operations/simulate/vesting.rs @@ -11,6 +11,7 @@ use nym_mixnet_contract_common::{Gateway, MixId, MixNode}; use nym_mixnet_contract_common::{GatewayConfigUpdate, MixNodeConfigUpdate}; use nym_types::currency::DecCoin; use nym_types::mixnode::MixNodeCostParams; +use nym_validator_client::nyxd::contract_traits::NymContractsProvider; use nym_vesting_contract_common::ExecuteMsg; async fn simulate_vesting_operation( @@ -29,7 +30,10 @@ async fn simulate_vesting_operation( }; let client = guard.current_client()?; - let vesting_contract = client.nyxd.vesting_contract_address(); + let vesting_contract = client + .nyxd + .vesting_contract_address() + .expect("vesting contract address is not available"); let msg = client .nyxd diff --git a/nym-wallet/src-tauri/src/state.rs b/nym-wallet/src-tauri/src/state.rs index bfc2d85cb6..5fd4485e18 100644 --- a/nym-wallet/src-tauri/src/state.rs +++ b/nym-wallet/src-tauri/src/state.rs @@ -8,10 +8,8 @@ use log::warn; use nym_types::currency::{DecCoin, Denom, RegisteredCoins}; use nym_types::fees::FeeDetails; use nym_validator_client::nyxd::cosmwasm_client::types::SimulateResponse; -use nym_validator_client::nyxd::{ - AccountId as CosmosAccountId, Coin, DirectSigningNyxdClient, Fee, -}; -use nym_validator_client::Client; +use nym_validator_client::nyxd::{AccountId as CosmosAccountId, Coin, Fee, SigningCosmWasmClient}; +use nym_validator_client::DirectSigningHttpRpcValidatorClient; use nym_wallet_types::network::Network; use nym_wallet_types::network_config; use once_cell::sync::Lazy; @@ -67,7 +65,7 @@ impl WalletState { #[derive(Default)] pub struct WalletStateInner { config: config::Config, - signing_clients: HashMap>, + signing_clients: HashMap, current_network: Network, // All the accounts the we get from decrypting the wallet. We hold on to these for being able to @@ -181,7 +179,7 @@ impl WalletStateInner { // this MUST succeed as we just used it before let client = self.current_client()?; let gas_price = client.nyxd.gas_price().clone(); - let gas_adjustment = client.nyxd.gas_adjustment(); + let gas_adjustment = client.nyxd.simulated_gas_multiplier(); let res = SimulateResult::new(simulate_response.gas_info, gas_price, gas_adjustment); @@ -196,7 +194,7 @@ impl WalletStateInner { pub fn client( &self, network: Network, - ) -> Result<&Client, BackendError> { + ) -> Result<&DirectSigningHttpRpcValidatorClient, BackendError> { self.signing_clients .get(&network) .ok_or(BackendError::ClientNotInitialized) @@ -205,13 +203,13 @@ impl WalletStateInner { pub fn client_mut( &mut self, network: Network, - ) -> Result<&mut Client, BackendError> { + ) -> Result<&mut DirectSigningHttpRpcValidatorClient, BackendError> { self.signing_clients .get_mut(&network) .ok_or(BackendError::ClientNotInitialized) } - pub fn current_client(&self) -> Result<&Client, BackendError> { + pub fn current_client(&self) -> Result<&DirectSigningHttpRpcValidatorClient, BackendError> { self.signing_clients .get(&self.current_network) .ok_or(BackendError::ClientNotInitialized) @@ -220,7 +218,7 @@ impl WalletStateInner { #[allow(unused)] pub fn current_client_mut( &mut self, - ) -> Result<&mut Client, BackendError> { + ) -> Result<&mut DirectSigningHttpRpcValidatorClient, BackendError> { self.signing_clients .get_mut(&self.current_network) .ok_or(BackendError::ClientNotInitialized) @@ -240,7 +238,7 @@ impl WalletStateInner { Ok(self.config.save_to_files()?) } - pub fn add_client(&mut self, network: Network, client: Client) { + pub fn add_client(&mut self, network: Network, client: DirectSigningHttpRpcValidatorClient) { self.signing_clients.insert(network, client); } diff --git a/nym-wallet/src-tauri/src/utils.rs b/nym-wallet/src-tauri/src/utils.rs index f6fe9ab4b3..2a340cc5dd 100644 --- a/nym-wallet/src-tauri/src/utils.rs +++ b/nym-wallet/src-tauri/src/utils.rs @@ -30,7 +30,7 @@ pub fn get_env() -> AppEnv { #[tauri::command] pub async fn owns_mixnode(state: tauri::State<'_, WalletState>) -> Result { Ok(nyxd_client!(state) - .get_owned_mixnode(nyxd_client!(state).address()) + .get_owned_mixnode(&nyxd_client!(state).address()) .await? .mixnode_details .is_some()) @@ -39,7 +39,7 @@ pub async fn owns_mixnode(state: tauri::State<'_, WalletState>) -> Result) -> Result { Ok(nyxd_client!(state) - .get_owned_gateway(nyxd_client!(state).address()) + .get_owned_gateway(&nyxd_client!(state).address()) .await? .gateway .is_some()) From 15bc4ae272ae579b570ab7da8ac2312eef05585f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Tue, 1 Aug 2023 18:13:17 +0100 Subject: [PATCH 12/24] clippy --- clients/webassembly/src/lib.rs | 18 +++++++++--------- common/client-libs/validator-client/Cargo.toml | 2 -- nym-api/src/support/nyxd/mod.rs | 14 +++++++------- 3 files changed, 16 insertions(+), 18 deletions(-) diff --git a/clients/webassembly/src/lib.rs b/clients/webassembly/src/lib.rs index f8dd2d629e..af6d657940 100644 --- a/clients/webassembly/src/lib.rs +++ b/clients/webassembly/src/lib.rs @@ -3,24 +3,24 @@ use wasm_bindgen::prelude::*; -// #[cfg(target_arch = "wasm32")] +#[cfg(target_arch = "wasm32")] mod client; -// #[cfg(target_arch = "wasm32")] +#[cfg(target_arch = "wasm32")] pub mod encoded_payload_helper; -// #[cfg(target_arch = "wasm32")] +#[cfg(target_arch = "wasm32")] pub mod error; -// #[cfg(target_arch = "wasm32")] +#[cfg(target_arch = "wasm32")] pub mod gateway_selector; -// #[cfg(target_arch = "wasm32")] +#[cfg(target_arch = "wasm32")] pub mod storage; -// #[cfg(target_arch = "wasm32")] +#[cfg(target_arch = "wasm32")] pub mod tester; -// #[cfg(target_arch = "wasm32")] +#[cfg(target_arch = "wasm32")] pub mod topology; -// #[cfg(target_arch = "wasm32")] +#[cfg(target_arch = "wasm32")] pub mod validation; -// #[cfg(target_arch = "wasm32")] +#[cfg(target_arch = "wasm32")] mod helpers; mod constants; diff --git a/common/client-libs/validator-client/Cargo.toml b/common/client-libs/validator-client/Cargo.toml index 58b4d8b581..96fb9f37cc 100644 --- a/common/client-libs/validator-client/Cargo.toml +++ b/common/client-libs/validator-client/Cargo.toml @@ -35,11 +35,9 @@ nym-network-defaults = { path = "../../network-defaults" } nym-api-requests = { path = "../../../nym-api/nym-api-requests" } async-trait = { workspace = true } -#bip39 = { workspace = true, features = ["rand"], optional = true } bip39 = { workspace = true, features = ["rand"] } nym-config = { path = "../../config" } cosmrs = { workspace = true, features = ["bip32", "cosmwasm"] } -#cosmrs = { workspace = true, features = ["bip32", "rpc", "cosmwasm"], optional = true } # note that this has the same version as used by cosmrs # import it just for the `Client` trait diff --git a/nym-api/src/support/nyxd/mod.rs b/nym-api/src/support/nyxd/mod.rs index ec0359c31b..a5f46893c1 100644 --- a/nym-api/src/support/nyxd/mod.rs +++ b/nym-api/src/support/nyxd/mod.rs @@ -106,7 +106,7 @@ impl Client { cosmwasm_addr .clone() .parse() - .map_err(|_| NyxdError::MalformedAccountAddress(cosmwasm_addr).into()) + .map_err(|_| NyxdError::MalformedAccountAddress(cosmwasm_addr)) } // a helper function for the future to obtain the current block timestamp @@ -145,17 +145,17 @@ impl Client { } pub(crate) async fn get_current_interval(&self) -> Result { - Ok(self.0.read().await.get_current_interval_details().await?) + self.0.read().await.get_current_interval_details().await } pub(crate) async fn get_current_epoch_status(&self) -> Result { - Ok(self.0.read().await.get_current_epoch_status().await?) + self.0.read().await.get_current_epoch_status().await } pub(crate) async fn get_current_rewarding_parameters( &self, ) -> Result { - Ok(self.0.read().await.get_rewarding_parameters().await?) + self.0.read().await.get_rewarding_parameters().await } pub(crate) async fn get_rewarded_set_mixnodes( @@ -179,13 +179,13 @@ impl Client { return Ok(0); } - Ok(serde_json::from_slice(&res).map_err(NyxdError::from)?) + serde_json::from_slice(&res).map_err(NyxdError::from) } pub(crate) async fn get_all_vesting_coins( &self, ) -> Result, NyxdError> { - Ok(self.0.read().await.get_all_accounts_vesting_coins().await?) + self.0.read().await.get_all_accounts_vesting_coins().await } pub(crate) async fn get_all_family_members( @@ -241,7 +241,7 @@ impl Client { guard .execute_multiple( - &mixnet_contract, + mixnet_contract, msgs, Default::default(), format!("rewarding {} mixnodes", nodes.len()), From 6bcc781a673b05b1d6b37049f9ac289f27e40ff3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Wed, 2 Aug 2023 16:58:55 +0100 Subject: [PATCH 13/24] dealing with all query clients --- Cargo.lock | 2 + clients/webassembly/Cargo.lock | 2 + .../client-libs/validator-client/Cargo.toml | 2 + .../coconut_bandwidth_query_client.rs | 43 ++- .../coconut_bandwidth_signing_client.rs | 3 +- .../nyxd/contract_traits/dkg_query_client.rs | 42 ++- .../contract_traits/dkg_signing_client.rs | 3 +- .../contract_traits/group_query_client.rs | 68 ++++- .../contract_traits/group_signing_client.rs | 3 +- .../contract_traits/mixnet_query_client.rs | 286 ++++++++++++------ .../contract_traits/mixnet_signing_client.rs | 3 +- .../src/nyxd/contract_traits/mod.rs | 28 +- .../contract_traits/multisig_query_client.rs | 37 +-- .../multisig_signing_client.rs | 3 +- .../name_service_query_client.rs | 85 ++++-- .../name_service_signing_client.rs | 3 +- .../sp_directory_query_client.rs | 55 ++-- .../sp_directory_signing_client.rs | 3 +- .../contract_traits/vesting_query_client.rs | 177 +++++++---- .../contract_traits/vesting_signing_client.rs | 3 +- nym-api/src/support/nyxd/mod.rs | 7 +- nym-connect/desktop/Cargo.lock | 2 + nym-wallet/Cargo.lock | 2 + 23 files changed, 601 insertions(+), 261 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 81db4b247a..be6ea96af0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4885,7 +4885,9 @@ dependencies = [ "colored", "cosmrs", "cosmwasm-std", + "cw-controllers", "cw-utils", + "cw2", "cw3", "cw4", "eyre", diff --git a/clients/webassembly/Cargo.lock b/clients/webassembly/Cargo.lock index eb5217315e..889a842029 100644 --- a/clients/webassembly/Cargo.lock +++ b/clients/webassembly/Cargo.lock @@ -3128,7 +3128,9 @@ dependencies = [ "colored", "cosmrs", "cosmwasm-std", + "cw-controllers", "cw-utils", + "cw2", "cw3", "cw4", "eyre", diff --git a/common/client-libs/validator-client/Cargo.toml b/common/client-libs/validator-client/Cargo.toml index 96fb9f37cc..052a625943 100644 --- a/common/client-libs/validator-client/Cargo.toml +++ b/common/client-libs/validator-client/Cargo.toml @@ -45,8 +45,10 @@ tendermint-rpc = { workspace = true } eyre = { version = "0.6" } cw-utils = { workspace = true } +cw2 = { workspace = true } cw3 = { workspace = true } cw4 = { workspace = true } +cw-controllers = { workspace = true } prost = { version = "0.11", default-features = false } flate2 = { version = "1.0.20" } sha2 = { version = "0.9.5" } diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/coconut_bandwidth_query_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/coconut_bandwidth_query_client.rs index b48ab83e94..e26863fbe9 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/coconut_bandwidth_query_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/coconut_bandwidth_query_client.rs @@ -1,12 +1,15 @@ // Copyright 2022-2023 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 +use crate::collect_paged; use crate::nyxd::contract_traits::NymContractsProvider; use crate::nyxd::error::NyxdError; use crate::nyxd::CosmWasmClient; use async_trait::async_trait; use nym_coconut_bandwidth_contract_common::msg::QueryMsg as CoconutBandwidthQueryMsg; -use nym_coconut_bandwidth_contract_common::spend_credential::SpendCredentialResponse; +use nym_coconut_bandwidth_contract_common::spend_credential::{ + PagedSpendCredentialResponse, SpendCredential, SpendCredentialResponse, +}; use serde::Deserialize; #[async_trait] @@ -27,8 +30,30 @@ pub trait CoconutBandwidthQueryClient { }) .await } + + async fn get_all_spent_credential_paged( + &self, + start_after: Option, + limit: Option, + ) -> Result { + self.query_coconut_bandwidth_contract(CoconutBandwidthQueryMsg::GetAllSpentCredentials { + limit, + start_after, + }) + .await + } } +#[async_trait] +pub trait PagedCoconutBandwidthQueryClient: CoconutBandwidthQueryClient { + async fn get_all_spent_credentials(&self) -> Result, NyxdError> { + collect_paged!(self, get_all_spent_credential_paged, spend_credentials) + } +} + +#[async_trait] +impl PagedCoconutBandwidthQueryClient for T where T: CoconutBandwidthQueryClient {} + #[async_trait] impl CoconutBandwidthQueryClient for C where @@ -52,13 +77,21 @@ where #[cfg(test)] mod tests { use super::*; + use crate::nyxd::contract_traits::tests::IgnoreValue; - // it's enough that this compiles - #[deprecated] - async fn all_query_variants_are_covered( + // it's enough that this compiles and clippy is happy about it + #[allow(dead_code)] + fn all_query_variants_are_covered( client: C, msg: CoconutBandwidthQueryMsg, ) { - unimplemented!() + match msg { + CoconutBandwidthQueryMsg::GetSpentCredential { + blinded_serial_number, + } => client.get_spent_credential(blinded_serial_number).ignore(), + CoconutBandwidthQueryMsg::GetAllSpentCredentials { limit, start_after } => client + .get_all_spent_credential_paged(start_after, limit) + .ignore(), + }; } } diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/coconut_bandwidth_signing_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/coconut_bandwidth_signing_client.rs index edf2ac176f..1711c34621 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/coconut_bandwidth_signing_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/coconut_bandwidth_signing_client.rs @@ -102,8 +102,7 @@ where mod tests { use super::*; - // it's enough that this compiles - #[deprecated] + // it's enough that this compiles and clippy is happy about it async fn all_execute_variants_are_covered( client: C, msg: CoconutBandwidthExecuteMsg, 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 7acc1e4041..2a569127e3 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 @@ -65,12 +65,12 @@ pub trait DkgQueryClient { async fn get_dealings_paged( &self, - idx: usize, + idx: u64, start_after: Option, limit: Option, ) -> Result { let request = DkgQueryMsg::GetDealing { - idx: idx as u64, + idx, limit, start_after, }; @@ -104,7 +104,7 @@ pub trait PagedDkgQueryClient: DkgQueryClient { collect_paged!(self, get_past_dealers_paged, dealers) } - async fn get_all_epoch_dealings(&self, idx: usize) -> Result, NyxdError> { + async fn get_all_epoch_dealings(&self, idx: u64) -> Result, NyxdError> { collect_paged!(self, get_dealings_paged, dealings, idx) } @@ -139,13 +139,41 @@ where #[cfg(test)] mod tests { use super::*; + use crate::nyxd::contract_traits::tests::IgnoreValue; - // it's enough that this compiles - #[deprecated] - async fn all_query_variants_are_covered( + // it's enough that this compiles and clippy is happy about it + #[allow(dead_code)] + fn all_query_variants_are_covered( client: C, msg: DkgQueryMsg, ) { - unimplemented!() + match msg { + DkgQueryMsg::GetCurrentEpochState {} => client.get_current_epoch().ignore(), + DkgQueryMsg::GetCurrentEpochThreshold {} => { + client.get_current_epoch_threshold().ignore() + } + DkgQueryMsg::GetInitialDealers {} => client.get_initial_dealers().ignore(), + DkgQueryMsg::GetDealerDetails { dealer_address } => client + .get_dealer_details(&dealer_address.parse().unwrap()) + .ignore(), + DkgQueryMsg::GetCurrentDealers { limit, start_after } => client + .get_current_dealers_paged(start_after, limit) + .ignore(), + DkgQueryMsg::GetPastDealers { limit, start_after } => { + client.get_past_dealers_paged(start_after, limit).ignore() + } + DkgQueryMsg::GetDealing { + idx, + limit, + start_after, + } => client.get_dealings_paged(idx, start_after, limit).ignore(), + DkgQueryMsg::GetVerificationKeys { + epoch_id, + limit, + start_after, + } => client + .get_vk_shares_paged(epoch_id, start_after, limit) + .ignore(), + }; } } diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/dkg_signing_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/dkg_signing_client.rs index a0fac3a036..5b28ea7d8e 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/dkg_signing_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/dkg_signing_client.rs @@ -108,8 +108,7 @@ where mod tests { use super::*; - // it's enough that this compiles - #[deprecated] + // it's enough that this compiles and clippy is happy about it async fn all_execute_variants_are_covered( client: C, msg: DkgExecuteMsg, diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/group_query_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/group_query_client.rs index 3bc5bcabef..580f1ccefd 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/group_query_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/group_query_client.rs @@ -5,7 +5,7 @@ use crate::nyxd::contract_traits::NymContractsProvider; use crate::nyxd::error::NyxdError; use crate::nyxd::CosmWasmClient; use async_trait::async_trait; -use cw4::MemberResponse; +use cw4::{Member, MemberListResponse, MemberResponse, TotalWeightResponse}; use nym_group_contract_common::msg::QueryMsg as GroupQueryMsg; use serde::Deserialize; @@ -15,6 +15,24 @@ pub trait GroupQueryClient { where for<'a> T: Deserialize<'a>; + async fn admin(&self) -> Result { + self.query_group_contract(GroupQueryMsg::Admin {}).await + } + + async fn total_weight(&self, at_height: Option) -> Result { + self.query_group_contract(GroupQueryMsg::TotalWeight { at_height }) + .await + } + + async fn list_members_paged( + &self, + start_after: Option, + limit: Option, + ) -> Result { + self.query_group_contract(GroupQueryMsg::ListMembers { start_after, limit }) + .await + } + async fn member( &self, addr: String, @@ -23,8 +41,39 @@ pub trait GroupQueryClient { self.query_group_contract(GroupQueryMsg::Member { addr, at_height }) .await } + + async fn hooks(&self) -> Result { + self.query_group_contract(GroupQueryMsg::Hooks {}).await + } } +#[async_trait] +pub trait PagedGroupQueryClient: GroupQueryClient { + // can't use the macro due to different paging behaviour + async fn get_all_members(&self) -> Result, NyxdError> { + let mut members = Vec::new(); + let mut start_after = None; + + loop { + let mut paged_response = self.list_members_paged(start_after.take(), None).await?; + + let last_id = paged_response.members.last().map(|mem| mem.addr.clone()); + members.append(&mut paged_response.members); + + if let Some(start_after_res) = last_id { + start_after = Some(start_after_res) + } else { + break; + } + } + + Ok(members) + } +} + +#[async_trait] +impl PagedGroupQueryClient for T where T: GroupQueryClient {} + #[async_trait] impl GroupQueryClient for C where @@ -45,13 +94,22 @@ where #[cfg(test)] mod tests { use super::*; + use crate::nyxd::contract_traits::tests::IgnoreValue; - // it's enough that this compiles - #[deprecated] - async fn all_query_variants_are_covered( + // it's enough that this compiles and clippy is happy about it + #[allow(dead_code)] + fn all_query_variants_are_covered( client: C, msg: GroupQueryMsg, ) { - unimplemented!() + match msg { + GroupQueryMsg::Admin {} => client.admin().ignore(), + GroupQueryMsg::TotalWeight { at_height } => client.total_weight(at_height).ignore(), + GroupQueryMsg::ListMembers { start_after, limit } => { + client.list_members_paged(start_after, limit).ignore() + } + GroupQueryMsg::Member { addr, at_height } => client.member(addr, at_height).ignore(), + GroupQueryMsg::Hooks {} => client.hooks().ignore(), + }; } } diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/group_signing_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/group_signing_client.rs index e17de6ed08..af05635430 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/group_signing_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/group_signing_client.rs @@ -56,8 +56,7 @@ where mod tests { use super::*; - // it's enough that this compiles - #[deprecated] + // it's enough that this compiles and clippy is happy about it async fn all_execute_variants_are_covered( client: C, msg: GroupExecuteMsg, diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/mixnet_query_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/mixnet_query_client.rs index b3f2e77142..e38c7e0eb5 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/mixnet_query_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/mixnet_query_client.rs @@ -33,6 +33,7 @@ use nym_mixnet_contract_common::{ RewardedSetNodeStatus, UnbondedMixnode, }; use serde::Deserialize; +use std::collections::HashSet; #[async_trait] pub trait MixnetQueryClient { @@ -47,6 +48,11 @@ pub trait MixnetQueryClient { .await } + async fn get_mixnet_contract_cw2_version(&self) -> Result { + self.query_mixnet_contract(MixnetQueryMsg::GetCW2ContractVersion {}) + .await + } + async fn get_rewarding_validator_address(&self) -> Result { self.query_mixnet_contract(MixnetQueryMsg::GetRewardingValidatorAddress {}) .await @@ -452,6 +458,20 @@ pub trait MixnetQueryClient { self.query_mixnet_contract(MixnetQueryMsg::GetFamilyByHead { head }) .await } + + // TODO: make sure the type matches after https://github.com/nymtech/nym/pull/3693 is merged + async fn get_family_members_by_head(&self, head: String) -> Result, NyxdError> { + self.query_mixnet_contract(MixnetQueryMsg::GetFamilyMembersByHead { head }) + .await + } + + async fn get_family_members_by_label( + &self, + label: String, + ) -> Result, NyxdError> { + self.query_mixnet_contract(MixnetQueryMsg::GetFamilyMembersByLabel { label }) + .await + } } // extension trait to the query client to deal with the paged queries @@ -559,107 +579,175 @@ where #[cfg(test)] mod tests { use super::*; + use crate::nyxd::contract_traits::tests::IgnoreValue; - // it's enough that this compiles - #[deprecated] - async fn all_query_variants_are_covered( + // it's enough that this compiles and clippy is happy about it + #[allow(dead_code)] + fn all_query_variants_are_covered( client: C, msg: MixnetQueryMsg, - ) { - todo!() - // match msg { - // MixnetQueryMsg::GetAllFamiliesPaged { limit, start_after } => client - // .get_all_family_members_paged(limit, start_after) - // .await - // .map(|_| ()), - // MixnetQueryMsg::GetAllMembersPaged { limit, start_after } => client - // .get_all_family_members_paged(limit, start_after) - // .await - // .map(|_| ()), - // MixnetQueryMsg::GetFamilyByHead { head } => { - // client.get_node_family_by_head(head).await.map(|_| ()) - // } - // MixnetQueryMsg::GetFamilyByLabel { label } => { - // client.get_node_family_by_label(label).await.map(|_| ()) - // } - // MixnetQueryMsg::GetFamilyMembersByHead { head } => todo!(), - // MixnetQueryMsg::GetFamilyMembersByLabel { label } => todo!(), - // MixnetQueryMsg::GetContractVersion {} => { - // client.get_mixnet_contract_version().await.map(|_| ()) - // } - // MixnetQueryMsg::GetCW2ContractVersion {} => todo!(), - // MixnetQueryMsg::GetRewardingValidatorAddress {} => { - // client.get_rewarding_validator_address().await.map(|_| ()) - // } - // MixnetQueryMsg::GetStateParams {} => todo!(), - // MixnetQueryMsg::GetState {} => client.get_mixnet_contract_state().await.map(|_| ()), - // MixnetQueryMsg::GetRewardingParams {} => {} - // MixnetQueryMsg::GetEpochStatus {} => {} - // MixnetQueryMsg::GetCurrentIntervalDetails {} => {} - // MixnetQueryMsg::GetRewardedSet { limit, start_after } => {} - // MixnetQueryMsg::GetMixNodeBonds { limit, start_after } => {} - // MixnetQueryMsg::GetMixNodesDetailed { limit, start_after } => {} - // MixnetQueryMsg::GetUnbondedMixNodes { limit, start_after } => {} - // MixnetQueryMsg::GetUnbondedMixNodesByOwner { - // owner, - // limit, - // start_after, - // } => {} - // MixnetQueryMsg::GetUnbondedMixNodesByIdentityKey { - // identity_key, - // limit, - // start_after, - // } => {} - // MixnetQueryMsg::GetOwnedMixnode { address } => {} - // MixnetQueryMsg::GetMixnodeDetails { mix_id } => {} - // MixnetQueryMsg::GetMixnodeRewardingDetails { mix_id } => {} - // MixnetQueryMsg::GetStakeSaturation { mix_id } => {} - // MixnetQueryMsg::GetUnbondedMixNodeInformation { mix_id } => {} - // MixnetQueryMsg::GetBondedMixnodeDetailsByIdentity { mix_identity } => {} - // MixnetQueryMsg::GetLayerDistribution {} => {} - // MixnetQueryMsg::GetGateways { start_after, limit } => {} - // MixnetQueryMsg::GetGatewayBond { identity } => {} - // MixnetQueryMsg::GetOwnedGateway { address } => {} - // MixnetQueryMsg::GetMixnodeDelegations { - // mix_id, - // start_after, - // limit, - // } => {} - // MixnetQueryMsg::GetDelegatorDelegations { - // delegator, - // start_after, - // limit, - // } => {} - // MixnetQueryMsg::GetDelegationDetails { - // mix_id, - // delegator, - // proxy, - // } => {} - // MixnetQueryMsg::GetAllDelegations { start_after, limit } => {} - // MixnetQueryMsg::GetPendingOperatorReward { address } => {} - // MixnetQueryMsg::GetPendingMixNodeOperatorReward { mix_id } => {} - // MixnetQueryMsg::GetPendingDelegatorReward { - // address, - // mix_id, - // proxy, - // } => {} - // MixnetQueryMsg::GetEstimatedCurrentEpochOperatorReward { - // mix_id, - // estimated_performance, - // } => {} - // MixnetQueryMsg::GetEstimatedCurrentEpochDelegatorReward { - // address, - // mix_id, - // proxy, - // estimated_performance, - // } => {} - // MixnetQueryMsg::GetPendingEpochEvents { limit, start_after } => {} - // MixnetQueryMsg::GetPendingIntervalEvents { limit, start_after } => {} - // MixnetQueryMsg::GetPendingEpochEvent { event_id } => {} - // MixnetQueryMsg::GetPendingIntervalEvent { event_id } => {} - // MixnetQueryMsg::GetNumberOfPendingEvents {} => {} - // MixnetQueryMsg::GetSigningNonce { address } => {} - // } - // .expect("ignore error") + ) -> u32 { + match msg { + MixnetQueryMsg::GetAllFamiliesPaged { limit, start_after } => client + .get_all_family_members_paged(start_after, limit) + .ignore(), + MixnetQueryMsg::GetAllMembersPaged { limit, start_after } => client + .get_all_family_members_paged(start_after, limit) + .ignore(), + MixnetQueryMsg::GetFamilyByHead { head } => { + client.get_node_family_by_head(head).ignore() + } + MixnetQueryMsg::GetFamilyByLabel { label } => { + client.get_node_family_by_label(label).ignore() + } + MixnetQueryMsg::GetFamilyMembersByHead { head } => { + client.get_family_members_by_head(head).ignore() + } + MixnetQueryMsg::GetFamilyMembersByLabel { label } => { + client.get_family_members_by_label(label).ignore() + } + MixnetQueryMsg::GetContractVersion {} => client.get_mixnet_contract_version().ignore(), + MixnetQueryMsg::GetCW2ContractVersion {} => { + client.get_mixnet_contract_cw2_version().ignore() + } + MixnetQueryMsg::GetRewardingValidatorAddress {} => { + client.get_rewarding_validator_address().ignore() + } + MixnetQueryMsg::GetStateParams {} => {} + MixnetQueryMsg::GetState {} => client.get_mixnet_contract_state().ignore(), + MixnetQueryMsg::GetRewardingParams {} => client.get_rewarding_parameters().ignore(), + MixnetQueryMsg::GetEpochStatus {} => client.get_current_epoch_status().ignore(), + MixnetQueryMsg::GetCurrentIntervalDetails {} => { + client.get_current_interval_details().ignore() + } + MixnetQueryMsg::GetRewardedSet { limit, start_after } => { + client.get_rewarded_set_paged(start_after, limit).ignore() + } + MixnetQueryMsg::GetMixNodeBonds { limit, start_after } => { + client.get_mixnode_bonds_paged(start_after, limit).ignore() + } + MixnetQueryMsg::GetMixNodesDetailed { limit, start_after } => client + .get_mixnodes_detailed_paged(start_after, limit) + .ignore(), + MixnetQueryMsg::GetUnbondedMixNodes { limit, start_after } => { + client.get_unbonded_paged(start_after, limit).ignore() + } + MixnetQueryMsg::GetUnbondedMixNodesByOwner { + owner, + limit, + start_after, + } => client + .get_unbonded_by_owner_paged(&owner.parse().unwrap(), start_after, limit) + .ignore(), + MixnetQueryMsg::GetUnbondedMixNodesByIdentityKey { + identity_key, + limit, + start_after, + } => client + .get_unbonded_by_identity_paged(&identity_key, start_after, limit) + .ignore(), + MixnetQueryMsg::GetOwnedMixnode { address } => { + client.get_owned_mixnode(&address.parse().unwrap()).ignore() + } + MixnetQueryMsg::GetMixnodeDetails { mix_id } => { + client.get_mixnode_details(mix_id).ignore() + } + MixnetQueryMsg::GetMixnodeRewardingDetails { mix_id } => { + client.get_mixnode_rewarding_details(mix_id).ignore() + } + MixnetQueryMsg::GetStakeSaturation { mix_id } => { + client.get_mixnode_stake_saturation(mix_id).ignore() + } + MixnetQueryMsg::GetUnbondedMixNodeInformation { mix_id } => { + client.get_unbonded_mixnode_information(mix_id).ignore() + } + MixnetQueryMsg::GetBondedMixnodeDetailsByIdentity { mix_identity } => client + .get_mixnode_details_by_identity(mix_identity) + .ignore(), + MixnetQueryMsg::GetLayerDistribution {} => client.get_layer_distribution().ignore(), + MixnetQueryMsg::GetGateways { start_after, limit } => { + client.get_gateways_paged(start_after, limit).ignore() + } + MixnetQueryMsg::GetGatewayBond { identity } => { + client.get_gateway_bond(identity).ignore() + } + MixnetQueryMsg::GetOwnedGateway { address } => { + client.get_owned_gateway(&address.parse().unwrap()).ignore() + } + MixnetQueryMsg::GetMixnodeDelegations { + mix_id, + start_after, + limit, + } => client + .get_mixnode_delegations_paged(mix_id, start_after, limit) + .ignore(), + MixnetQueryMsg::GetDelegatorDelegations { + delegator, + start_after, + limit, + } => client + .get_delegator_delegations_paged(&delegator.parse().unwrap(), start_after, limit) + .ignore(), + MixnetQueryMsg::GetDelegationDetails { + mix_id, + delegator, + proxy, + } => client + .get_delegation_details(mix_id, &delegator.parse().unwrap(), proxy) + .ignore(), + MixnetQueryMsg::GetAllDelegations { start_after, limit } => client + .get_all_network_delegations_paged(start_after, limit) + .ignore(), + MixnetQueryMsg::GetPendingOperatorReward { address } => client + .get_pending_operator_reward(&address.parse().unwrap()) + .ignore(), + MixnetQueryMsg::GetPendingMixNodeOperatorReward { mix_id } => { + client.get_pending_mixnode_operator_reward(mix_id).ignore() + } + MixnetQueryMsg::GetPendingDelegatorReward { + address, + mix_id, + proxy, + } => client + .get_pending_delegator_reward(&address.parse().unwrap(), mix_id, proxy) + .ignore(), + MixnetQueryMsg::GetEstimatedCurrentEpochOperatorReward { + mix_id, + estimated_performance, + } => client + .get_estimated_current_epoch_operator_reward(mix_id, estimated_performance) + .ignore(), + MixnetQueryMsg::GetEstimatedCurrentEpochDelegatorReward { + address, + mix_id, + proxy, + estimated_performance, + } => client + .get_estimated_current_epoch_delegator_reward( + &address.parse().unwrap(), + mix_id, + proxy, + estimated_performance, + ) + .ignore(), + MixnetQueryMsg::GetPendingEpochEvents { limit, start_after } => client + .get_pending_epoch_events_paged(start_after, limit) + .ignore(), + MixnetQueryMsg::GetPendingIntervalEvents { limit, start_after } => client + .get_pending_interval_events_paged(start_after, limit) + .ignore(), + MixnetQueryMsg::GetPendingEpochEvent { event_id } => { + client.get_pending_epoch_event(event_id).ignore() + } + MixnetQueryMsg::GetPendingIntervalEvent { event_id } => { + client.get_pending_interval_event(event_id).ignore() + } + MixnetQueryMsg::GetNumberOfPendingEvents {} => { + client.get_number_of_pending_events().ignore() + } + MixnetQueryMsg::GetSigningNonce { address } => { + client.get_signing_nonce(&address.parse().unwrap()).ignore() + } + } } } diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/mixnet_signing_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/mixnet_signing_client.rs index cc5e12e7e8..de5923a5a1 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/mixnet_signing_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/mixnet_signing_client.rs @@ -704,8 +704,7 @@ where mod tests { use super::*; - // it's enough that this compiles - #[deprecated] + // it's enough that this compiles and clippy is happy about it async fn all_execute_variants_are_covered( client: C, msg: MixnetExecuteMsg, diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/mod.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/mod.rs index b2e4d44405..8292136bb8 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/mod.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/mod.rs @@ -28,14 +28,16 @@ mod sp_directory_signing_client; mod vesting_signing_client; // re-export query traits -pub use coconut_bandwidth_query_client::CoconutBandwidthQueryClient; +pub use coconut_bandwidth_query_client::{ + CoconutBandwidthQueryClient, PagedCoconutBandwidthQueryClient, +}; pub use dkg_query_client::{DkgQueryClient, PagedDkgQueryClient}; -pub use group_query_client::GroupQueryClient; +pub use group_query_client::{GroupQueryClient, PagedGroupQueryClient}; pub use mixnet_query_client::{MixnetQueryClient, PagedMixnetQueryClient}; pub use multisig_query_client::{MultisigQueryClient, PagedMultisigQueryClient}; -pub use name_service_query_client::NameServiceQueryClient; -pub use sp_directory_query_client::SpDirectoryQueryClient; -pub use vesting_query_client::VestingQueryClient; +pub use name_service_query_client::{NameServiceQueryClient, PagedNameServiceQueryClient}; +pub use sp_directory_query_client::{PagedSpDirectoryQueryClient, SpDirectoryQueryClient}; +pub use vesting_query_client::{PagedVestingQueryClient, VestingQueryClient}; // re-export signing traits pub use coconut_bandwidth_signing_client::CoconutBandwidthSigningClient; @@ -153,3 +155,19 @@ macro_rules! collect_paged { } }}; } + +#[cfg(test)] +mod tests { + pub(crate) trait IgnoreValue { + fn ignore(self) -> u32 + where + Self: Sized, + { + 42 + // reason we're returning a value as opposed to just `()` is that whenever we match on all enums + // we don't want to accidentally miss a variant because compiler will treat it the same way + } + } + + impl IgnoreValue for T {} +} diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/multisig_query_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/multisig_query_client.rs index b2aa0154c5..b7d180f4a1 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/multisig_query_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/multisig_query_client.rs @@ -83,10 +83,8 @@ pub trait MultisigQueryClient { .await } - // technically it's not deprecated, just not implemented, but I need clippy to point it out to me before I make a PR - #[deprecated] async fn query_config(&self) -> Result<(), NyxdError> { - unimplemented!() + unimplemented!("requires exporting state::Config type") } } @@ -139,44 +137,39 @@ where #[cfg(test)] mod tests { use super::*; + use crate::nyxd::contract_traits::tests::IgnoreValue; - // it's enough that this compiles - async fn all_query_variants_are_covered( + // it's enough that this compiles and clippy is happy about it + #[allow(dead_code)] + fn all_query_variants_are_covered( client: C, msg: MultisigQueryMsg, ) { match msg { - MultisigQueryMsg::Threshold {} => client.query_threshold().await.map(|_| ()), + MultisigQueryMsg::Threshold {} => client.query_threshold().ignore(), MultisigQueryMsg::Proposal { proposal_id } => { - client.query_proposal(proposal_id).await.map(|_| ()) + client.query_proposal(proposal_id).ignore() } MultisigQueryMsg::ListProposals { start_after, limit } => { - client.list_proposals(start_after, limit).await.map(|_| ()) + client.list_proposals(start_after, limit).ignore() } MultisigQueryMsg::ReverseProposals { start_before, limit, - } => client - .reverse_proposals(start_before, limit) - .await - .map(|_| ()), + } => client.reverse_proposals(start_before, limit).ignore(), MultisigQueryMsg::Vote { proposal_id, voter } => { - client.query_vote(proposal_id, voter).await.map(|_| ()) + client.query_vote(proposal_id, voter).ignore() } MultisigQueryMsg::ListVotes { proposal_id, start_after, limit, - } => client - .list_votes(proposal_id, start_after, limit) - .await - .map(|_| ()), - MultisigQueryMsg::Voter { address } => client.query_voter(address).await.map(|_| ()), + } => client.list_votes(proposal_id, start_after, limit).ignore(), + MultisigQueryMsg::Voter { address } => client.query_voter(address).ignore(), MultisigQueryMsg::ListVoters { start_after, limit } => { - client.list_voters(start_after, limit).await.map(|_| ()) + client.list_voters(start_after, limit).ignore() } - MultisigQueryMsg::Config {} => client.query_config().await.map(|_| ()), - } - .expect("ignore error") + MultisigQueryMsg::Config {} => client.query_config().ignore(), + }; } } diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/multisig_signing_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/multisig_signing_client.rs index b19f5de10c..9e6c2948db 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/multisig_signing_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/multisig_signing_client.rs @@ -115,8 +115,7 @@ where mod tests { use super::*; - // it's enough that this compiles - #[deprecated] + // it's enough that this compiles and clippy is happy about it async fn all_execute_variants_are_covered( client: C, msg: MultisigExecuteMsg, diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/name_service_query_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/name_service_query_client.rs index 4f53fa52dc..d5a65b8e66 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/name_service_query_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/name_service_query_client.rs @@ -1,6 +1,7 @@ // Copyright 2023 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 +use crate::collect_paged; use crate::nyxd::contract_traits::NymContractsProvider; use crate::nyxd::{error::NyxdError, CosmWasmClient}; use async_trait::async_trait; @@ -9,7 +10,7 @@ use nym_contracts_common::{signing::Nonce, ContractBuildInformation}; use nym_name_service_common::{ msg::QueryMsg as NameQueryMsg, response::{ConfigResponse, NamesListResponse, PagedNamesListResponse}, - Address, NameId, RegisteredName, + Address, NameId, NymName, RegisteredName, }; use serde::Deserialize; @@ -38,6 +39,13 @@ pub trait NameServiceQueryClient { .await } + async fn get_name_signing_nonce(&self, address: &AccountId) -> Result { + self.query_name_service_contract(NameQueryMsg::SigningNonce { + address: address.to_string(), + }) + .await + } + async fn get_names_by_owner(&self, owner: AccountId) -> Result { self.query_name_service_contract(NameQueryMsg::ByOwner { owner: owner.to_string(), @@ -45,6 +53,11 @@ pub trait NameServiceQueryClient { .await } + async fn get_names_by_nym_name(&self, name: NymName) -> Result { + self.query_name_service_contract(NameQueryMsg::ByName { name }) + .await + } + async fn get_names_by_address(&self, address: Address) -> Result { self.query_name_service_contract(NameQueryMsg::ByAddress { address }) .await @@ -57,33 +70,24 @@ pub trait NameServiceQueryClient { .await } - async fn get_all_names(&self) -> Result, NyxdError> { - let mut services = Vec::new(); - let mut start_after = None; - - loop { - let mut paged_response = self.get_names_paged(start_after.take(), None).await?; - - let last_id = paged_response.names.last().map(|serv| serv.id); - services.append(&mut paged_response.names); - - if let Some(start_after_res) = last_id { - start_after = Some(start_after_res) - } else { - break; - } - } - - Ok(services) - } - - async fn get_name_signing_nonce(&self, address: &AccountId) -> Result { - self.query_name_service_contract(NameQueryMsg::SigningNonce { - address: address.to_string(), - }) - .await + async fn get_name_service_contract_cw2_version( + &self, + ) -> Result { + self.query_name_service_contract(NameQueryMsg::GetCW2ContractVersion {}) + .await } } + +#[async_trait] +pub trait PagedNameServiceQueryClient: NameServiceQueryClient { + async fn get_all_names(&self) -> Result, NyxdError> { + collect_paged!(self, get_names_paged, names) + } +} + +#[async_trait] +impl PagedNameServiceQueryClient for T where T: NameServiceQueryClient {} + #[async_trait] impl NameServiceQueryClient for C where @@ -104,13 +108,34 @@ where #[cfg(test)] mod tests { use super::*; + use crate::nyxd::contract_traits::tests::IgnoreValue; - // it's enough that this compiles - #[deprecated] - async fn all_query_variants_are_covered( + // it's enough that this compiles and clippy is happy about it + #[allow(dead_code)] + fn all_query_variants_are_covered( client: C, msg: NameQueryMsg, ) { - unimplemented!() + match msg { + NameQueryMsg::NameId { name_id } => client.get_name_entry(name_id).ignore(), + NameQueryMsg::ByOwner { owner } => { + client.get_names_by_owner(owner.parse().unwrap()).ignore() + } + NameQueryMsg::ByName { name } => client.get_names_by_nym_name(name).ignore(), + NameQueryMsg::ByAddress { address } => client.get_names_by_address(address).ignore(), + NameQueryMsg::All { limit, start_after } => { + client.get_names_paged(limit, start_after).ignore() + } + NameQueryMsg::SigningNonce { address } => client + .get_name_signing_nonce(&address.parse().unwrap()) + .ignore(), + NameQueryMsg::Config {} => client.get_name_service_config().ignore(), + NameQueryMsg::GetContractVersion {} => { + client.get_name_service_contract_version().ignore() + } + NameQueryMsg::GetCW2ContractVersion {} => { + client.get_name_service_contract_cw2_version().ignore() + } + }; } } diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/name_service_signing_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/name_service_signing_client.rs index 63dde6dd0d..27ff60c99a 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/name_service_signing_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/name_service_signing_client.rs @@ -108,8 +108,7 @@ where mod tests { use super::*; - // it's enough that this compiles - #[deprecated] + // it's enough that this compiles and clippy is happy about it async fn all_execute_variants_are_covered( client: C, msg: NameExecuteMsg, diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/sp_directory_query_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/sp_directory_query_client.rs index f246fc7f18..47a56f9080 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/sp_directory_query_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/sp_directory_query_client.rs @@ -1,3 +1,4 @@ +use crate::collect_paged; use async_trait::async_trait; use cosmrs::AccountId; use nym_contracts_common::{signing::Nonce, ContractBuildInformation}; @@ -64,21 +65,9 @@ pub trait SpDirectoryQueryClient { .await } - async fn get_all_services(&self) -> Result, NyxdError> { - let mut services = Vec::new(); - let mut start_after = None; - loop { - let mut paged_response = self.get_services_paged(start_after.take(), None).await?; - services.append(&mut paged_response.services); - - if let Some(start_after_res) = paged_response.start_next_after { - start_after = Some(start_after_res) - } else { - break; - } - } - - Ok(services) + async fn get_sp_contract_cw2_version(&self) -> Result { + self.query_service_provider_contract(SpQueryMsg::GetCW2ContractVersion {}) + .await } async fn get_service_signing_nonce(&self, address: &AccountId) -> Result { @@ -89,6 +78,16 @@ pub trait SpDirectoryQueryClient { } } +#[async_trait] +pub trait PagedSpDirectoryQueryClient: SpDirectoryQueryClient { + async fn get_all_services(&self) -> Result, NyxdError> { + collect_paged!(self, get_services_paged, services) + } +} + +#[async_trait] +impl PagedSpDirectoryQueryClient for T where T: SpDirectoryQueryClient {} + #[async_trait] impl SpDirectoryQueryClient for C where @@ -110,13 +109,31 @@ where #[cfg(test)] mod tests { use super::*; + use crate::nyxd::contract_traits::tests::IgnoreValue; - // it's enough that this compiles - #[deprecated] - async fn all_query_variants_are_covered( + // it's enough that this compiles and clippy is happy about it + #[allow(dead_code)] + fn all_query_variants_are_covered( client: C, msg: SpQueryMsg, ) { - unimplemented!() + match msg { + SpQueryMsg::ServiceId { service_id } => client.get_service_info(service_id).ignore(), + SpQueryMsg::ByAnnouncer { announcer } => client + .get_services_by_announcer(announcer.parse().unwrap()) + .ignore(), + SpQueryMsg::ByNymAddress { nym_address } => { + client.get_services_by_nym_address(nym_address).ignore() + } + SpQueryMsg::All { limit, start_after } => { + client.get_services_paged(start_after, limit).ignore() + } + SpQueryMsg::SigningNonce { address } => client + .get_service_signing_nonce(&address.parse().unwrap()) + .ignore(), + SpQueryMsg::Config {} => client.get_service_config().ignore(), + SpQueryMsg::GetContractVersion {} => client.get_sp_contract_version().ignore(), + SpQueryMsg::GetCW2ContractVersion {} => client.get_sp_contract_cw2_version().ignore(), + }; } } diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/sp_directory_signing_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/sp_directory_signing_client.rs index 115c024d82..597847549f 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/sp_directory_signing_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/sp_directory_signing_client.rs @@ -118,8 +118,7 @@ where mod tests { use super::*; - // it's enough that this compiles - #[deprecated] + // it's enough that this compiles and clippy is happy about it async fn all_execute_variants_are_covered( client: C, msg: SpExecuteMsg, diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/vesting_query_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/vesting_query_client.rs index 6d96546c87..2a5b587f93 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/vesting_query_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/vesting_query_client.rs @@ -1,6 +1,7 @@ // Copyright 2021-2023 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 +use crate::collect_paged; use crate::nyxd::coin::Coin; use crate::nyxd::contract_traits::NymContractsProvider; use crate::nyxd::error::NyxdError; @@ -27,6 +28,11 @@ pub trait VestingQueryClient { .await } + async fn get_vesting_contract_cw2_version(&self) -> Result { + self.query_vesting_contract(VestingQueryMsg::GetCW2ContractVersion {}) + .await + } + async fn get_all_accounts_paged( &self, start_next_after: Option, @@ -274,65 +280,26 @@ pub trait VestingQueryClient { self.query_vesting_contract(VestingQueryMsg::GetAllDelegations { start_after, limit }) .await } +} +#[async_trait] +pub trait PagedVestingQueryClient: VestingQueryClient { async fn get_all_vesting_delegations(&self) -> Result, NyxdError> { - let mut delegations = Vec::new(); - let mut start_after = None; - loop { - let mut paged_response = self - .get_all_vesting_delegations_paged(start_after.take(), None) - .await?; - delegations.append(&mut paged_response.delegations); - - if let Some(start_after_res) = paged_response.start_next_after { - start_after = Some(start_after_res) - } else { - break; - } - } - - Ok(delegations) + collect_paged!(self, get_all_vesting_delegations_paged, delegations) } async fn get_all_accounts_info(&self) -> Result, NyxdError> { - let mut accounts = Vec::new(); - let mut start_after = None; - loop { - let mut paged_response = self - .get_all_accounts_paged(start_after.take(), None) - .await?; - accounts.append(&mut paged_response.accounts); - - if let Some(start_after_res) = paged_response.start_next_after { - start_after = Some(start_after_res.into_string()) - } else { - break; - } - } - - Ok(accounts) + collect_paged!(self, get_all_accounts_paged, accounts) } async fn get_all_accounts_vesting_coins(&self) -> Result, NyxdError> { - let mut accounts = Vec::new(); - let mut start_after = None; - loop { - let mut paged_response = self - .get_all_accounts_vesting_coins_paged(start_after.take(), None) - .await?; - accounts.append(&mut paged_response.accounts); - - if let Some(start_after_res) = paged_response.start_next_after { - start_after = Some(start_after_res.into_string()) - } else { - break; - } - } - - Ok(accounts) + collect_paged!(self, get_all_accounts_vesting_coins_paged, accounts) } } +#[async_trait] +impl PagedVestingQueryClient for T where T: VestingQueryClient {} + #[async_trait] impl VestingQueryClient for C where @@ -353,13 +320,119 @@ where #[cfg(test)] mod tests { use super::*; + use crate::nyxd::contract_traits::tests::IgnoreValue; - // it's enough that this compiles - #[deprecated] - async fn all_query_variants_are_covered( + // it's enough that this compiles and clippy is happy about it + #[allow(dead_code)] + fn all_query_variants_are_covered( client: C, msg: VestingQueryMsg, ) { - unimplemented!() + match msg { + VestingQueryMsg::GetContractVersion {} => { + client.get_vesting_contract_version().ignore() + } + VestingQueryMsg::GetCW2ContractVersion {} => { + client.get_vesting_contract_cw2_version().ignore() + } + VestingQueryMsg::GetAccountsPaged { + start_next_after, + limit, + } => client + .get_all_accounts_paged(start_next_after, limit) + .ignore(), + VestingQueryMsg::GetAccountsVestingCoinsPaged { + start_next_after, + limit, + } => client + .get_all_accounts_vesting_coins_paged(start_next_after, limit) + .ignore(), + VestingQueryMsg::LockedCoins { + vesting_account_address, + block_time, + } => client + .locked_coins(&vesting_account_address, block_time) + .ignore(), + VestingQueryMsg::SpendableCoins { + vesting_account_address, + block_time, + } => client + .spendable_coins(&vesting_account_address, block_time) + .ignore(), + VestingQueryMsg::GetVestedCoins { + vesting_account_address, + block_time, + } => client + .vested_coins(&vesting_account_address, block_time) + .ignore(), + VestingQueryMsg::GetVestingCoins { + vesting_account_address, + block_time, + } => client + .vesting_coins(&vesting_account_address, block_time) + .ignore(), + VestingQueryMsg::GetStartTime { + vesting_account_address, + } => client.vesting_start_time(&vesting_account_address).ignore(), + VestingQueryMsg::GetEndTime { + vesting_account_address, + } => client.vesting_end_time(&vesting_account_address).ignore(), + VestingQueryMsg::GetOriginalVesting { + vesting_account_address, + } => client.original_vesting(&vesting_account_address).ignore(), + VestingQueryMsg::GetHistoricalVestingStakingReward { + vesting_account_address, + } => client + .get_historical_vesting_staking_reward(&vesting_account_address) + .ignore(), + VestingQueryMsg::GetSpendableVestedCoins { + vesting_account_address, + } => client + .get_spendable_vested_coins(&vesting_account_address) + .ignore(), + VestingQueryMsg::GetSpendableRewardCoins { + vesting_account_address, + } => client + .get_spendable_reward_coins(&vesting_account_address) + .ignore(), + VestingQueryMsg::GetDelegatedCoins { + vesting_account_address, + } => client + .get_delegated_coins(&vesting_account_address) + .ignore(), + VestingQueryMsg::GetPledgedCoins { + vesting_account_address, + } => client.get_pledged_coins(&vesting_account_address).ignore(), + VestingQueryMsg::GetStakedCoins { + vesting_account_address, + } => client.get_staked_coins(&vesting_account_address).ignore(), + VestingQueryMsg::GetWithdrawnCoins { + vesting_account_address, + } => client + .get_withdrawn_coins(&vesting_account_address) + .ignore(), + VestingQueryMsg::GetAccount { address } => client.get_account(&address).ignore(), + VestingQueryMsg::GetMixnode { address } => client.get_mixnode_pledge(&address).ignore(), + VestingQueryMsg::GetGateway { address } => client.get_gateway_pledge(&address).ignore(), + VestingQueryMsg::GetCurrentVestingPeriod { address } => { + client.get_current_vesting_period(&address).ignore() + } + VestingQueryMsg::GetDelegation { + address, + mix_id, + block_timestamp_secs, + } => client + .get_vesting_delegation(&address, mix_id, block_timestamp_secs) + .ignore(), + VestingQueryMsg::GetTotalDelegationAmount { address, mix_id } => client + .get_total_delegation_amount(&address, mix_id) + .ignore(), + VestingQueryMsg::GetDelegationTimes { address, mix_id } => { + client.get_delegation_timestamps(&address, mix_id).ignore() + } + VestingQueryMsg::GetAllDelegations { start_after, limit } => client + .get_all_vesting_delegations_paged(start_after, limit) + .ignore(), + }; } } diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/vesting_signing_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/vesting_signing_client.rs index b43876d6fb..eff759e068 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/vesting_signing_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/vesting_signing_client.rs @@ -375,8 +375,7 @@ where mod tests { use super::*; - // it's enough that this compiles - #[deprecated] + // it's enough that this compiles and clippy is happy about it async fn all_execute_variants_are_covered( client: C, msg: VestingExecuteMsg, diff --git a/nym-api/src/support/nyxd/mod.rs b/nym-api/src/support/nyxd/mod.rs index a5f46893c1..c3473d6a9a 100644 --- a/nym-api/src/support/nyxd/mod.rs +++ b/nym-api/src/support/nyxd/mod.rs @@ -344,7 +344,12 @@ impl crate::coconut::client::Client for Client { &self, idx: usize, ) -> crate::coconut::error::Result> { - Ok(self.0.read().await.get_all_epoch_dealings(idx).await?) + Ok(self + .0 + .read() + .await + .get_all_epoch_dealings(idx as u64) + .await?) } async fn get_verification_key_shares( diff --git a/nym-connect/desktop/Cargo.lock b/nym-connect/desktop/Cargo.lock index 5be85f5cda..625721abe4 100644 --- a/nym-connect/desktop/Cargo.lock +++ b/nym-connect/desktop/Cargo.lock @@ -4561,7 +4561,9 @@ dependencies = [ "colored 2.0.4", "cosmrs", "cosmwasm-std", + "cw-controllers", "cw-utils", + "cw2", "cw3", "cw4", "eyre", diff --git a/nym-wallet/Cargo.lock b/nym-wallet/Cargo.lock index 68eff5cacf..ba0ebb18e0 100644 --- a/nym-wallet/Cargo.lock +++ b/nym-wallet/Cargo.lock @@ -3415,7 +3415,9 @@ dependencies = [ "colored 2.0.4", "cosmrs", "cosmwasm-std", + "cw-controllers", "cw-utils", + "cw2", "cw3", "cw4", "eyre", From 9e40763f7f2e7e8ffe06a6a5bf62a6bf8ff48343 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Wed, 2 Aug 2023 17:01:30 +0100 Subject: [PATCH 14/24] using type alias in the credential client --- clients/credential/src/client.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/clients/credential/src/client.rs b/clients/credential/src/client.rs index 95b161fb4d..9eb0a7da75 100644 --- a/clients/credential/src/client.rs +++ b/clients/credential/src/client.rs @@ -4,14 +4,14 @@ use crate::error::Result; use bip39::Mnemonic; use nym_network_defaults::{NymNetworkDetails, VOUCHER_INFO}; -use nym_validator_client::nyxd; use nym_validator_client::nyxd::contract_traits::CoconutBandwidthSigningClient; -use nym_validator_client::nyxd::{Coin, DirectSigningNyxdClient, Fee, NyxdClient}; +use nym_validator_client::nyxd::{self, DirectSigningHttpRpcNyxdClient}; +use nym_validator_client::nyxd::{Coin, Fee, NyxdClient}; use std::str::FromStr; use url::Url; pub(crate) struct Client { - nyxd_client: NyxdClient, + nyxd_client: DirectSigningHttpRpcNyxdClient, mix_denom_base: String, } From cc6fdfa11093393cceb845e083accd605c5dbdb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Wed, 2 Aug 2023 17:18:22 +0100 Subject: [PATCH 15/24] signing clients for coconut bandwidth and dkg --- .../coconut_bandwidth_signing_client.rs | 43 ++++++++++++- .../contract_traits/dkg_signing_client.rs | 60 ++++++++++++++++++- .../src/nyxd/contract_traits/mod.rs | 6 ++ .../coconut-dkg/src/msg.rs | 1 + 4 files changed, 106 insertions(+), 4 deletions(-) diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/coconut_bandwidth_signing_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/coconut_bandwidth_signing_client.rs index 1711c34621..a1d30758cc 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/coconut_bandwidth_signing_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/coconut_bandwidth_signing_client.rs @@ -64,6 +64,22 @@ pub trait CoconutBandwidthSigningClient { ) .await } + + async fn release_funds( + &self, + amount: Coin, + fee: Option, + ) -> Result { + self.execute_coconut_bandwidth_contract( + fee, + CoconutBandwidthExecuteMsg::ReleaseFunds { + funds: amount.into(), + }, + "CoconutBandwidth::ReleaseFunds".to_string(), + vec![], + ) + .await + } } #[async_trait] @@ -101,12 +117,35 @@ where #[cfg(test)] mod tests { use super::*; + use crate::nyxd::contract_traits::tests::{mock_coin, IgnoreValue}; // it's enough that this compiles and clippy is happy about it - async fn all_execute_variants_are_covered( + #[allow(dead_code)] + fn all_execute_variants_are_covered( client: C, msg: CoconutBandwidthExecuteMsg, ) { - unimplemented!() + match msg { + CoconutBandwidthExecuteMsg::DepositFunds { data } => client + .deposit( + mock_coin(), + data.deposit_info().to_string(), + data.identity_key().to_string(), + data.encryption_key().to_string(), + None, + ) + .ignore(), + CoconutBandwidthExecuteMsg::SpendCredential { data } => client + .spend_credential( + mock_coin(), + data.blinded_serial_number().to_string(), + data.gateway_cosmos_address().to_string(), + None, + ) + .ignore(), + CoconutBandwidthExecuteMsg::ReleaseFunds { funds } => { + client.release_funds(mock_coin(), None).ignore() + } + }; } } diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/dkg_signing_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/dkg_signing_client.rs index 5b28ea7d8e..9ecf476743 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/dkg_signing_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/dkg_signing_client.rs @@ -7,6 +7,8 @@ use crate::nyxd::error::NyxdError; use crate::nyxd::{Coin, Fee, SigningCosmWasmClient}; use crate::signing::signer::OfflineSigner; use async_trait::async_trait; +use cosmrs::AccountId; +use cosmwasm_std::Addr; use nym_coconut_dkg_common::msg::ExecuteMsg as DkgExecuteMsg; use nym_coconut_dkg_common::types::EncodedBTEPublicKeyWithProof; use nym_coconut_dkg_common::verification_key::VerificationKeyShare; @@ -29,6 +31,13 @@ pub trait DkgSigningClient { .await } + async fn surpass_threshold(&self, fee: Option) -> Result { + let req = DkgExecuteMsg::SurpassedThreshold {}; + + self.execute_dkg_contract(fee, req, "surpass DKG threshold".to_string(), vec![]) + .await + } + async fn register_dealer( &self, bte_key: EncodedBTEPublicKeyWithProof, @@ -77,6 +86,25 @@ pub trait DkgSigningClient { ) .await } + + async fn verify_verification_key_share( + &self, + owner: &AccountId, + resharing: bool, + fee: Option, + ) -> Result { + // the call to unchecked is fine as we're converting from pre-validated `AccountId` + let owner = Addr::unchecked(owner.to_string()); + let req = DkgExecuteMsg::VerifyVerificationKeyShare { owner, resharing }; + + self.execute_dkg_contract( + fee, + req, + "verification key VerifyVerificationKeyShare".to_string(), + vec![], + ) + .await + } } #[async_trait] @@ -107,12 +135,40 @@ where #[cfg(test)] mod tests { use super::*; + use crate::nyxd::contract_traits::tests::IgnoreValue; // it's enough that this compiles and clippy is happy about it - async fn all_execute_variants_are_covered( + #[allow(dead_code)] + fn all_execute_variants_are_covered( client: C, msg: DkgExecuteMsg, ) { - unimplemented!() + match msg { + DkgExecuteMsg::RegisterDealer { + bte_key_with_proof, + announce_address, + resharing, + } => client + .register_dealer(bte_key_with_proof, announce_address, resharing, None) + .ignore(), + DkgExecuteMsg::CommitDealing { + dealing_bytes, + resharing, + } => client + .submit_dealing_bytes(dealing_bytes, resharing, None) + .ignore(), + DkgExecuteMsg::CommitVerificationKeyShare { share, resharing } => client + .submit_verification_key_share(share, resharing, None) + .ignore(), + DkgExecuteMsg::VerifyVerificationKeyShare { owner, resharing } => client + .verify_verification_key_share( + &owner.into_string().parse().unwrap(), + resharing, + None, + ) + .ignore(), + DkgExecuteMsg::SurpassedThreshold {} => client.surpass_threshold(None).ignore(), + DkgExecuteMsg::AdvanceEpochState {} => client.advance_dkg_epoch_state(None).ignore(), + }; } } diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/mod.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/mod.rs index 8292136bb8..545fdf05ec 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/mod.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/mod.rs @@ -158,6 +158,8 @@ macro_rules! collect_paged { #[cfg(test)] mod tests { + use crate::nyxd::Coin; + pub(crate) trait IgnoreValue { fn ignore(self) -> u32 where @@ -170,4 +172,8 @@ mod tests { } impl IgnoreValue for T {} + + pub(crate) fn mock_coin() -> Coin { + Coin::new(42, "ufoomp") + } } diff --git a/common/cosmwasm-smart-contracts/coconut-dkg/src/msg.rs b/common/cosmwasm-smart-contracts/coconut-dkg/src/msg.rs index 076f84291c..b986b77f41 100644 --- a/common/cosmwasm-smart-contracts/coconut-dkg/src/msg.rs +++ b/common/cosmwasm-smart-contracts/coconut-dkg/src/msg.rs @@ -42,6 +42,7 @@ pub enum ExecuteMsg { }, VerifyVerificationKeyShare { + // TODO: this should be using a String... owner: Addr, resharing: bool, }, From 1740cead377544b47c0f92a38207f6aea2330bd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Wed, 2 Aug 2023 17:21:44 +0100 Subject: [PATCH 16/24] fixed usage of paged query client traits --- .../validator-client/examples/query_name_service.rs | 4 +++- .../examples/query_service_provider_directory.rs | 4 +++- nym-api/src/nym_contract_cache/cache/refresher.rs | 4 +++- nym-api/src/support/nyxd/mod.rs | 2 +- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/common/client-libs/validator-client/examples/query_name_service.rs b/common/client-libs/validator-client/examples/query_name_service.rs index 5fe5a64c1d..68e4da4cf2 100644 --- a/common/client-libs/validator-client/examples/query_name_service.rs +++ b/common/client-libs/validator-client/examples/query_name_service.rs @@ -3,7 +3,9 @@ use std::str::FromStr; use cosmrs::AccountId; use nym_name_service_common::Address; use nym_network_defaults::{setup_env, NymNetworkDetails}; -use nym_validator_client::nyxd::contract_traits::NameServiceQueryClient; +use nym_validator_client::nyxd::contract_traits::{ + NameServiceQueryClient, PagedNameServiceQueryClient, +}; #[tokio::main] async fn main() { diff --git a/common/client-libs/validator-client/examples/query_service_provider_directory.rs b/common/client-libs/validator-client/examples/query_service_provider_directory.rs index 797aaae950..d0f6f7ce46 100644 --- a/common/client-libs/validator-client/examples/query_service_provider_directory.rs +++ b/common/client-libs/validator-client/examples/query_service_provider_directory.rs @@ -3,7 +3,9 @@ use std::str::FromStr; use cosmrs::AccountId; use nym_network_defaults::{setup_env, NymNetworkDetails}; use nym_service_provider_directory_common::NymAddress; -use nym_validator_client::nyxd::contract_traits::SpDirectoryQueryClient; +use nym_validator_client::nyxd::contract_traits::{ + PagedSpDirectoryQueryClient, SpDirectoryQueryClient, +}; #[tokio::main] async fn main() { diff --git a/nym-api/src/nym_contract_cache/cache/refresher.rs b/nym-api/src/nym_contract_cache/cache/refresher.rs index 7df88a225f..c6bbe1f81a 100644 --- a/nym-api/src/nym_contract_cache/cache/refresher.rs +++ b/nym-api/src/nym_contract_cache/cache/refresher.rs @@ -4,7 +4,9 @@ use crate::support::caching::CacheNotification; use anyhow::Result; use nym_mixnet_contract_common::{MixId, MixNodeDetails, RewardedSetNodeStatus}; use nym_task::TaskClient; -use nym_validator_client::nyxd::contract_traits::{NameServiceQueryClient, SpDirectoryQueryClient}; +use nym_validator_client::nyxd::contract_traits::{ + PagedNameServiceQueryClient, PagedSpDirectoryQueryClient, +}; use std::{collections::HashMap, sync::atomic::Ordering, time::Duration}; use tokio::sync::watch; use tokio::time; diff --git a/nym-api/src/support/nyxd/mod.rs b/nym-api/src/support/nyxd/mod.rs index c3473d6a9a..861b485307 100644 --- a/nym-api/src/support/nyxd/mod.rs +++ b/nym-api/src/support/nyxd/mod.rs @@ -34,7 +34,7 @@ use nym_validator_client::nyxd::{ CoconutBandwidthQueryClient, DkgQueryClient, DkgSigningClient, GroupQueryClient, MixnetQueryClient, MixnetSigningClient, MultisigQueryClient, MultisigSigningClient, NymContractsProvider, PagedMixnetQueryClient, PagedMultisigQueryClient, - SpDirectoryQueryClient, VestingQueryClient, + PagedVestingQueryClient, SpDirectoryQueryClient, }, cosmwasm_client::types::ExecuteResult, CosmWasmClient, Fee, From 4652ac882fbd483a53e65166cc4a08f97f8d5476 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Thu, 3 Aug 2023 09:56:43 +0100 Subject: [PATCH 17/24] missing implementations of signing methods --- .../contract_traits/group_signing_client.rs | 67 +++++- .../contract_traits/mixnet_signing_client.rs | 227 +++++++++++++++++- .../multisig_signing_client.rs | 69 +++++- .../name_service_signing_client.rs | 22 +- .../sp_directory_signing_client.rs | 22 +- .../contract_traits/vesting_signing_client.rs | 182 +++++++++++++- 6 files changed, 576 insertions(+), 13 deletions(-) diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/group_signing_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/group_signing_client.rs index af05635430..07d14200d7 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/group_signing_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/group_signing_client.rs @@ -7,6 +7,7 @@ use crate::nyxd::error::NyxdError; use crate::nyxd::{Coin, Fee, SigningCosmWasmClient}; use crate::signing::signer::OfflineSigner; use async_trait::async_trait; +use cw4::Member; use nym_group_contract_common::msg::ExecuteMsg as GroupExecuteMsg; #[async_trait] @@ -18,6 +19,59 @@ pub trait GroupSigningClient { memo: String, funds: Vec, ) -> Result; + + async fn update_admin( + &self, + admin: Option, + fee: Option, + ) -> Result { + self.execute_group_contract( + fee, + GroupExecuteMsg::UpdateAdmin { admin }, + "GroupExecuteMsg::UpdateAdmin".to_string(), + vec![], + ) + .await + } + + async fn update_members( + &self, + add: Vec, + remove: Vec, + fee: Option, + ) -> Result { + self.execute_group_contract( + fee, + GroupExecuteMsg::UpdateMembers { add, remove }, + "GroupExecuteMsg::UpdateMembers".to_string(), + vec![], + ) + .await + } + + async fn add_hook(&self, addr: String, fee: Option) -> Result { + self.execute_group_contract( + fee, + GroupExecuteMsg::AddHook { addr }, + "GroupExecuteMsg::AddHook".to_string(), + vec![], + ) + .await + } + + async fn remove_hook( + &self, + addr: String, + fee: Option, + ) -> Result { + self.execute_group_contract( + fee, + GroupExecuteMsg::RemoveHook { addr }, + "GroupExecuteMsg::RemoveHook".to_string(), + vec![], + ) + .await + } } #[async_trait] @@ -55,12 +109,21 @@ where #[cfg(test)] mod tests { use super::*; + use crate::nyxd::contract_traits::tests::IgnoreValue; // it's enough that this compiles and clippy is happy about it - async fn all_execute_variants_are_covered( + #[allow(dead_code)] + fn all_execute_variants_are_covered( client: C, msg: GroupExecuteMsg, ) { - unimplemented!() + match msg { + GroupExecuteMsg::UpdateAdmin { admin } => client.update_admin(admin, None).ignore(), + GroupExecuteMsg::UpdateMembers { remove, add } => { + client.update_members(add, remove, None).ignore() + } + GroupExecuteMsg::AddHook { addr } => client.add_hook(addr, None).ignore(), + GroupExecuteMsg::RemoveHook { addr } => client.remove_hook(addr, None).ignore(), + }; } } diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/mixnet_signing_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/mixnet_signing_client.rs index de5923a5a1..ad7d03327c 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/mixnet_signing_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/mixnet_signing_client.rs @@ -15,7 +15,8 @@ use nym_mixnet_contract_common::gateway::GatewayConfigUpdate; use nym_mixnet_contract_common::mixnode::{MixNodeConfigUpdate, MixNodeCostParams}; use nym_mixnet_contract_common::reward_params::{IntervalRewardingParamsUpdate, Performance}; use nym_mixnet_contract_common::{ - ContractStateParams, ExecuteMsg as MixnetExecuteMsg, Gateway, LayerAssignment, MixId, MixNode, + ContractStateParams, ExecuteMsg as MixnetExecuteMsg, Gateway, Layer, LayerAssignment, MixId, + MixNode, }; #[async_trait] @@ -132,6 +133,20 @@ pub trait MixnetSigningClient { .await } + async fn assign_node_layer( + &self, + mix_id: MixId, + layer: Layer, + fee: Option, + ) -> Result { + self.execute_mixnet_contract( + fee, + MixnetExecuteMsg::AssignNodeLayer { mix_id, layer }, + vec![], + ) + .await + } + async fn reconcile_epoch_events( &self, limit: Option, @@ -666,6 +681,18 @@ pub trait MixnetSigningClient { ) .await } + + #[cfg(feature = "nym_mixnet_contract_common/contract-testing")] + async fn testing_resolve_all_pending_events( + fee: Option, + ) -> Result { + self.execute_mixnet_contract( + fee, + MixnetExecuteMsg::TestingResolveAllPendingEvents {}, + vec![], + ) + .await + } } #[async_trait] @@ -703,12 +730,206 @@ where #[cfg(test)] mod tests { use super::*; + use crate::nyxd::contract_traits::tests::{mock_coin, IgnoreValue}; // it's enough that this compiles and clippy is happy about it - async fn all_execute_variants_are_covered( + #[allow(dead_code)] + fn all_execute_variants_are_covered( client: C, msg: MixnetExecuteMsg, ) { - unimplemented!() + match msg { + MixnetExecuteMsg::AssignNodeLayer { mix_id, layer } => { + client.assign_node_layer(mix_id, layer, None).ignore() + } + MixnetExecuteMsg::CreateFamily { label } => client.create_family(label, None).ignore(), + MixnetExecuteMsg::JoinFamily { + join_permit, + family_head, + } => client.join_family(join_permit, family_head, None).ignore(), + MixnetExecuteMsg::LeaveFamily { family_head } => { + client.leave_family(family_head, None).ignore() + } + MixnetExecuteMsg::KickFamilyMember { member } => { + client.kick_family_member(member, None).ignore() + } + MixnetExecuteMsg::CreateFamilyOnBehalf { + owner_address, + label, + } => client + .create_family_on_behalf(owner_address, label, None) + .ignore(), + MixnetExecuteMsg::JoinFamilyOnBehalf { + member_address, + join_permit, + family_head, + } => client + .join_family_on_behalf(member_address, join_permit, family_head, None) + .ignore(), + MixnetExecuteMsg::LeaveFamilyOnBehalf { + member_address, + family_head, + } => client + .leave_family_on_behalf(member_address, family_head, None) + .ignore(), + MixnetExecuteMsg::KickFamilyMemberOnBehalf { + head_address, + member, + } => client + .kick_family_member_on_behalf(head_address, member, None) + .ignore(), + MixnetExecuteMsg::UpdateRewardingValidatorAddress { address } => client + .update_rewarding_validator_address(address.parse().unwrap(), None) + .ignore(), + MixnetExecuteMsg::UpdateContractStateParams { updated_parameters } => client + .update_contract_state_params(updated_parameters, None) + .ignore(), + MixnetExecuteMsg::UpdateActiveSetSize { + active_set_size, + force_immediately, + } => client + .update_active_set_size(active_set_size, force_immediately, None) + .ignore(), + MixnetExecuteMsg::UpdateRewardingParams { + updated_params, + force_immediately, + } => client + .update_rewarding_parameters(updated_params, force_immediately, None) + .ignore(), + MixnetExecuteMsg::UpdateIntervalConfig { + epochs_in_interval, + epoch_duration_secs, + force_immediately, + } => client + .update_interval_config( + epochs_in_interval, + epoch_duration_secs, + force_immediately, + None, + ) + .ignore(), + MixnetExecuteMsg::BeginEpochTransition {} => { + client.begin_epoch_transition(None).ignore() + } + MixnetExecuteMsg::AdvanceCurrentEpoch { + new_rewarded_set, + expected_active_set_size, + } => client + .advance_current_epoch(new_rewarded_set, expected_active_set_size, None) + .ignore(), + MixnetExecuteMsg::ReconcileEpochEvents { limit } => { + client.reconcile_epoch_events(limit, None).ignore() + } + MixnetExecuteMsg::BondMixnode { + mix_node, + cost_params, + owner_signature, + } => client + .bond_mixnode(mix_node, cost_params, owner_signature, mock_coin(), None) + .ignore(), + MixnetExecuteMsg::BondMixnodeOnBehalf { + mix_node, + cost_params, + owner_signature, + owner, + } => client + .bond_mixnode_on_behalf( + owner.parse().unwrap(), + mix_node, + cost_params, + owner_signature, + mock_coin(), + None, + ) + .ignore(), + MixnetExecuteMsg::PledgeMore {} => client.pledge_more(mock_coin(), None).ignore(), + MixnetExecuteMsg::PledgeMoreOnBehalf { owner } => client + .pledge_more_on_behalf(owner.parse().unwrap(), mock_coin(), None) + .ignore(), + MixnetExecuteMsg::DecreasePledge { decrease_by } => { + client.decrease_pledge(decrease_by.into(), None).ignore() + } + MixnetExecuteMsg::DecreasePledgeOnBehalf { owner, decrease_by } => client + .decrease_pledge_on_behalf(owner.parse().unwrap(), decrease_by.into(), None) + .ignore(), + MixnetExecuteMsg::UnbondMixnode {} => client.unbond_mixnode(None).ignore(), + MixnetExecuteMsg::UnbondMixnodeOnBehalf { owner } => client + .unbond_mixnode_on_behalf(owner.parse().unwrap(), None) + .ignore(), + MixnetExecuteMsg::UpdateMixnodeCostParams { new_costs } => { + client.update_mixnode_cost_params(new_costs, None).ignore() + } + MixnetExecuteMsg::UpdateMixnodeCostParamsOnBehalf { new_costs, owner } => client + .update_mixnode_cost_params_on_behalf(owner.parse().unwrap(), new_costs, None) + .ignore(), + MixnetExecuteMsg::UpdateMixnodeConfig { new_config } => { + client.update_mixnode_config(new_config, None).ignore() + } + MixnetExecuteMsg::UpdateMixnodeConfigOnBehalf { new_config, owner } => client + .update_mixnode_config_on_behalf(owner.parse().unwrap(), new_config, None) + .ignore(), + MixnetExecuteMsg::BondGateway { + gateway, + owner_signature, + } => client + .bond_gateway(gateway, owner_signature, mock_coin(), None) + .ignore(), + MixnetExecuteMsg::BondGatewayOnBehalf { + gateway, + owner, + owner_signature, + } => client + .bond_gateway_on_behalf( + owner.parse().unwrap(), + gateway, + owner_signature, + mock_coin(), + None, + ) + .ignore(), + MixnetExecuteMsg::UnbondGateway {} => client.unbond_gateway(None).ignore(), + MixnetExecuteMsg::UnbondGatewayOnBehalf { owner } => client + .unbond_gateway_on_behalf(owner.parse().unwrap(), None) + .ignore(), + MixnetExecuteMsg::UpdateGatewayConfig { new_config } => { + client.update_gateway_config(new_config, None).ignore() + } + MixnetExecuteMsg::UpdateGatewayConfigOnBehalf { new_config, owner } => client + .update_gateway_config_on_behalf(owner.parse().unwrap(), new_config, None) + .ignore(), + MixnetExecuteMsg::DelegateToMixnode { mix_id } => client + .delegate_to_mixnode(mix_id, mock_coin(), None) + .ignore(), + MixnetExecuteMsg::DelegateToMixnodeOnBehalf { mix_id, delegate } => client + .delegate_to_mixnode_on_behalf(delegate.parse().unwrap(), mix_id, mock_coin(), None) + .ignore(), + MixnetExecuteMsg::UndelegateFromMixnode { mix_id } => { + client.undelegate_from_mixnode(mix_id, None).ignore() + } + MixnetExecuteMsg::UndelegateFromMixnodeOnBehalf { mix_id, delegate } => client + .undelegate_to_mixnode_on_behalf(delegate.parse().unwrap(), mix_id, None) + .ignore(), + MixnetExecuteMsg::RewardMixnode { + mix_id, + performance, + } => client.reward_mixnode(mix_id, performance, None).ignore(), + MixnetExecuteMsg::WithdrawOperatorReward {} => { + client.withdraw_operator_reward(None).ignore() + } + MixnetExecuteMsg::WithdrawOperatorRewardOnBehalf { owner } => client + .withdraw_operator_reward_on_behalf(owner.parse().unwrap(), None) + .ignore(), + MixnetExecuteMsg::WithdrawDelegatorReward { mix_id } => { + client.withdraw_delegator_reward(mix_id, None).ignore() + } + MixnetExecuteMsg::WithdrawDelegatorRewardOnBehalf { mix_id, owner } => client + .withdraw_delegator_reward_on_behalf(owner.parse().unwrap(), mix_id, None) + .ignore(), + + #[cfg(feature = "nym_mixnet_contract_common/contract-testing")] + MixnetExecuteMsg::TestingResolveAllPendingEvents {} => { + client.testing_resolve_all_pending_events(None).ignore() + } + }; } } diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/multisig_signing_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/multisig_signing_client.rs index 9e6c2948db..0da2fd9de8 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/multisig_signing_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/multisig_signing_client.rs @@ -9,6 +9,7 @@ use crate::signing::signer::OfflineSigner; use async_trait::async_trait; use cosmwasm_std::{to_binary, CosmosMsg, WasmMsg}; use cw3::Vote; +use cw4::{MemberChangedHookMsg, MemberDiff}; use nym_coconut_bandwidth_contract_common::msg::ExecuteMsg as CoconutBandwidthExecuteMsg; use nym_multisig_contract_common::msg::ExecuteMsg as MultisigExecuteMsg; @@ -68,6 +69,22 @@ pub trait MultisigSigningClient: NymContractsProvider { .await } + // alternative variant to vote_proposal that lets you to abstain and veto a proposal + async fn vote( + &self, + proposal_id: u64, + vote: Vote, + fee: Option, + ) -> Result { + self.execute_multisig_contract( + fee, + MultisigExecuteMsg::Vote { proposal_id, vote }, + "Multisig::Vote".to_string(), + vec![], + ) + .await + } + async fn execute_proposal( &self, proposal_id: u64, @@ -77,6 +94,34 @@ pub trait MultisigSigningClient: NymContractsProvider { self.execute_multisig_contract(fee, req, "Multisig::Execute".to_string(), vec![]) .await } + + async fn close_proposal( + &self, + proposal_id: u64, + fee: Option, + ) -> Result { + self.execute_multisig_contract( + fee, + MultisigExecuteMsg::Close { proposal_id }, + "Multisig::Close".to_string(), + vec![], + ) + .await + } + + async fn changed_member_hook( + &self, + member_diff: Vec, + fee: Option, + ) -> Result { + self.execute_multisig_contract( + fee, + MultisigExecuteMsg::MemberChangedHook(MemberChangedHookMsg::new(member_diff)), + "Multisig::MemberChangedHook".to_string(), + vec![], + ) + .await + } } #[async_trait] @@ -114,12 +159,32 @@ where #[cfg(test)] mod tests { use super::*; + use crate::nyxd::contract_traits::tests::{mock_coin, IgnoreValue}; // it's enough that this compiles and clippy is happy about it - async fn all_execute_variants_are_covered( + #[allow(dead_code)] + fn all_execute_variants_are_covered( client: C, msg: MultisigExecuteMsg, ) { - unimplemented!() + match msg { + MultisigExecuteMsg::Propose { + title, description, .. + } => client + .propose_release_funds(title, description, mock_coin(), None) + .ignore(), + MultisigExecuteMsg::Vote { proposal_id, vote } => { + client.vote(proposal_id, vote, None).ignore() + } + MultisigExecuteMsg::Execute { proposal_id } => { + client.execute_proposal(proposal_id, None).ignore() + } + MultisigExecuteMsg::Close { proposal_id } => { + client.close_proposal(proposal_id, None).ignore() + } + MultisigExecuteMsg::MemberChangedHook(hook_msg) => { + client.changed_member_hook(hook_msg.diffs, None).ignore() + } + }; } } diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/name_service_signing_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/name_service_signing_client.rs index 27ff60c99a..bc5a06e1a9 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/name_service_signing_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/name_service_signing_client.rs @@ -107,12 +107,30 @@ where #[cfg(test)] mod tests { use super::*; + use crate::nyxd::contract_traits::tests::{mock_coin, IgnoreValue}; // it's enough that this compiles and clippy is happy about it - async fn all_execute_variants_are_covered( + #[allow(dead_code)] + fn all_execute_variants_are_covered( client: C, msg: NameExecuteMsg, ) { - unimplemented!() + match msg { + NameExecuteMsg::Register { + name, + owner_signature, + } => client + .register_name(name, owner_signature, mock_coin(), None) + .ignore(), + NameExecuteMsg::DeleteId { name_id } => { + client.delete_name_by_id(name_id, None).ignore() + } + NameExecuteMsg::DeleteName { name } => { + client.delete_service_provider_by_name(name, None).ignore() + } + NameExecuteMsg::UpdateDepositRequired { deposit_required } => client + .update_deposit_required(deposit_required.into(), None) + .ignore(), + }; } } diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/sp_directory_signing_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/sp_directory_signing_client.rs index 597847549f..9d0f3f458a 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/sp_directory_signing_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/sp_directory_signing_client.rs @@ -117,12 +117,30 @@ where #[cfg(test)] mod tests { use super::*; + use crate::nyxd::contract_traits::tests::{mock_coin, IgnoreValue}; // it's enough that this compiles and clippy is happy about it - async fn all_execute_variants_are_covered( + #[allow(dead_code)] + fn all_execute_variants_are_covered( client: C, msg: SpExecuteMsg, ) { - unimplemented!() + match msg { + SpExecuteMsg::Announce { + service, + owner_signature, + } => client + .announce_service_provider(service, owner_signature, mock_coin(), None) + .ignore(), + SpExecuteMsg::DeleteId { service_id } => client + .delete_service_provider_by_id(service_id, None) + .ignore(), + SpExecuteMsg::DeleteNymAddress { nym_address } => client + .delete_service_provider_by_nym_address(nym_address, None) + .ignore(), + SpExecuteMsg::UpdateDepositRequired { deposit_required } => client + .update_deposit_required(deposit_required.into(), None) + .ignore(), + }; } } diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/vesting_signing_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/vesting_signing_client.rs index eff759e068..b540d3b3f9 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/vesting_signing_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/vesting_signing_client.rs @@ -71,6 +71,23 @@ pub trait VestingSigningClient { self.execute_vesting_contract(fee, req, vec![]).await } + async fn vesting_track_decrease_pledge( + &self, + owner: String, + amount: Coin, + fee: Option, + ) -> Result { + self.execute_vesting_contract( + fee, + VestingExecuteMsg::TrackDecreasePledge { + owner, + amount: amount.into(), + }, + Vec::new(), + ) + .await + } + async fn vesting_bond_gateway( &self, gateway: Gateway, @@ -256,6 +273,23 @@ pub trait VestingSigningClient { self.execute_vesting_contract(fee, req, vec![amount]).await } + async fn vesting_track_reward( + &self, + amount: Coin, + address: String, + fee: Option, + ) -> Result { + self.execute_vesting_contract( + fee, + VestingExecuteMsg::TrackReward { + amount: amount.into(), + address, + }, + Vec::new(), + ) + .await + } + async fn vesting_withdraw_operator_reward( &self, fee: Option, @@ -277,6 +311,32 @@ pub trait VestingSigningClient { .await } + async fn vesting_transfer_ownership( + &self, + to_address: String, + fee: Option, + ) -> Result { + self.execute_vesting_contract( + fee, + VestingExecuteMsg::TransferOwnership { to_address }, + Vec::new(), + ) + .await + } + + async fn update_staking_address( + &self, + to_address: Option, + fee: Option, + ) -> Result { + self.execute_vesting_contract( + fee, + VestingExecuteMsg::UpdateStakingAddress { to_address }, + Vec::new(), + ) + .await + } + async fn update_locked_pledge_cap( &self, address: AccountId, @@ -374,12 +434,130 @@ where #[cfg(test)] mod tests { use super::*; + use crate::nyxd::contract_traits::tests::{mock_coin, IgnoreValue}; // it's enough that this compiles and clippy is happy about it - async fn all_execute_variants_are_covered( + #[allow(dead_code)] + fn all_execute_variants_are_covered( client: C, msg: VestingExecuteMsg, ) { - unimplemented!() + match msg { + VestingExecuteMsg::CreateFamily { label } => { + client.vesting_create_family(label, None).ignore() + } + VestingExecuteMsg::JoinFamily { + join_permit, + family_head, + } => client + .vesting_join_family(join_permit, family_head, None) + .ignore(), + VestingExecuteMsg::LeaveFamily { family_head } => { + client.vesting_leave_family(family_head, None).ignore() + } + VestingExecuteMsg::KickFamilyMember { member } => { + client.vesting_kick_family_member(member, None).ignore() + } + VestingExecuteMsg::TrackReward { amount, address } => client + .vesting_track_reward(amount.into(), address, None) + .ignore(), + VestingExecuteMsg::ClaimOperatorReward {} => { + client.vesting_withdraw_operator_reward(None).ignore() + } + VestingExecuteMsg::ClaimDelegatorReward { mix_id } => client + .vesting_withdraw_delegator_reward(mix_id, None) + .ignore(), + VestingExecuteMsg::UpdateMixnodeCostParams { new_costs } => client + .vesting_update_mixnode_cost_params(new_costs, None) + .ignore(), + VestingExecuteMsg::UpdateMixnodeConfig { new_config } => client + .vesting_update_mixnode_config(new_config, None) + .ignore(), + VestingExecuteMsg::UpdateMixnetAddress { address } => { + client.update_mixnet_address(&address, None).ignore() + } + VestingExecuteMsg::DelegateToMixnode { + mix_id, + amount, + on_behalf_of, + } => client + .vesting_delegate_to_mixnode(mix_id, amount.into(), on_behalf_of, None) + .ignore(), + VestingExecuteMsg::UndelegateFromMixnode { + mix_id, + on_behalf_of, + } => client + .vesting_undelegate_from_mixnode(mix_id, on_behalf_of, None) + .ignore(), + VestingExecuteMsg::CreateAccount { + owner_address, + staking_address, + vesting_spec, + cap, + } => client + .create_periodic_vesting_account( + &owner_address, + staking_address, + vesting_spec, + mock_coin(), + cap, + None, + ) + .ignore(), + VestingExecuteMsg::WithdrawVestedCoins { amount } => { + client.withdraw_vested_coins(amount.into(), None).ignore() + } + VestingExecuteMsg::TrackUndelegation { + owner, + mix_id, + amount, + } => client + .vesting_track_undelegation(&owner, mix_id, amount.into(), None) + .ignore(), + VestingExecuteMsg::BondMixnode { + mix_node, + cost_params, + owner_signature, + amount, + } => client + .vesting_bond_mixnode(mix_node, cost_params, owner_signature, amount.into(), None) + .ignore(), + VestingExecuteMsg::PledgeMore { amount } => { + client.vesting_pledge_more(amount.into(), None).ignore() + } + VestingExecuteMsg::DecreasePledge { amount } => { + client.vesting_decrease_pledge(amount.into(), None).ignore() + } + VestingExecuteMsg::UnbondMixnode {} => client.vesting_unbond_mixnode(None).ignore(), + VestingExecuteMsg::TrackUnbondMixnode { owner, amount } => client + .vesting_track_unbond_mixnode(&owner, amount.into(), None) + .ignore(), + VestingExecuteMsg::TrackDecreasePledge { owner, amount } => client + .vesting_track_decrease_pledge(owner, amount.into(), None) + .ignore(), + VestingExecuteMsg::BondGateway { + gateway, + owner_signature, + amount, + } => client + .vesting_bond_gateway(gateway, owner_signature, amount.into(), None) + .ignore(), + VestingExecuteMsg::UnbondGateway {} => client.vesting_unbond_gateway(None).ignore(), + VestingExecuteMsg::TrackUnbondGateway { owner, amount } => client + .vesting_track_unbond_gateway(&owner, amount.into(), None) + .ignore(), + VestingExecuteMsg::UpdateGatewayConfig { new_config } => client + .vesting_update_gateway_config(new_config, None) + .ignore(), + VestingExecuteMsg::TransferOwnership { to_address } => { + client.vesting_transfer_ownership(to_address, None).ignore() + } + VestingExecuteMsg::UpdateStakingAddress { to_address } => { + client.update_staking_address(to_address, None).ignore() + } + VestingExecuteMsg::UpdateLockedPledgeCap { address, cap } => client + .update_locked_pledge_cap(address.parse().unwrap(), cap, None) + .ignore(), + }; } } From c3a09a0860ba0d34dbad115b96dd28b61635b2a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Thu, 3 Aug 2023 10:25:58 +0100 Subject: [PATCH 18/24] missing handler for 'MixnetQueryMsg::GetStateParams' --- .../src/nyxd/contract_traits/mixnet_query_client.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/mixnet_query_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/mixnet_query_client.rs index e38c7e0eb5..74e7f653d7 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/mixnet_query_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/mixnet_query_client.rs @@ -63,6 +63,11 @@ pub trait MixnetQueryClient { .await } + async fn get_mixnet_contract_state_params(&self) -> Result { + self.query_mixnet_contract(MixnetQueryMsg::GetStateParams {}) + .await + } + async fn get_mixnet_contract_state(&self) -> Result { self.query_mixnet_contract(MixnetQueryMsg::GetState {}) .await @@ -613,7 +618,7 @@ mod tests { MixnetQueryMsg::GetRewardingValidatorAddress {} => { client.get_rewarding_validator_address().ignore() } - MixnetQueryMsg::GetStateParams {} => {} + MixnetQueryMsg::GetStateParams {} => client.get_mixnet_contract_state_params().ignore(), MixnetQueryMsg::GetState {} => client.get_mixnet_contract_state().ignore(), MixnetQueryMsg::GetRewardingParams {} => client.get_rewarding_parameters().ignore(), MixnetQueryMsg::GetEpochStatus {} => client.get_current_epoch_status().ignore(), From a255c6733b5e35b9fd5b8c01eb3fdfef766d0a67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Thu, 3 Aug 2023 10:39:04 +0100 Subject: [PATCH 19/24] clippy --- .../nyxd/contract_traits/coconut_bandwidth_signing_client.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/coconut_bandwidth_signing_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/coconut_bandwidth_signing_client.rs index a1d30758cc..e9c43e6fca 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/coconut_bandwidth_signing_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/coconut_bandwidth_signing_client.rs @@ -144,7 +144,7 @@ mod tests { ) .ignore(), CoconutBandwidthExecuteMsg::ReleaseFunds { funds } => { - client.release_funds(mock_coin(), None).ignore() + client.release_funds(funds.into(), None).ignore() } }; } From 3409e86a63b4595ecbc89231f14874fa50e56506 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Thu, 3 Aug 2023 15:19:13 +0100 Subject: [PATCH 20/24] removed unused import post rebasing --- .../contract_traits/mixnet_query_client.rs | 30 +++++-------------- 1 file changed, 8 insertions(+), 22 deletions(-) diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/mixnet_query_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/mixnet_query_client.rs index 74e7f653d7..09793e3eb1 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/mixnet_query_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/mixnet_query_client.rs @@ -24,16 +24,16 @@ use nym_mixnet_contract_common::{ CurrentIntervalResponse, Delegation, EpochEventId, EpochStatus, FamilyByHeadResponse, FamilyByLabelResponse, FamilyMembersByHeadResponse, FamilyMembersByLabelResponse, GatewayBond, GatewayBondResponse, GatewayOwnershipResponse, IdentityKey, IntervalEventId, LayerDistribution, - MixId, MixNodeBond, MixNodeDetails, MixOwnershipResponse, MixnodeDetailsResponse, - NumberOfPendingEventsResponse, PagedAllDelegationsResponse, PagedDelegatorDelegationsResponse, - PagedFamiliesResponse, PagedGatewayResponse, PagedMembersResponse, - PagedMixNodeDelegationsResponse, PagedMixnodeBondsResponse, PagedRewardedSetResponse, - PendingEpochEvent, PendingEpochEventResponse, PendingEpochEventsResponse, PendingIntervalEvent, - PendingIntervalEventResponse, PendingIntervalEventsResponse, QueryMsg as MixnetQueryMsg, - RewardedSetNodeStatus, UnbondedMixnode, + MixId, MixNodeBond, MixNodeDetails, MixOwnershipResponse, MixnodeDetailsByIdentityResponse, + MixnodeDetailsResponse, NumberOfPendingEventsResponse, PagedAllDelegationsResponse, + PagedDelegatorDelegationsResponse, PagedFamiliesResponse, PagedGatewayResponse, + PagedMembersResponse, PagedMixNodeDelegationsResponse, PagedMixnodeBondsResponse, + PagedRewardedSetResponse, PendingEpochEvent, PendingEpochEventResponse, + PendingEpochEventsResponse, PendingIntervalEvent, PendingIntervalEventResponse, + PendingIntervalEventsResponse, QueryMsg as MixnetQueryMsg, RewardedSetNodeStatus, + UnbondedMixnode, }; use serde::Deserialize; -use std::collections::HashSet; #[async_trait] pub trait MixnetQueryClient { @@ -463,20 +463,6 @@ pub trait MixnetQueryClient { self.query_mixnet_contract(MixnetQueryMsg::GetFamilyByHead { head }) .await } - - // TODO: make sure the type matches after https://github.com/nymtech/nym/pull/3693 is merged - async fn get_family_members_by_head(&self, head: String) -> Result, NyxdError> { - self.query_mixnet_contract(MixnetQueryMsg::GetFamilyMembersByHead { head }) - .await - } - - async fn get_family_members_by_label( - &self, - label: String, - ) -> Result, NyxdError> { - self.query_mixnet_contract(MixnetQueryMsg::GetFamilyMembersByLabel { label }) - .await - } } // extension trait to the query client to deal with the paged queries From 42d08195f7d0aaa20845e80cc6c2cd80310b805f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Fri, 4 Aug 2023 16:05:15 +0100 Subject: [PATCH 21/24] fixed 'OfflineSigner' implementation for 'NyxdClient' and 'MaybeSigningClient' --- .../validator-client/src/nyxd/cosmwasm_client/mod.rs | 9 +++++++++ common/client-libs/validator-client/src/nyxd/mod.rs | 10 +++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) 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 55e98a0de3..c082468486 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 @@ -13,6 +13,7 @@ use tendermint_rpc::{Error as TendermintRpcError, SimpleRequest}; #[cfg(feature = "http-client")] use cosmrs::rpc::{HttpClient, HttpClientUrl}; +use cosmrs::tx::{Raw, SignDoc}; pub mod client_traits; mod helpers; @@ -99,6 +100,14 @@ where fn get_accounts(&self) -> Result, Self::Error> { self.signer.get_accounts() } + + fn sign_direct_with_account( + &self, + signer: &AccountData, + sign_doc: SignDoc, + ) -> Result { + self.signer.sign_direct_with_account(signer, sign_doc) + } } #[async_trait] diff --git a/common/client-libs/validator-client/src/nyxd/mod.rs b/common/client-libs/validator-client/src/nyxd/mod.rs index cde1d182fe..102cac80c3 100644 --- a/common/client-libs/validator-client/src/nyxd/mod.rs +++ b/common/client-libs/validator-client/src/nyxd/mod.rs @@ -15,7 +15,7 @@ use crate::signing::tx_signer::TxSigner; use crate::signing::AccountData; use async_trait::async_trait; use cosmrs::cosmwasm; -use cosmrs::tx::Msg; +use cosmrs::tx::{Msg, Raw, SignDoc}; use cosmwasm_std::Addr; use nym_network_defaults::{ChainDetails, NymNetworkDetails}; use serde::Serialize; @@ -603,6 +603,14 @@ where fn get_accounts(&self) -> Result, Self::Error> { self.client.get_accounts() } + + fn sign_direct_with_account( + &self, + signer: &AccountData, + sign_doc: SignDoc, + ) -> Result { + self.client.sign_direct_with_account(signer, sign_doc) + } } #[async_trait] From aae4725005fdbe7638b2129c6d75e97f1ec7d5c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Mon, 14 Aug 2023 11:01:22 +0100 Subject: [PATCH 22/24] fixed wasm build for explorer-api-requests --- Cargo.lock | 5 ++--- clients/webassembly/Cargo.lock | 1 - clients/webassembly/Cargo.toml | 2 +- common/client-libs/validator-client/Cargo.toml | 2 +- explorer-api/explorer-api-requests/Cargo.toml | 2 +- explorer-api/explorer-api-requests/src/lib.rs | 2 +- nym-connect/desktop/Cargo.lock | 1 - 7 files changed, 6 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index be6ea96af0..b84d9d3f41 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -460,8 +460,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "93f2635620bf0b9d4576eb7bb9a38a55df78bd1205d26fa994b25911a69f212f" dependencies = [ "bitcoin_hashes", - "rand 0.8.5", - "rand_core 0.6.4", + "rand 0.6.5", + "rand_core 0.4.2", "serde", "unicode-normalization", "zeroize", @@ -4047,7 +4047,6 @@ version = "0.1.0" dependencies = [ "nym-contracts-common", "nym-mixnet-contract-common", - "nym-validator-client", "schemars", "serde", "ts-rs", diff --git a/clients/webassembly/Cargo.lock b/clients/webassembly/Cargo.lock index 889a842029..083afb5309 100644 --- a/clients/webassembly/Cargo.lock +++ b/clients/webassembly/Cargo.lock @@ -2735,7 +2735,6 @@ version = "0.1.0" dependencies = [ "nym-contracts-common", "nym-mixnet-contract-common", - "nym-validator-client", "schemars", "serde", ] diff --git a/clients/webassembly/Cargo.toml b/clients/webassembly/Cargo.toml index 7405002cea..d68b5d37f6 100644 --- a/clients/webassembly/Cargo.toml +++ b/clients/webassembly/Cargo.toml @@ -3,7 +3,7 @@ name = "nym-client-wasm" authors = ["Dave Hrycyszyn ", "Jedrzej Stuczynski "] version = "1.1.1" edition = "2021" -keywords = ["nym", "sphinx", "wasm", "webassembly", "privacy", "client"] +keywords = ["nym", "sphinx", "wasm", "webassembly", "privacy"] license = "Apache-2.0" repository = "https://github.com/nymtech/nym" description = "A webassembly client which can be used to interact with the the Nym privacy platform. Wasm is used for Sphinx packet generation." diff --git a/common/client-libs/validator-client/Cargo.toml b/common/client-libs/validator-client/Cargo.toml index 052a625943..f1cd481f1d 100644 --- a/common/client-libs/validator-client/Cargo.toml +++ b/common/client-libs/validator-client/Cargo.toml @@ -26,7 +26,7 @@ reqwest = { workspace = true, features = ["json"] } thiserror = "1" log = { workspace = true } url = { version = "2.2", features = ["serde"] } -tokio = { version = "1.24.1", features = ["sync", "time"] } +tokio = { workspace = true, features = ["sync", "time"] } futures = "0.3" openssl = { version = "^0.10.55", features = ["vendored"], optional = true } diff --git a/explorer-api/explorer-api-requests/Cargo.toml b/explorer-api/explorer-api-requests/Cargo.toml index 93c8faaada..7d8dc2f803 100644 --- a/explorer-api/explorer-api-requests/Cargo.toml +++ b/explorer-api/explorer-api-requests/Cargo.toml @@ -6,7 +6,7 @@ edition = "2021" [dependencies] nym-contracts-common = { path = "../../common/cosmwasm-smart-contracts/contracts-common" } nym-mixnet-contract-common = { path = "../../common/cosmwasm-smart-contracts/mixnet-contract" } -nym-validator-client = { path = "../../common/client-libs/validator-client" } +nym-api-requests = { path = "../../nym-api/nym-api-requests" } schemars = { version = "0.8", features = ["preserve_order"] } serde = { version = "1.0", features = ["derive"] } ts-rs = { version = "6.1.2", optional = true } diff --git a/explorer-api/explorer-api-requests/src/lib.rs b/explorer-api/explorer-api-requests/src/lib.rs index bfcafa2860..6180d65f11 100644 --- a/explorer-api/explorer-api-requests/src/lib.rs +++ b/explorer-api/explorer-api-requests/src/lib.rs @@ -1,6 +1,6 @@ +use nym_api_requests::models::NodePerformance; use nym_contracts_common::Percent; use nym_mixnet_contract_common::{Addr, Coin, Layer, MixId, MixNode}; -use nym_validator_client::models::NodePerformance; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; diff --git a/nym-connect/desktop/Cargo.lock b/nym-connect/desktop/Cargo.lock index 625721abe4..b1aa136deb 100644 --- a/nym-connect/desktop/Cargo.lock +++ b/nym-connect/desktop/Cargo.lock @@ -4124,7 +4124,6 @@ version = "0.1.0" dependencies = [ "nym-contracts-common", "nym-mixnet-contract-common", - "nym-validator-client", "schemars", "serde", ] From d13c8bde5722331b5e090573582010f1cfbcbb6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Thu, 17 Aug 2023 10:21:21 +0100 Subject: [PATCH 23/24] Feature/wasm tendermint rpc client (#3744) * wasm-compatible reqwest-based rpc client * better constructors for the reqwest based client * fixed usages of the client * introduced /network/details endpoint to nym-api to return used network information (#3758) * introduced /network/details endpoint to nym-api to return used network information * introduced endpoints for nym contract information --- Cargo.lock | 4 + Cargo.toml | 3 +- clients/native/Cargo.toml | 6 +- clients/socks5/Cargo.toml | 4 +- clients/webassembly/Cargo.lock | 3 + clients/webassembly/src/client/mod.rs | 8 +- clients/webassembly/src/tester/mod.rs | 7 +- common/async-file-watcher/Cargo.toml | 2 +- common/bandwidth-controller/Cargo.toml | 2 +- common/client-core/Cargo.toml | 4 +- .../client-core/src/client/base_client/mod.rs | 2 +- common/client-libs/gateway-client/Cargo.toml | 6 +- common/client-libs/mixnet-client/Cargo.toml | 2 +- .../client-libs/validator-client/Cargo.toml | 17 +- .../validator-client/src/client.rs | 103 ++-- .../client-libs/validator-client/src/error.rs | 4 + .../client-libs/validator-client/src/lib.rs | 32 +- .../coconut_bandwidth_query_client.rs | 9 +- .../coconut_bandwidth_signing_client.rs | 6 +- .../nyxd/contract_traits/dkg_query_client.rs | 9 +- .../contract_traits/dkg_signing_client.rs | 6 +- .../contract_traits/group_query_client.rs | 9 +- .../contract_traits/group_signing_client.rs | 6 +- .../contract_traits/mixnet_query_client.rs | 37 +- .../contract_traits/mixnet_signing_client.rs | 6 +- .../contract_traits/multisig_query_client.rs | 9 +- .../multisig_signing_client.rs | 6 +- .../name_service_query_client.rs | 9 +- .../name_service_signing_client.rs | 6 +- .../sp_directory_query_client.rs | 9 +- .../sp_directory_signing_client.rs | 6 +- .../contract_traits/vesting_query_client.rs | 9 +- .../contract_traits/vesting_signing_client.rs | 6 +- .../client_traits/query_client.rs | 29 +- .../client_traits/signing_client.rs | 3 +- .../src/nyxd/cosmwasm_client/mod.rs | 14 +- .../validator-client/src/nyxd/mod.rs | 132 ++--- .../validator-client/src/nyxd/wasm.rs | 20 - .../validator-client/src/rpc/mod.rs | 514 ++++++++++++++++++ .../validator-client/src/rpc/reqwest.rs | 118 ++++ common/commands/Cargo.toml | 4 +- common/config/Cargo.toml | 2 +- common/mixnode-common/Cargo.toml | 6 +- common/network-defaults/Cargo.toml | 1 + common/network-defaults/src/lib.rs | 21 +- common/node-tester-utils/Cargo.toml | 2 +- common/socks5-client-core/Cargo.toml | 4 +- common/socks5/proxy-helpers/Cargo.toml | 2 +- common/task/Cargo.toml | 6 +- common/types/Cargo.toml | 4 +- common/types/src/error.rs | 7 + common/wasm-utils/Cargo.toml | 2 +- explorer-api/src/tasks.rs | 5 +- gateway/Cargo.toml | 2 +- gateway/gateway-requests/Cargo.toml | 2 +- mixnode/Cargo.toml | 2 +- nym-api/Cargo.toml | 9 +- nym-api/src/main.rs | 8 +- nym-api/src/network/mod.rs | 16 + nym-api/src/network/models.rs | 28 + nym-api/src/network/routes.rs | 63 +++ nym-api/src/nym_contract_cache/cache/data.rs | 31 +- nym-api/src/nym_contract_cache/cache/mod.rs | 13 + .../src/nym_contract_cache/cache/refresher.rs | 131 ++++- nym-api/src/support/caching/mod.rs | 16 +- nym-api/src/support/config/mod.rs | 16 +- nym-api/src/support/http/mod.rs | 8 +- nym-api/src/support/nyxd/mod.rs | 13 +- nym-connect/desktop/Cargo.lock | 3 + nym-connect/desktop/src-tauri/Cargo.toml | 2 +- nym-wallet/Cargo.lock | 16 + nym-wallet/src-tauri/src/error.rs | 7 +- sdk/lib/socks5-listener/Cargo.toml | 2 +- sdk/rust/nym-sdk/Cargo.toml | 6 +- .../network-requester/Cargo.toml | 2 +- 75 files changed, 1334 insertions(+), 315 deletions(-) delete mode 100644 common/client-libs/validator-client/src/nyxd/wasm.rs create mode 100644 common/client-libs/validator-client/src/rpc/mod.rs create mode 100644 common/client-libs/validator-client/src/rpc/reqwest.rs create mode 100644 nym-api/src/network/mod.rs create mode 100644 nym-api/src/network/models.rs create mode 100644 nym-api/src/network/routes.rs diff --git a/Cargo.lock b/Cargo.lock index b84d9d3f41..4ff0f9a693 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3575,6 +3575,7 @@ dependencies = [ "console-subscriber", "cosmwasm-std", "cw-utils", + "cw2", "cw3", "cw4", "dirs 4.0.0", @@ -4045,6 +4046,7 @@ dependencies = [ name = "nym-explorer-api-requests" version = "0.1.0" dependencies = [ + "nym-api-requests", "nym-contracts-common", "nym-mixnet-contract-common", "schemars", @@ -4319,6 +4321,7 @@ dependencies = [ "dotenvy", "hex-literal", "once_cell", + "schemars", "serde", "thiserror", "url", @@ -4918,6 +4921,7 @@ dependencies = [ "tokio", "ts-rs", "url", + "wasmtimer", "zeroize", ] diff --git a/Cargo.toml b/Cargo.toml index 9d609443f0..8ba5452d11 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -134,6 +134,7 @@ cw3 = { version = "=1.1.0" } cw4 = { version = "=1.1.0" } cw-controllers = { version = "=1.1.0" } dotenvy = "0.15.6" +futures = "0.3.28" generic-array = "0.14.7" getrandom = "0.2.10" k256 = "0.13" @@ -148,7 +149,7 @@ tap = "1.0.1" tendermint-rpc = "0.32" # same version as used by cosmrs thiserror = "1.0.38" tokio = "1.24.1" -url = "2.2" +url = "2.4" zeroize = "1.6.0" # wasm-related dependencies diff --git a/clients/native/Cargo.toml b/clients/native/Cargo.toml index e950db03ba..9bf16e89ad 100644 --- a/clients/native/Cargo.toml +++ b/clients/native/Cargo.toml @@ -14,11 +14,11 @@ path = "src/lib.rs" [dependencies] # dependencies to review: -futures = "0.3" # bunch of futures stuff, however, now that I think about it, it could perhaps be completely removed +futures = { workspace = true } # bunch of futures stuff, however, now that I think about it, it could perhaps be completely removed # the AsyncRead, AsyncWrite, Stream, Sink, etc. traits could be used from tokio # channels should really be replaced with crossbeam due to that implementation being more efficient # and the single instance of abortable we have should really be refactored anyway -url = "2.2" +url = { workspace = true } clap = { version = "4.0", features = ["cargo", "derive"] } dirs = "4.0" @@ -28,7 +28,7 @@ pretty_env_logger = "0.4" # for formatting log messages rand = { version = "0.7.3", features = ["wasm-bindgen"] } # rng-related traits + some rng implementation to use serde = { workspace = true, features = ["derive"] } # for config serialization/deserialization serde_json = { workspace = true } -thiserror = "1.0.34" +thiserror = { workspace = true } tap = "1.0.1" tokio = { version = "1.24.1", features = ["rt-multi-thread", "net", "signal"] } # async runtime tokio-tungstenite = "0.14" # websocket diff --git a/clients/socks5/Cargo.toml b/clients/socks5/Cargo.toml index 3e22c2f148..a574f28985 100644 --- a/clients/socks5/Cargo.toml +++ b/clients/socks5/Cargo.toml @@ -14,9 +14,9 @@ pretty_env_logger = "0.4" serde = { workspace = true, features = ["derive"] } # for config serialization/deserialization serde_json = { workspace = true } tap = "1.0.1" -thiserror = "1.0.34" +thiserror = { workspace = true } tokio = { version = "1.24.1", features = ["rt-multi-thread", "net", "signal"] } -url = "2.2" +url = { workspace = true } # internal nym-bin-common = { path = "../../common/bin-common", features = ["output_format"] } diff --git a/clients/webassembly/Cargo.lock b/clients/webassembly/Cargo.lock index 083afb5309..c5aa4a2830 100644 --- a/clients/webassembly/Cargo.lock +++ b/clients/webassembly/Cargo.lock @@ -2733,6 +2733,7 @@ dependencies = [ name = "nym-explorer-api-requests" version = "0.1.0" dependencies = [ + "nym-api-requests", "nym-contracts-common", "nym-mixnet-contract-common", "schemars", @@ -2856,6 +2857,7 @@ dependencies = [ "dotenvy", "hex-literal", "once_cell", + "schemars", "serde", "thiserror", "url", @@ -3160,6 +3162,7 @@ dependencies = [ "thiserror", "tokio", "url", + "wasmtimer", "zeroize", ] diff --git a/clients/webassembly/src/client/mod.rs b/clients/webassembly/src/client/mod.rs index 05e3809498..733521ea97 100644 --- a/clients/webassembly/src/client/mod.rs +++ b/clients/webassembly/src/client/mod.rs @@ -25,7 +25,7 @@ use nym_task::TaskManager; use nym_topology::provider_trait::{HardcodedTopologyProvider, TopologyProvider}; use nym_topology::NymTopology; use nym_validator_client::client::IdentityKey; -use nym_validator_client::QueryWasmRpcNyxdClient; +use nym_validator_client::QueryReqwestRpcNyxdClient; use rand::rngs::OsRng; use rand::RngCore; use std::sync::Arc; @@ -152,7 +152,11 @@ impl NymClientBuilder { let maybe_topology_provider = self.topology_provider(); let mut base_builder: BaseClientBuilder<_, FullWasmClientStorage> = - BaseClientBuilder::::new(&self.config.base, storage, None); + BaseClientBuilder::::new( + &self.config.base, + storage, + None, + ); if let Some(topology_provider) = maybe_topology_provider { base_builder = base_builder.with_topology_provider(topology_provider); } diff --git a/clients/webassembly/src/tester/mod.rs b/clients/webassembly/src/tester/mod.rs index c7d397f322..ba70062f3b 100644 --- a/clients/webassembly/src/tester/mod.rs +++ b/clients/webassembly/src/tester/mod.rs @@ -26,7 +26,7 @@ use nym_sphinx::preparer::PreparedFragment; use nym_task::TaskManager; use nym_topology::NymTopology; use nym_validator_client::client::IdentityKey; -use nym_validator_client::QueryWasmRpcNyxdClient; +use nym_validator_client::QueryReqwestRpcNyxdClient; use rand::rngs::OsRng; use std::collections::HashSet; use std::sync::atomic::{AtomicBool, AtomicU32, Ordering}; @@ -41,7 +41,8 @@ mod ephemeral_receiver; pub(crate) mod helpers; pub type NodeTestMessage = TestMessage; -type LockedGatewayClient = Arc>>; +type LockedGatewayClient = + Arc>>; pub(crate) const DEFAULT_TEST_TIMEOUT: Duration = Duration::from_secs(10); pub(crate) const DEFAULT_TEST_PACKETS: u32 = 20; @@ -77,7 +78,7 @@ pub struct NymNodeTesterBuilder { base_topology: NymTopology, // unimplemented - bandwidth_controller: Option>, + bandwidth_controller: Option>, } fn address(keys: &ManagedKeys, gateway_identity: NodeIdentity) -> Recipient { diff --git a/common/async-file-watcher/Cargo.toml b/common/async-file-watcher/Cargo.toml index 05e7035cf2..0a44f239cf 100644 --- a/common/async-file-watcher/Cargo.toml +++ b/common/async-file-watcher/Cargo.toml @@ -8,5 +8,5 @@ edition = "2021" [dependencies] log = "0.4" tokio = { workspace = true, features = ["time"] } -futures = "0.3" +futures = { workspace = true } notify = "5.1.0" diff --git a/common/bandwidth-controller/Cargo.toml b/common/bandwidth-controller/Cargo.toml index 7c372063de..3ce1f01454 100644 --- a/common/bandwidth-controller/Cargo.toml +++ b/common/bandwidth-controller/Cargo.toml @@ -9,7 +9,7 @@ edition = "2021" bip39 = { workspace = true } rand = "0.7.3" thiserror = "1.0" -url = "2.2" +url = { workspace = true } nym-coconut-interface = { path = "../coconut-interface" } nym-credential-storage = { path = "../credential-storage" } diff --git a/common/client-core/Cargo.toml b/common/client-core/Cargo.toml index af45a71737..bcb21899fe 100644 --- a/common/client-core/Cargo.toml +++ b/common/client-core/Cargo.toml @@ -12,7 +12,7 @@ async-trait = { workspace = true } base64 = "0.21.2" dashmap = "5.4.0" dirs = "4.0" -futures = "0.3" +futures = { workspace = true } humantime-serde = "1.0" log = { workspace = true } rand = { version = "0.7.3", features = ["wasm-bindgen"] } @@ -25,7 +25,7 @@ thiserror = "1.0.34" time = "0.3.17" tokio = { version = "1.24.1", features = ["macros"]} tungstenite = { version = "0.13.0", default-features = false } -url = { version ="2.2", features = ["serde"] } +url = { workspace = true, features = ["serde"] } zeroize = { workspace = true } # internal diff --git a/common/client-core/src/client/base_client/mod.rs b/common/client-core/src/client/base_client/mod.rs index 37f57fa601..2f2e7d0072 100644 --- a/common/client-core/src/client/base_client/mod.rs +++ b/common/client-core/src/client/base_client/mod.rs @@ -25,7 +25,7 @@ use crate::client::topology_control::{ }; use crate::config::{Config, DebugConfig}; use crate::error::ClientCoreError; -use crate::init::{setup_gateway, GatewaySetup, InitialisationDetails}; +use crate::init::{setup_gateway, GatewaySetup, InitialisationDetails, InitialisationResult}; use crate::{config, spawn_future}; use futures::channel::mpsc; use log::{debug, info}; diff --git a/common/client-libs/gateway-client/Cargo.toml b/common/client-libs/gateway-client/Cargo.toml index ef8d324531..3f8f4ac0e4 100644 --- a/common/client-libs/gateway-client/Cargo.toml +++ b/common/client-libs/gateway-client/Cargo.toml @@ -9,10 +9,10 @@ edition = "2021" [dependencies] # TODO: (for this and other crates), similarly to 'tokio', import only required "futures" modules rather than # the entire crate -futures = "0.3" +futures = { workspace = true } log = { workspace = true } -thiserror = "1.0" -url = "2.2" +thiserror = { workspace = true } +url = { workspace = true } rand = { version = "0.7.3", features = ["wasm-bindgen"] } tokio = { version = "1.24.1", features = ["macros"] } diff --git a/common/client-libs/mixnet-client/Cargo.toml b/common/client-libs/mixnet-client/Cargo.toml index fabcca892d..9eede069da 100644 --- a/common/client-libs/mixnet-client/Cargo.toml +++ b/common/client-libs/mixnet-client/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -futures = "0.3" +futures = { workspace = true } log = { workspace = true } tokio = { version = "1.24.1", features = ["time", "net", "rt"] } tokio-util = { version = "0.7.4", features = ["codec"] } diff --git a/common/client-libs/validator-client/Cargo.toml b/common/client-libs/validator-client/Cargo.toml index f1cd481f1d..952d106e97 100644 --- a/common/client-libs/validator-client/Cargo.toml +++ b/common/client-libs/validator-client/Cargo.toml @@ -23,11 +23,11 @@ nym-service-provider-directory-common = { path = "../../cosmwasm-smart-contracts serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true } reqwest = { workspace = true, features = ["json"] } -thiserror = "1" +thiserror = { workspace = true } log = { workspace = true } -url = { version = "2.2", features = ["serde"] } +url = { workspace = true, features = ["serde"] } tokio = { workspace = true, features = ["sync", "time"] } -futures = "0.3" +futures = { workspace = true } openssl = { version = "^0.10.55", features = ["vendored"], optional = true } nym-coconut-interface = { path = "../../coconut-interface" } @@ -53,14 +53,17 @@ prost = { version = "0.11", default-features = false } flate2 = { version = "1.0.20" } sha2 = { version = "0.9.5" } itertools = { version = "0.10" } -zeroize = { version = "1.5.7", features = ["zeroize_derive"] } +zeroize = { workspace = true, features = ["zeroize_derive"] } cosmwasm-std = { workspace = true } +# required for polling for broadcast result +[target."cfg(target_arch = \"wasm32\")".dependencies.wasmtimer] +workspace = true +features = ["tokio"] + [dev-dependencies] bip39 = { workspace = true } -#cosmrs = { workspace = true, features = ["rpc", "bip32"] } cosmrs = { workspace = true, features = ["bip32"] } -tokio = { version = "1.24.1", features = ["rt-multi-thread", "macros"] } ts-rs = "6.1.2" [[example]] @@ -72,12 +75,10 @@ required-features = ["http-client"] [[example]] name = "query_service_provider_directory" -# TODO: validate the requirements required-features = ["http-client"] [[example]] name = "query_name_service" -# TODO: validate the requirements required-features = ["http-client"] [features] diff --git a/common/client-libs/validator-client/src/client.rs b/common/client-libs/validator-client/src/client.rs index 5106c1c9ae..e70cbdaf2f 100644 --- a/common/client-libs/validator-client/src/client.rs +++ b/common/client-libs/validator-client/src/client.rs @@ -1,10 +1,13 @@ // Copyright 2021-2023 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use crate::nyxd::contract_traits::NymContractsProvider; use crate::nyxd::{self, NyxdClient}; -use crate::signing::signer::NoSigner; -use crate::{nym_api, ValidatorClientError}; +use crate::signing::direct_wallet::DirectSecp256k1HdWallet; +use crate::signing::signer::{NoSigner, OfflineSigner}; +use crate::{ + nym_api, DirectSigningReqwestRpcValidatorClient, QueryReqwestRpcValidatorClient, + ReqwestRpcClient, ValidatorClientError, +}; use nym_api_requests::coconut::{ BlindSignRequestBody, BlindedSignatureResponse, VerifyCredentialBody, VerifyCredentialResponse, }; @@ -24,9 +27,7 @@ pub use nym_mixnet_contract_common::{ pub use crate::coconut::CoconutApiClient; #[cfg(feature = "http-client")] -use crate::signing::direct_wallet::DirectSecp256k1HdWallet; -#[cfg(feature = "http-client")] -use tendermint_rpc::HttpClient; +use crate::{DirectSigningHttpRpcValidatorClient, HttpRpcClient, QueryHttpRpcValidatorClient}; #[must_use] #[derive(Debug, Clone)] @@ -89,22 +90,18 @@ pub struct Client { } #[cfg(feature = "http-client")] -impl Client { +impl Client { pub fn new_signing( config: Config, mnemonic: bip39::Mnemonic, - ) -> Result, ValidatorClientError> { - let nym_api_client = nym_api::Client::new(config.api_url.clone()); - let nyxd_client = NyxdClient::connect_with_mnemonic( - config.nyxd_config.clone(), - config.nyxd_url.as_str(), - mnemonic, - )?; + ) -> Result { + let rpc_client = HttpRpcClient::new(config.nyxd_url.as_str())?; + let prefix = &config.nyxd_config.chain_details.bech32_account_prefix; + let wallet = DirectSecp256k1HdWallet::from_mnemonic(prefix, mnemonic); - Ok(Client { - nym_api: nym_api_client, - nyxd: nyxd_client, - }) + Ok(Self::new_signing_with_rpc_client( + config, rpc_client, wallet, + )) } pub fn change_nyxd(&mut self, new_endpoint: Url) -> Result<(), ValidatorClientError> { @@ -113,17 +110,24 @@ impl Client { } } -#[cfg(feature = "http-client")] -impl Client { - pub fn new_query(config: Config) -> Result, ValidatorClientError> { - let nym_api_client = nym_api::Client::new(config.api_url.clone()); - let nyxd_client = - NyxdClient::connect(config.nyxd_config.clone(), config.nyxd_url.as_str())?; +impl Client { + pub fn new_reqwest_signing( + config: Config, + mnemonic: bip39::Mnemonic, + ) -> DirectSigningReqwestRpcValidatorClient { + let rpc_client = ReqwestRpcClient::new(config.nyxd_url.clone()); + let prefix = &config.nyxd_config.chain_details.bech32_account_prefix; + let wallet = DirectSecp256k1HdWallet::from_mnemonic(prefix, mnemonic); - Ok(Client { - nym_api: nym_api_client, - nyxd: nyxd_client, - }) + Self::new_signing_with_rpc_client(config, rpc_client, wallet) + } +} + +#[cfg(feature = "http-client")] +impl Client { + pub fn new_query(config: Config) -> Result { + let rpc_client = HttpRpcClient::new(config.nyxd_url.as_str())?; + Ok(Self::new_with_rpc_client(config, rpc_client)) } pub fn change_nyxd(&mut self, new_endpoint: Url) -> Result<(), ValidatorClientError> { @@ -132,24 +136,35 @@ impl Client { } } -// nyxd wrappers -impl Client { - // use case: somebody initialised client without a contract in order to upload and initialise one - // and now they want to actually use it without making new client - - #[deprecated] - pub fn set_mixnet_contract_address(&mut self, mixnet_contract_address: cosmrs::AccountId) { - self.nyxd - .set_mixnet_contract_address(mixnet_contract_address) +impl Client { + pub fn new_reqwest_query(config: Config) -> QueryReqwestRpcValidatorClient { + let rpc_client = ReqwestRpcClient::new(config.nyxd_url.clone()); + Self::new_with_rpc_client(config, rpc_client) } +} - #[deprecated] - pub fn get_mixnet_contract_address(&self) -> cosmrs::AccountId { - // TODO: deal with the expect - self.nyxd - .mixnet_contract_address() - .expect("mixnet contract address is not available") - .clone() +impl Client { + pub fn new_with_rpc_client(config: Config, rpc_client: C) -> Self { + let nym_api_client = nym_api::Client::new(config.api_url.clone()); + + Client { + nym_api: nym_api_client, + nyxd: NyxdClient::new(config.nyxd_config, rpc_client), + } + } +} + +impl Client { + pub fn new_signing_with_rpc_client(config: Config, rpc_client: C, signer: S) -> Self + where + S: OfflineSigner, + { + let nym_api_client = nym_api::Client::new(config.api_url.clone()); + + Client { + nym_api: nym_api_client, + nyxd: NyxdClient::new_signing(config.nyxd_config, rpc_client, signer), + } } } diff --git a/common/client-libs/validator-client/src/error.rs b/common/client-libs/validator-client/src/error.rs index a675a27717..d439a86848 100644 --- a/common/client-libs/validator-client/src/error.rs +++ b/common/client-libs/validator-client/src/error.rs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use crate::nym_api; +pub use tendermint_rpc::error::Error as TendermintRpcError; use thiserror::Error; #[derive(Error, Debug)] @@ -12,6 +13,9 @@ pub enum ValidatorClientError { source: nym_api::error::NymAPIError, }, + #[error("Tendermint RPC request failure: {0}")] + TendermintErrorRpc(#[from] TendermintRpcError), + #[error("One of the provided URLs was malformed - {0}")] MalformedUrlProvided(#[from] url::ParseError), diff --git a/common/client-libs/validator-client/src/lib.rs b/common/client-libs/validator-client/src/lib.rs index 86989833f5..c6391673a0 100644 --- a/common/client-libs/validator-client/src/lib.rs +++ b/common/client-libs/validator-client/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2021 - Nym Technologies SA +// Copyright 2021-2023 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 pub mod client; @@ -8,26 +8,24 @@ pub mod connection_tester; pub mod error; pub mod nym_api; pub mod nyxd; +pub mod rpc; pub mod signing; pub use crate::error::ValidatorClientError; +pub use crate::rpc::reqwest::ReqwestRpcClient; +pub use crate::signing::direct_wallet::DirectSecp256k1HdWallet; pub use client::NymApiClient; pub use client::{Client, CoconutApiClient, Config}; pub use nym_api_requests::*; +#[cfg(feature = "http-client")] +pub use cosmrs::rpc::HttpClient as HttpRpcClient; + // some type aliasing pub type ValidatorClient = Client; pub type SigningValidatorClient = Client; -#[cfg(feature = "http-client")] -pub use cosmrs::rpc::HttpClient as HttpRpcClient; - -#[cfg(target_arch = "wasm32")] -pub use crate::nyxd::wasm::WasmRpcClient; - -use crate::signing::direct_wallet::DirectSecp256k1HdWallet; - #[cfg(feature = "http-client")] pub type QueryHttpRpcValidatorClient = Client; #[cfg(feature = "http-client")] @@ -38,15 +36,9 @@ pub type DirectSigningHttpRpcValidatorClient = Client; -// TODO: the same for reqwest client (once implemented) +pub type QueryReqwestRpcValidatorClient = Client; +pub type QueryReqwestRpcNyxdClient = nyxd::NyxdClient; -// TODO: rename it to whatever we end up using in wasm -#[cfg(target_arch = "wasm32")] -pub type QueryWasmRpcValidatorClient = Client; -#[cfg(target_arch = "wasm32")] -pub type QueryWasmRpcNyxdClient = nyxd::NyxdClient; - -#[cfg(target_arch = "wasm32")] -pub type DirectSigningWasmRpcValidatorClient = Client; -#[cfg(target_arch = "wasm32")] -pub type DirectSigningWasmRpcNyxdClient = nyxd::NyxdClient; +pub type DirectSigningReqwestRpcValidatorClient = Client; +pub type DirectSigningReqwestRpcNyxdClient = + nyxd::NyxdClient; diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/coconut_bandwidth_query_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/coconut_bandwidth_query_client.rs index e26863fbe9..1737edf613 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/coconut_bandwidth_query_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/coconut_bandwidth_query_client.rs @@ -12,7 +12,8 @@ use nym_coconut_bandwidth_contract_common::spend_credential::{ }; use serde::Deserialize; -#[async_trait] +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] pub trait CoconutBandwidthQueryClient { async fn query_coconut_bandwidth_contract( &self, @@ -44,7 +45,8 @@ pub trait CoconutBandwidthQueryClient { } } -#[async_trait] +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] pub trait PagedCoconutBandwidthQueryClient: CoconutBandwidthQueryClient { async fn get_all_spent_credentials(&self) -> Result, NyxdError> { collect_paged!(self, get_all_spent_credential_paged, spend_credentials) @@ -54,7 +56,8 @@ pub trait PagedCoconutBandwidthQueryClient: CoconutBandwidthQueryClient { #[async_trait] impl PagedCoconutBandwidthQueryClient for T where T: CoconutBandwidthQueryClient {} -#[async_trait] +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] impl CoconutBandwidthQueryClient for C where C: CosmWasmClient + NymContractsProvider + Send + Sync, diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/coconut_bandwidth_signing_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/coconut_bandwidth_signing_client.rs index e9c43e6fca..030d78b29a 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/coconut_bandwidth_signing_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/coconut_bandwidth_signing_client.rs @@ -12,7 +12,8 @@ use nym_coconut_bandwidth_contract_common::{ deposit::DepositData, msg::ExecuteMsg as CoconutBandwidthExecuteMsg, }; -#[async_trait] +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] pub trait CoconutBandwidthSigningClient { async fn execute_coconut_bandwidth_contract( &self, @@ -82,7 +83,8 @@ pub trait CoconutBandwidthSigningClient { } } -#[async_trait] +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] impl CoconutBandwidthSigningClient for C where C: SigningCosmWasmClient + NymContractsProvider + Sync, 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 2a569127e3..d3ac4807e8 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 @@ -15,7 +15,8 @@ use nym_coconut_dkg_common::types::{DealerDetails, Epoch, EpochId, InitialReplac use nym_coconut_dkg_common::verification_key::{ContractVKShare, PagedVKSharesResponse}; use serde::Deserialize; -#[async_trait] +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] pub trait DkgQueryClient { async fn query_dkg_contract(&self, query: DkgQueryMsg) -> Result where @@ -94,7 +95,8 @@ pub trait DkgQueryClient { // extension trait to the query client to deal with the paged queries // (it didn't feel appropriate to combine it with the existing trait -#[async_trait] +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] pub trait PagedDkgQueryClient: DkgQueryClient { async fn get_all_current_dealers(&self) -> Result, NyxdError> { collect_paged!(self, get_current_dealers_paged, dealers) @@ -119,7 +121,8 @@ pub trait PagedDkgQueryClient: DkgQueryClient { #[async_trait] impl PagedDkgQueryClient for T where T: DkgQueryClient {} -#[async_trait] +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] impl DkgQueryClient for C where C: CosmWasmClient + NymContractsProvider + Send + Sync, diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/dkg_signing_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/dkg_signing_client.rs index 9ecf476743..73bce467b7 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/dkg_signing_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/dkg_signing_client.rs @@ -14,7 +14,8 @@ use nym_coconut_dkg_common::types::EncodedBTEPublicKeyWithProof; use nym_coconut_dkg_common::verification_key::VerificationKeyShare; use nym_contracts_common::dealings::ContractSafeBytes; -#[async_trait] +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] pub trait DkgSigningClient { async fn execute_dkg_contract( &self, @@ -107,7 +108,8 @@ pub trait DkgSigningClient { } } -#[async_trait] +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] impl DkgSigningClient for C where C: SigningCosmWasmClient + NymContractsProvider + Sync, diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/group_query_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/group_query_client.rs index 580f1ccefd..8513dfa5bb 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/group_query_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/group_query_client.rs @@ -9,7 +9,8 @@ use cw4::{Member, MemberListResponse, MemberResponse, TotalWeightResponse}; use nym_group_contract_common::msg::QueryMsg as GroupQueryMsg; use serde::Deserialize; -#[async_trait] +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] pub trait GroupQueryClient { async fn query_group_contract(&self, query: GroupQueryMsg) -> Result where @@ -47,7 +48,8 @@ pub trait GroupQueryClient { } } -#[async_trait] +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] pub trait PagedGroupQueryClient: GroupQueryClient { // can't use the macro due to different paging behaviour async fn get_all_members(&self) -> Result, NyxdError> { @@ -74,7 +76,8 @@ pub trait PagedGroupQueryClient: GroupQueryClient { #[async_trait] impl PagedGroupQueryClient for T where T: GroupQueryClient {} -#[async_trait] +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] impl GroupQueryClient for C where C: CosmWasmClient + NymContractsProvider + Send + Sync, diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/group_signing_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/group_signing_client.rs index 07d14200d7..5ac1954849 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/group_signing_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/group_signing_client.rs @@ -10,7 +10,8 @@ use async_trait::async_trait; use cw4::Member; use nym_group_contract_common::msg::ExecuteMsg as GroupExecuteMsg; -#[async_trait] +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] pub trait GroupSigningClient { async fn execute_group_contract( &self, @@ -74,7 +75,8 @@ pub trait GroupSigningClient { } } -#[async_trait] +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] impl GroupSigningClient for C where C: SigningCosmWasmClient + NymContractsProvider + Sync, diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/mixnet_query_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/mixnet_query_client.rs index 09793e3eb1..95d692d592 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/mixnet_query_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/mixnet_query_client.rs @@ -8,22 +8,20 @@ use crate::nyxd::CosmWasmClient; use async_trait::async_trait; use cosmrs::AccountId; use nym_contracts_common::signing::Nonce; -use nym_contracts_common::IdentityKeyRef; -use nym_mixnet_contract_common::delegation::{MixNodeDelegationResponse, OwnerProxySubKey}; -use nym_mixnet_contract_common::families::{Family, FamilyHead}; -use nym_mixnet_contract_common::mixnode::{ - MixnodeRewardingDetailsResponse, PagedMixnodesDetailsResponse, PagedUnbondedMixnodesResponse, - StakeSaturationResponse, UnbondedMixnodeResponse, -}; -use nym_mixnet_contract_common::reward_params::{Performance, RewardingParams}; -use nym_mixnet_contract_common::rewarding::{ - EstimatedCurrentEpochRewardResponse, PendingRewardResponse, -}; use nym_mixnet_contract_common::{ - delegation, ContractBuildInformation, ContractState, ContractStateParams, - CurrentIntervalResponse, Delegation, EpochEventId, EpochStatus, FamilyByHeadResponse, - FamilyByLabelResponse, FamilyMembersByHeadResponse, FamilyMembersByLabelResponse, GatewayBond, - GatewayBondResponse, GatewayOwnershipResponse, IdentityKey, IntervalEventId, LayerDistribution, + delegation, + delegation::{MixNodeDelegationResponse, OwnerProxySubKey}, + families::{Family, FamilyHead}, + mixnode::{ + MixnodeRewardingDetailsResponse, PagedMixnodesDetailsResponse, + PagedUnbondedMixnodesResponse, StakeSaturationResponse, UnbondedMixnodeResponse, + }, + reward_params::{Performance, RewardingParams}, + rewarding::{EstimatedCurrentEpochRewardResponse, PendingRewardResponse}, + ContractBuildInformation, ContractState, ContractStateParams, CurrentIntervalResponse, + Delegation, EpochEventId, EpochStatus, FamilyByHeadResponse, FamilyByLabelResponse, + FamilyMembersByHeadResponse, FamilyMembersByLabelResponse, GatewayBond, GatewayBondResponse, + GatewayOwnershipResponse, IdentityKey, IdentityKeyRef, IntervalEventId, LayerDistribution, MixId, MixNodeBond, MixNodeDetails, MixOwnershipResponse, MixnodeDetailsByIdentityResponse, MixnodeDetailsResponse, NumberOfPendingEventsResponse, PagedAllDelegationsResponse, PagedDelegatorDelegationsResponse, PagedFamiliesResponse, PagedGatewayResponse, @@ -35,7 +33,8 @@ use nym_mixnet_contract_common::{ }; use serde::Deserialize; -#[async_trait] +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] pub trait MixnetQueryClient { async fn query_mixnet_contract(&self, query: MixnetQueryMsg) -> Result where @@ -467,7 +466,8 @@ pub trait MixnetQueryClient { // extension trait to the query client to deal with the paged queries // (it didn't feel appropriate to combine it with the existing trait -#[async_trait] +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] pub trait PagedMixnetQueryClient: MixnetQueryClient { async fn get_all_node_families(&self) -> Result, NyxdError> { collect_paged!(self, get_all_node_families_paged, families) @@ -550,7 +550,8 @@ pub trait PagedMixnetQueryClient: MixnetQueryClient { #[async_trait] impl PagedMixnetQueryClient for T where T: MixnetQueryClient {} -#[async_trait] +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] impl MixnetQueryClient for C where C: CosmWasmClient + NymContractsProvider + Send + Sync, diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/mixnet_signing_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/mixnet_signing_client.rs index ad7d03327c..f8b5521e0d 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/mixnet_signing_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/mixnet_signing_client.rs @@ -19,7 +19,8 @@ use nym_mixnet_contract_common::{ MixNode, }; -#[async_trait] +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] pub trait MixnetSigningClient { async fn execute_mixnet_contract( &self, @@ -695,7 +696,8 @@ pub trait MixnetSigningClient { } } -#[async_trait] +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] impl MixnetSigningClient for C where C: SigningCosmWasmClient + NymContractsProvider + Sync, diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/multisig_query_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/multisig_query_client.rs index b7d180f4a1..48fcadc050 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/multisig_query_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/multisig_query_client.rs @@ -13,7 +13,8 @@ use cw_utils::ThresholdResponse; use nym_multisig_contract_common::msg::QueryMsg as MultisigQueryMsg; use serde::Deserialize; -#[async_trait] +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] pub trait MultisigQueryClient { async fn query_multisig_contract(&self, query: MultisigQueryMsg) -> Result where @@ -90,7 +91,8 @@ pub trait MultisigQueryClient { // extension trait to the query client to deal with the paged queries // (it didn't feel appropriate to combine it with the existing trait -#[async_trait] +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] pub trait PagedMultisigQueryClient: MultisigQueryClient { // can't use the macro due to different paging behaviour async fn get_all_proposals(&self) -> Result, NyxdError> { @@ -117,7 +119,8 @@ pub trait PagedMultisigQueryClient: MultisigQueryClient { #[async_trait] impl PagedMultisigQueryClient for T where T: MultisigQueryClient {} -#[async_trait] +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] impl MultisigQueryClient for C where C: CosmWasmClient + NymContractsProvider + Send + Sync, diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/multisig_signing_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/multisig_signing_client.rs index 0da2fd9de8..f7249f02ea 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/multisig_signing_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/multisig_signing_client.rs @@ -13,7 +13,8 @@ use cw4::{MemberChangedHookMsg, MemberDiff}; use nym_coconut_bandwidth_contract_common::msg::ExecuteMsg as CoconutBandwidthExecuteMsg; use nym_multisig_contract_common::msg::ExecuteMsg as MultisigExecuteMsg; -#[async_trait] +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] pub trait MultisigSigningClient: NymContractsProvider { async fn execute_multisig_contract( &self, @@ -124,7 +125,8 @@ pub trait MultisigSigningClient: NymContractsProvider { } } -#[async_trait] +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] impl MultisigSigningClient for C where C: SigningCosmWasmClient + NymContractsProvider + Sync, diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/name_service_query_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/name_service_query_client.rs index d5a65b8e66..60071f674d 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/name_service_query_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/name_service_query_client.rs @@ -14,7 +14,8 @@ use nym_name_service_common::{ }; use serde::Deserialize; -#[async_trait] +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] pub trait NameServiceQueryClient { async fn query_name_service_contract(&self, query: NameQueryMsg) -> Result where @@ -78,7 +79,8 @@ pub trait NameServiceQueryClient { } } -#[async_trait] +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] pub trait PagedNameServiceQueryClient: NameServiceQueryClient { async fn get_all_names(&self) -> Result, NyxdError> { collect_paged!(self, get_names_paged, names) @@ -88,7 +90,8 @@ pub trait PagedNameServiceQueryClient: NameServiceQueryClient { #[async_trait] impl PagedNameServiceQueryClient for T where T: NameServiceQueryClient {} -#[async_trait] +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] impl NameServiceQueryClient for C where C: CosmWasmClient + NymContractsProvider + Send + Sync, diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/name_service_signing_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/name_service_signing_client.rs index bc5a06e1a9..0a363f991b 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/name_service_signing_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/name_service_signing_client.rs @@ -11,7 +11,8 @@ use crate::nyxd::{ }; use crate::signing::signer::OfflineSigner; -#[async_trait] +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] pub trait NameServiceSigningClient { async fn execute_name_service_contract( &self, @@ -72,7 +73,8 @@ pub trait NameServiceSigningClient { } } -#[async_trait] +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] impl NameServiceSigningClient for C where C: SigningCosmWasmClient + NymContractsProvider + Sync, diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/sp_directory_query_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/sp_directory_query_client.rs index 47a56f9080..09279c543a 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/sp_directory_query_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/sp_directory_query_client.rs @@ -14,7 +14,8 @@ use serde::Deserialize; use crate::nyxd::contract_traits::NymContractsProvider; use crate::nyxd::{error::NyxdError, CosmWasmClient}; -#[async_trait] +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] pub trait SpDirectoryQueryClient { async fn query_service_provider_contract(&self, query: SpQueryMsg) -> Result where @@ -78,7 +79,8 @@ pub trait SpDirectoryQueryClient { } } -#[async_trait] +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] pub trait PagedSpDirectoryQueryClient: SpDirectoryQueryClient { async fn get_all_services(&self) -> Result, NyxdError> { collect_paged!(self, get_services_paged, services) @@ -88,7 +90,8 @@ pub trait PagedSpDirectoryQueryClient: SpDirectoryQueryClient { #[async_trait] impl PagedSpDirectoryQueryClient for T where T: SpDirectoryQueryClient {} -#[async_trait] +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] impl SpDirectoryQueryClient for C where C: CosmWasmClient + NymContractsProvider + Send + Sync, diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/sp_directory_signing_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/sp_directory_signing_client.rs index 9d0f3f458a..c1efde20f5 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/sp_directory_signing_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/sp_directory_signing_client.rs @@ -12,7 +12,8 @@ use nym_service_provider_directory_common::{ msg::ExecuteMsg as SpExecuteMsg, NymAddress, ServiceDetails, ServiceId, }; -#[async_trait] +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] pub trait SpDirectorySigningClient { async fn execute_service_provider_directory_contract( &self, @@ -81,7 +82,8 @@ pub trait SpDirectorySigningClient { } } -#[async_trait] +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] impl SpDirectorySigningClient for C where C: SigningCosmWasmClient + NymContractsProvider + Sync, diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/vesting_query_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/vesting_query_client.rs index 2a5b587f93..fa6bd643fa 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/vesting_query_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/vesting_query_client.rs @@ -17,7 +17,8 @@ use nym_vesting_contract_common::{ }; use serde::Deserialize; -#[async_trait] +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] pub trait VestingQueryClient { async fn query_vesting_contract(&self, query: VestingQueryMsg) -> Result where @@ -282,7 +283,8 @@ pub trait VestingQueryClient { } } -#[async_trait] +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] pub trait PagedVestingQueryClient: VestingQueryClient { async fn get_all_vesting_delegations(&self) -> Result, NyxdError> { collect_paged!(self, get_all_vesting_delegations_paged, delegations) @@ -300,7 +302,8 @@ pub trait PagedVestingQueryClient: VestingQueryClient { #[async_trait] impl PagedVestingQueryClient for T where T: VestingQueryClient {} -#[async_trait] +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] impl VestingQueryClient for C where C: CosmWasmClient + NymContractsProvider + Send + Sync, diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/vesting_signing_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/vesting_signing_client.rs index b540d3b3f9..11c449fccd 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/vesting_signing_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/vesting_signing_client.rs @@ -16,7 +16,8 @@ use nym_mixnet_contract_common::{Gateway, MixId, MixNode}; use nym_vesting_contract_common::messages::ExecuteMsg as VestingExecuteMsg; use nym_vesting_contract_common::{PledgeCap, VestingSpecification}; -#[async_trait] +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] pub trait VestingSigningClient { async fn execute_vesting_contract( &self, @@ -399,7 +400,8 @@ pub trait VestingSigningClient { } } -#[async_trait] +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] impl VestingSigningClient for C where C: SigningCosmWasmClient + NymContractsProvider + Sync, 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 46073a2671..69e94b3387 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 @@ -8,7 +8,7 @@ use crate::nyxd::cosmwasm_client::types::{ Account, CodeDetails, Contract, ContractCodeId, SequenceResponse, SimulateResponse, }; use crate::nyxd::error::NyxdError; -use crate::nyxd::TendermintClient; +use crate::rpc::TendermintRpcClient; use async_trait::async_trait; use cosmrs::cosmwasm::{CodeInfoResponse, ContractCodeHistoryEntry}; use cosmrs::proto::cosmos::auth::v1beta1::{QueryAccountRequest, QueryAccountResponse}; @@ -39,6 +39,16 @@ use tendermint_rpc::{ Order, }; +#[cfg(not(target_arch = "wasm32"))] +use tokio::time::sleep; +#[cfg(not(target_arch = "wasm32"))] +use tokio::time::Instant; + +#[cfg(target_arch = "wasm32")] +use wasmtimer::std::Instant; +#[cfg(target_arch = "wasm32")] +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); @@ -46,8 +56,9 @@ pub const DEFAULT_BROADCAST_TIMEOUT: Duration = Duration::from_secs(60); #[async_trait] impl CosmWasmClient for cosmrs::rpc::HttpClient {} -#[async_trait] -pub trait CosmWasmClient: TendermintClient { +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] +pub trait CosmWasmClient: TendermintRpcClient { // helper method to remove duplicate code involved in making abci requests with protobuf messages // TODO: perhaps it should have an additional argument to determine whether the response should // require proof? @@ -236,7 +247,7 @@ pub trait CosmWasmClient: TendermintClient { where T: Into> + Send, { - Ok(tendermint_rpc::client::Client::broadcast_tx_async(self, tx).await?) + Ok(TendermintRpcClient::broadcast_tx_async(self, tx).await?) } /// Broadcast a transaction, returning the response from `CheckTx`. @@ -244,7 +255,7 @@ pub trait CosmWasmClient: TendermintClient { where T: Into> + Send, { - Ok(tendermint_rpc::client::Client::broadcast_tx_sync(self, tx).await?) + Ok(TendermintRpcClient::broadcast_tx_sync(self, tx).await?) } /// Broadcast a transaction, returning the response from `DeliverTx`. @@ -255,7 +266,7 @@ pub trait CosmWasmClient: TendermintClient { where T: Into> + Send, { - Ok(tendermint_rpc::client::Client::broadcast_tx_commit(self, tx).await?) + Ok(TendermintRpcClient::broadcast_tx_commit(self, tx).await?) } async fn broadcast_tx( @@ -286,13 +297,13 @@ pub trait CosmWasmClient: TendermintClient { let tx_hash = broadcasted.hash; - let start = tokio::time::Instant::now(); + let start = Instant::now(); loop { log::debug!( "Polling for result of including {} in a block...", broadcasted.hash ); - if tokio::time::Instant::now().duration_since(start) >= timeout { + if Instant::now().duration_since(start) >= timeout { return Err(NyxdError::BroadcastTimeout { hash: tx_hash, timeout, @@ -303,7 +314,7 @@ pub trait CosmWasmClient: TendermintClient { return Ok(poll_res); } - tokio::time::sleep(poll_interval).await; + sleep(poll_interval).await; } } 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 4f6f3a9772..5b3deadb68 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 @@ -53,7 +53,8 @@ fn single_unspecified_signer_auth( .auth_info(empty_fee()) } -#[async_trait] +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] pub trait SigningCosmWasmClient: CosmWasmClient + TxSigner where NyxdError: From<::Error>, 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 c082468486..7ebff2ef16 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 @@ -3,7 +3,8 @@ use crate::nyxd::cosmwasm_client::client_traits::{CosmWasmClient, SigningCosmWasmClient}; use crate::nyxd::error::NyxdError; -use crate::nyxd::{Config, GasPrice, TendermintClient}; +use crate::nyxd::{Config, GasPrice}; +use crate::rpc::TendermintRpcClient; use crate::signing::{ signer::{NoSigner, OfflineSigner}, AccountData, @@ -77,10 +78,11 @@ impl MaybeSigningClient { } } -#[async_trait] -impl TendermintClient for MaybeSigningClient +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] +impl TendermintRpcClient for MaybeSigningClient where - C: TendermintClient + Send + Sync, + C: TendermintRpcClient + Send + Sync, S: Send + Sync, { async fn perform(&self, request: R) -> Result @@ -113,7 +115,7 @@ where #[async_trait] impl CosmWasmClient for MaybeSigningClient where - C: TendermintClient + Send + Sync, + C: TendermintRpcClient + Send + Sync, S: Send + Sync, { } @@ -121,7 +123,7 @@ where #[async_trait] impl SigningCosmWasmClient for MaybeSigningClient where - C: TendermintClient + Send + Sync, + C: TendermintRpcClient + Send + Sync, S: OfflineSigner + Send + Sync, NyxdError: From, { diff --git a/common/client-libs/validator-client/src/nyxd/mod.rs b/common/client-libs/validator-client/src/nyxd/mod.rs index 102cac80c3..d0cf1e0b3e 100644 --- a/common/client-libs/validator-client/src/nyxd/mod.rs +++ b/common/client-libs/validator-client/src/nyxd/mod.rs @@ -25,6 +25,7 @@ use tendermint_rpc::Error as TendermintRpcError; pub use crate::nyxd::cosmwasm_client::client_traits::{CosmWasmClient, SigningCosmWasmClient}; pub use crate::nyxd::fee::Fee; +pub use crate::rpc::TendermintRpcClient; pub use coin::Coin; pub use cosmrs::bank::MsgSend; pub use cosmrs::tendermint::abci::{response::DeliverTx, Event, EventAttribute}; @@ -38,18 +39,20 @@ pub use cosmrs::Gas; pub use cosmrs::{bip32, AccountId, Denom}; pub use cosmwasm_std::Coin as CosmWasmCoin; pub use fee::{gas_price::GasPrice, GasAdjustable, GasAdjustment}; -pub use tendermint_rpc::{client::Client as TendermintClient, Request, Response, SimpleRequest}; pub use tendermint_rpc::{ endpoint::{tx::Response as TxResponse, validators::Response as ValidatorResponse}, Paging, }; +pub use tendermint_rpc::{Request, Response, SimpleRequest}; -#[cfg(feature = "http-client")] +// #[cfg(feature = "http-client")] use crate::signing::direct_wallet::DirectSecp256k1HdWallet; #[cfg(feature = "http-client")] use crate::{DirectSigningHttpRpcNyxdClient, QueryHttpRpcNyxdClient}; +use crate::{DirectSigningReqwestRpcNyxdClient, QueryReqwestRpcNyxdClient, ReqwestRpcClient}; #[cfg(feature = "http-client")] use cosmrs::rpc::{HttpClient, HttpClientUrl}; +use url::Url; pub mod coin; pub mod contract_traits; @@ -57,11 +60,6 @@ pub mod cosmwasm_client; pub mod error; pub mod fee; -#[cfg(target_arch = "wasm32")] -pub mod wasm; - -// TODO: reqwest based for wasm - #[derive(Debug, Clone)] pub struct Config { pub(crate) chain_details: ChainDetails, @@ -71,30 +69,6 @@ pub struct Config { } impl Config { - // fn parse_optional_account( - // raw: Option<&String>, - // expected_prefix: &str, - // ) -> Result, NyxdError> { - // if let Some(address) = raw { - // trace!("Raw address:{:?}", raw); - // trace!("Expected prefix:{:?}", expected_prefix); - // let parsed: AccountId = address - // .parse() - // .map_err(|_| NyxdError::MalformedAccountAddress(address.clone()))?; - // debug!("Parsed prefix:{:?}", parsed); - // if parsed.prefix() != expected_prefix { - // Err(NyxdError::UnexpectedBech32Prefix { - // got: parsed.prefix().into(), - // expected: expected_prefix.into(), - // }) - // } else { - // Ok(Some(parsed)) - // } - // } else { - // Ok(None) - // } - // } - pub fn try_from_nym_network_details(details: &NymNetworkDetails) -> Result { Ok(Config { chain_details: details.chain_details.clone(), @@ -110,21 +84,13 @@ impl Config { } } -// so youd have: -// for queries: -// NyxdClient -// NyxdClient -// -// for signing: -// NyxdClient -// NyxdClient - #[derive(Debug)] pub struct NyxdClient { client: MaybeSigningClient, config: Config, } +// terrible name, but can't really change it because it will break so many uses #[cfg(feature = "http-client")] impl NyxdClient { pub fn connect(config: Config, endpoint: U) -> Result @@ -140,9 +106,32 @@ impl NyxdClient { } } +impl NyxdClient { + pub fn connect_reqwest( + config: Config, + endpoint: Url, + ) -> Result { + let client = ReqwestRpcClient::new(endpoint); + + Ok(NyxdClient { + client: MaybeSigningClient::new(client, (&config).into()), + config, + }) + } +} + +impl NyxdClient { + pub fn new(config: Config, client: C) -> Self { + NyxdClient { + client: MaybeSigningClient::new(client, (&config).into()), + config, + } + } +} + +// terrible name, but can't really change it because it will break so many uses #[cfg(feature = "http-client")] impl NyxdClient { - // TODO: rename this one pub fn connect_with_mnemonic( config: Config, endpoint: U, @@ -151,32 +140,37 @@ impl NyxdClient { where U: TryInto, { + let client = HttpClient::new(endpoint)?; + let prefix = &config.chain_details.bech32_account_prefix; let wallet = DirectSecp256k1HdWallet::from_mnemonic(prefix, mnemonic); - Self::connect_with_signer(config, endpoint, wallet) + Ok(Self::connect_with_signer(config, client, wallet)) } } -#[cfg(feature = "http-client")] -impl NyxdClient +impl NyxdClient { + pub fn connect_reqwest_with_mnemonic( + config: Config, + endpoint: Url, + mnemonic: bip39::Mnemonic, + ) -> DirectSigningReqwestRpcNyxdClient { + let client = ReqwestRpcClient::new(endpoint); + + let prefix = &config.chain_details.bech32_account_prefix; + let wallet = DirectSecp256k1HdWallet::from_mnemonic(prefix, mnemonic); + Self::connect_with_signer(config, client, wallet) + } +} + +impl NyxdClient where S: OfflineSigner, - // I have no idea why S::Error: Into bound wouldn't do the trick - NyxdError: From, { - pub fn connect_with_signer( - config: Config, - endpoint: U, - signer: S, - ) -> Result, NyxdError> - where - U: TryInto, - { - let client = HttpClient::new(endpoint)?; - Ok(NyxdClient { + pub fn connect_with_signer(config: Config, client: C, signer: S) -> NyxdClient { + NyxdClient { client: MaybeSigningClient::new_signing(client, signer, (&config).into()), config, - }) + } } } @@ -190,15 +184,6 @@ impl NyxdClient { } } -impl NyxdClient { - pub fn new(config: Config, client: C) -> Self { - NyxdClient { - client: MaybeSigningClient::new(client, (&config).into()), - config, - } - } -} - // no trait bounds impl NyxdClient { pub fn new_signing(config: Config, client: C, signer: S) -> Self @@ -289,7 +274,7 @@ impl NymContractsProvider for NyxdClient { // queries impl NyxdClient where - C: TendermintClient + Send + Sync, + C: TendermintRpcClient + Send + Sync, S: Send + Sync, { pub async fn get_account_public_key( @@ -339,7 +324,7 @@ where // signing impl NyxdClient where - C: TendermintClient + Send + Sync, + C: TendermintRpcClient + Send + Sync, S: OfflineSigner + Send + Sync, NyxdError: From<::Error>, { @@ -572,10 +557,11 @@ where // ugh. is there a way to avoid that nasty trait implementation? -#[async_trait] -impl TendermintClient for NyxdClient +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] +impl TendermintRpcClient for NyxdClient where - C: TendermintClient + Send + Sync, + C: TendermintRpcClient + Send + Sync, S: Send + Sync, { async fn perform(&self, request: R) -> Result @@ -589,7 +575,7 @@ where #[async_trait] impl CosmWasmClient for NyxdClient where - C: TendermintClient + Send + Sync, + C: TendermintRpcClient + Send + Sync, S: Send + Sync, { } @@ -616,7 +602,7 @@ where #[async_trait] impl SigningCosmWasmClient for NyxdClient where - C: TendermintClient + Send + Sync, + C: TendermintRpcClient + Send + Sync, S: TxSigner + Send + Sync, NyxdError: From, { diff --git a/common/client-libs/validator-client/src/nyxd/wasm.rs b/common/client-libs/validator-client/src/nyxd/wasm.rs deleted file mode 100644 index 4186fc54fa..0000000000 --- a/common/client-libs/validator-client/src/nyxd/wasm.rs +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2023 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 - -use crate::nyxd::TendermintClient; -use async_trait::async_trait; -use tendermint_rpc::{Error, SimpleRequest}; - -pub struct WasmRpcClient { - // -} - -#[async_trait] -impl TendermintClient for WasmRpcClient { - async fn perform(&self, _request: R) -> Result - where - R: SimpleRequest, - { - todo!() - } -} diff --git a/common/client-libs/validator-client/src/rpc/mod.rs b/common/client-libs/validator-client/src/rpc/mod.rs new file mode 100644 index 0000000000..f483f1067c --- /dev/null +++ b/common/client-libs/validator-client/src/rpc/mod.rs @@ -0,0 +1,514 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use async_trait::async_trait; +use cosmrs::tendermint::{self, abci, block::Height, evidence::Evidence, Genesis, Hash}; +use serde::{de::DeserializeOwned, Serialize}; +use std::fmt; +use tendermint_rpc::{ + endpoint::{validators::DEFAULT_VALIDATORS_PER_PAGE, *}, + query::Query, + Error, Order, Paging, SimpleRequest, +}; + +pub mod reqwest; + +// we have to create a sealed trait since `TendermintClient` needs T: Send (due to how async trait is created) +// which we can't do in wasm +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] +pub trait TendermintRpcClient { + /// `/abci_info`: get information about the ABCI application. + async fn abci_info(&self) -> Result { + Ok(self.perform(abci_info::Request).await?.response) + } + + /// `/abci_query`: query the ABCI application + async fn abci_query( + &self, + path: Option, + data: V, + height: Option, + prove: bool, + ) -> Result + where + V: Into> + Send, + { + Ok(self + .perform(abci_query::Request::new(path, data, height, prove)) + .await? + .response) + } + + /// `/block`: get block at a given height. + async fn block(&self, height: H) -> Result + where + H: Into + Send, + { + self.perform(block::Request::new(height.into())).await + } + + /// `/block_by_hash`: get block by hash. + async fn block_by_hash( + &self, + hash: tendermint::Hash, + ) -> Result { + self.perform(block_by_hash::Request::new(hash)).await + } + + /// `/block`: get the latest block. + async fn latest_block(&self) -> Result { + self.perform(block::Request::default()).await + } + + /// `/header`: get block header at a given height. + async fn header(&self, height: H) -> Result + where + H: Into + Send, + { + self.perform(header::Request::new(height.into())).await + } + + /// `/header_by_hash`: get block by hash. + async fn header_by_hash( + &self, + hash: tendermint::Hash, + ) -> Result { + self.perform(header_by_hash::Request::new(hash)).await + } + + /// `/block_results`: get ABCI results for a block at a particular height. + async fn block_results(&self, height: H) -> Result + where + H: Into + Send, + { + self.perform(block_results::Request::new(height.into())) + .await + } + + /// `/block_results`: get ABCI results for the latest block. + async fn latest_block_results(&self) -> Result { + self.perform(block_results::Request::default()).await + } + + /// `/block_search`: search for blocks by BeginBlock and EndBlock events. + async fn block_search( + &self, + query: Query, + page: u32, + per_page: u8, + order: Order, + ) -> Result { + self.perform(block_search::Request::new(query, page, per_page, order)) + .await + } + + /// `/blockchain`: get block headers for `min` <= `height` <= `max`. + /// + /// Block headers are returned in descending order (highest first). + /// + /// Returns at most 20 items. + async fn blockchain(&self, min: H, max: H) -> Result + where + H: Into + Send, + { + // TODO(tarcieri): return errors for invalid params before making request? + self.perform(blockchain::Request::new(min.into(), max.into())) + .await + } + + /// `/broadcast_tx_async`: broadcast a transaction, returning immediately. + async fn broadcast_tx_async(&self, tx: T) -> Result + where + T: Into> + Send, + { + self.perform(broadcast::tx_async::Request::new(tx)).await + } + + /// `/broadcast_tx_sync`: broadcast a transaction, returning the response + /// from `CheckTx`. + async fn broadcast_tx_sync(&self, tx: T) -> Result + where + T: Into> + Send, + { + self.perform(broadcast::tx_sync::Request::new(tx)).await + } + + /// `/broadcast_tx_commit`: broadcast a transaction, returning the response + /// from `DeliverTx`. + async fn broadcast_tx_commit(&self, tx: T) -> Result + where + T: Into> + Send, + { + self.perform(broadcast::tx_commit::Request::new(tx)).await + } + + /// `/commit`: get block commit at a given height. + async fn commit(&self, height: H) -> Result + where + H: Into + Send, + { + self.perform(commit::Request::new(height.into())).await + } + + /// `/consensus_params`: get current consensus parameters at the specified + /// height. + async fn consensus_params(&self, height: H) -> Result + where + H: Into + Send, + { + self.perform(consensus_params::Request::new(Some(height.into()))) + .await + } + + /// `/consensus_state`: get current consensus state + async fn consensus_state(&self) -> Result { + self.perform(consensus_state::Request::new()).await + } + + // TODO(thane): Simplify once validators endpoint removes pagination. + /// `/validators`: get validators a given height. + async fn validators(&self, height: H, paging: Paging) -> Result + where + H: Into + Send, + { + let height = height.into(); + match paging { + Paging::Default => { + self.perform(validators::Request::new(Some(height), None, None)) + .await + } + Paging::Specific { + page_number, + per_page, + } => { + self.perform(validators::Request::new( + Some(height), + Some(page_number), + Some(per_page), + )) + .await + } + Paging::All => { + let mut page_num = 1_usize; + let mut validators = Vec::new(); + let per_page = DEFAULT_VALIDATORS_PER_PAGE.into(); + loop { + let response = self + .perform(validators::Request::new( + Some(height), + Some(page_num.into()), + Some(per_page), + )) + .await?; + validators.extend(response.validators); + if validators.len() as i32 == response.total { + return Ok(validators::Response::new( + response.block_height, + validators, + response.total, + )); + } + page_num += 1; + } + } + } + } + + /// `/consensus_params`: get the latest consensus parameters. + async fn latest_consensus_params(&self) -> Result { + self.perform(consensus_params::Request::new(None)).await + } + + /// `/commit`: get the latest block commit + async fn latest_commit(&self) -> Result { + self.perform(commit::Request::default()).await + } + + /// `/health`: get node health. + /// + /// Returns empty result (200 OK) on success, no response in case of an error. + async fn health(&self) -> Result<(), Error> { + self.perform(health::Request).await?; + Ok(()) + } + + /// `/genesis`: get genesis file. + async fn genesis(&self) -> Result, Error> + where + AppState: fmt::Debug + Serialize + DeserializeOwned + Send, + { + Ok(self.perform(genesis::Request::default()).await?.genesis) + } + + /// `/net_info`: obtain information about P2P and other network connections. + async fn net_info(&self) -> Result { + self.perform(net_info::Request).await + } + + /// `/status`: get Tendermint status including node info, pubkey, latest + /// block hash, app hash, block height and time. + async fn status(&self) -> Result { + self.perform(status::Request).await + } + + /// `/broadcast_evidence`: broadcast an evidence. + async fn broadcast_evidence(&self, e: Evidence) -> Result { + self.perform(evidence::Request::new(e)).await + } + + /// `/tx`: find transaction by hash. + async fn tx(&self, hash: Hash, prove: bool) -> Result { + self.perform(tx::Request::new(hash, prove)).await + } + + /// `/tx_search`: search for transactions with their results. + async fn tx_search( + &self, + query: Query, + prove: bool, + page: u32, + per_page: u8, + order: Order, + ) -> Result { + self.perform(tx_search::Request::new(query, prove, page, per_page, order)) + .await + } + + #[cfg(any( + feature = "tendermint-rpc/http-client", + feature = "tendermint-rpc/websocket-client" + ))] + /// Poll the `/health` endpoint until it returns a successful result or + /// the given `timeout` has elapsed. + async fn wait_until_healthy(&self, timeout: T) -> Result<(), Error> + where + T: Into + Send, + { + let timeout = timeout.into(); + let poll_interval = core::time::Duration::from_millis(200); + let mut attempts_remaining = timeout.as_millis() / poll_interval.as_millis(); + + while self.health().await.is_err() { + if attempts_remaining == 0 { + return Err(Error::timeout(timeout)); + } + + attempts_remaining -= 1; + tokio::time::sleep(poll_interval).await; + } + + Ok(()) + } + + /// Perform a request against the RPC endpoint. + /// + /// This method is used by the default implementations of specific + /// endpoint methods. The latest protocol dialect is assumed to be invoked. + async fn perform(&self, request: R) -> Result + where + R: SimpleRequest; +} + +#[cfg(not(target_arch = "wasm32"))] +mod non_wasm { + use super::*; + use cosmrs::tendermint::abci::response::Info; + use std::fmt::Debug; + use tendermint_rpc::endpoint::abci_query::AbciQuery; + use tendermint_rpc::endpoint::block::Response; + + #[async_trait] + impl TendermintRpcClient for C + where + C: tendermint_rpc::client::Client + Sync, + { + async fn abci_info(&self) -> Result { + self.abci_info().await + } + + async fn abci_query( + &self, + path: Option, + data: V, + height: Option, + prove: bool, + ) -> Result + where + V: Into> + Send, + { + self.abci_query(path, data, height, prove).await + } + + async fn block(&self, height: H) -> Result + where + H: Into + Send, + { + self.block(height).await + } + + async fn block_by_hash(&self, hash: Hash) -> Result { + self.block_by_hash(hash).await + } + + async fn latest_block(&self) -> Result { + self.latest_block().await + } + + async fn header(&self, height: H) -> Result + where + H: Into + Send, + { + self.header(height).await + } + + async fn header_by_hash(&self, hash: Hash) -> Result { + self.header_by_hash(hash).await + } + + async fn block_results(&self, height: H) -> Result + where + H: Into + Send, + { + self.block_results(height).await + } + + async fn latest_block_results(&self) -> Result { + self.latest_block_results().await + } + + async fn block_search( + &self, + query: Query, + page: u32, + per_page: u8, + order: Order, + ) -> Result { + self.block_search(query, page, per_page, order).await + } + + async fn blockchain(&self, min: H, max: H) -> Result + where + H: Into + Send, + { + self.blockchain(min, max).await + } + + async fn broadcast_tx_async(&self, tx: T) -> Result + where + T: Into> + Send, + { + self.broadcast_tx_async(tx).await + } + + async fn broadcast_tx_sync(&self, tx: T) -> Result + where + T: Into> + Send, + { + self.broadcast_tx_sync(tx).await + } + + async fn broadcast_tx_commit( + &self, + tx: T, + ) -> Result + where + T: Into> + Send, + { + self.broadcast_tx_commit(tx).await + } + + async fn commit(&self, height: H) -> Result + where + H: Into + Send, + { + self.commit(height).await + } + + async fn consensus_params(&self, height: H) -> Result + where + H: Into + Send, + { + self.consensus_params(height).await + } + + async fn consensus_state(&self) -> Result { + self.consensus_state().await + } + + async fn validators( + &self, + height: H, + paging: Paging, + ) -> Result + where + H: Into + Send, + { + self.validators(height, paging).await + } + + async fn latest_consensus_params(&self) -> Result { + self.latest_consensus_params().await + } + + async fn latest_commit(&self) -> Result { + self.latest_commit().await + } + + async fn health(&self) -> Result<(), Error> { + self.health().await + } + + async fn genesis(&self) -> Result, Error> + where + AppState: Debug + Serialize + DeserializeOwned + Send, + { + self.genesis().await + } + + async fn net_info(&self) -> Result { + self.net_info().await + } + + async fn status(&self) -> Result { + self.status().await + } + + async fn broadcast_evidence(&self, e: Evidence) -> Result { + self.broadcast_evidence(e).await + } + + async fn tx(&self, hash: Hash, prove: bool) -> Result { + self.tx(hash, prove).await + } + + async fn tx_search( + &self, + query: Query, + prove: bool, + page: u32, + per_page: u8, + order: Order, + ) -> Result { + self.tx_search(query, prove, page, per_page, order).await + } + + #[cfg(any( + feature = "tendermint-rpc/http-client", + feature = "tendermint-rpc/websocket-client" + ))] + async fn wait_until_healthy(&self, timeout: T) -> Result<(), Error> + where + T: Into + Send, + { + self.wait_until_healthy(timeout).await + } + + async fn perform(&self, request: R) -> Result + where + R: SimpleRequest, + { + self.perform(request).await + } + } +} diff --git a/common/client-libs/validator-client/src/rpc/reqwest.rs b/common/client-libs/validator-client/src/rpc/reqwest.rs new file mode 100644 index 0000000000..9c8411d666 --- /dev/null +++ b/common/client-libs/validator-client/src/rpc/reqwest.rs @@ -0,0 +1,118 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::rpc::TendermintRpcClient; +use async_trait::async_trait; +use reqwest::header::HeaderMap; +use reqwest::{header, RequestBuilder}; +use tendermint_rpc::{Error, Response, SimpleRequest}; +use url::Url; + +pub struct ReqwestRpcClient { + inner: reqwest::Client, + url: Url, +} + +impl ReqwestRpcClient { + pub fn new(url: Url) -> Self { + ReqwestRpcClient { + inner: reqwest::Client::new(), + url, + } + } + + fn build_request(&self, request: R) -> RequestBuilder { + let mut headers = HeaderMap::new(); + headers.insert(header::CONTENT_TYPE, "application/json".parse().unwrap()); + headers.insert( + header::USER_AGENT, + format!("nym-reqwest-rpc-client/{}", env!("CARGO_PKG_VERSION")) + .parse() + .unwrap(), + ); + if let Some(auth) = extract_authorization(&self.url) { + headers.insert(header::AUTHORIZATION, auth.parse().unwrap()); + } + + self.inner + .post(self.url.clone()) + .body(request.into_json().into_bytes()) + .headers(headers) + } +} + +trait TendermintRpcErrorMap { + fn into_rpc_err(self) -> Error; +} + +impl TendermintRpcErrorMap for reqwest::Error { + fn into_rpc_err(self) -> Error { + todo!() + } +} + +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] +impl TendermintRpcClient for ReqwestRpcClient { + async fn perform(&self, request: R) -> Result + where + R: SimpleRequest, + { + let request = self.build_request(request); + // that's extremely unfortunate. the trait requires returning tendermint rpc error so we have to make best effort error mapping + let response = request + .send() + .await + .map_err(TendermintRpcErrorMap::into_rpc_err)?; + let bytes = response + .bytes() + .await + .map_err(TendermintRpcErrorMap::into_rpc_err)?; + R::Response::from_string(bytes).map(Into::into) + } +} + +// essentially https://github.com/informalsystems/tendermint-rs/blob/v0.32.0/rpc/src/client/transport/auth.rs#L31 +pub fn extract_authorization(url: &Url) -> Option { + if !url.has_authority() { + return None; + } + + let authority = url.authority(); + if let Some((userpass, _)) = authority.split_once('@') { + Some(base64::encode(userpass)) + } else { + None + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[cfg(test)] + mod extracting_url_authorization { + use super::*; + use std::str::FromStr; + + #[test] + fn extract_auth_absent() { + let uri = Url::from_str("http://example.com").unwrap(); + assert_eq!(extract_authorization(&uri), None); + } + + #[test] + fn extract_auth_username_only() { + let uri = Url::from_str("http://toto@example.com").unwrap(); + let base64 = "dG90bw==".to_string(); + assert_eq!(extract_authorization(&uri), Some(base64)); + } + + #[test] + fn extract_auth_username_password() { + let uri = Url::from_str("http://toto:tata@example.com").unwrap(); + let base64 = "dG90bzp0YXRh".to_string(); + assert_eq!(extract_authorization(&uri), Some(base64)); + } + } +} diff --git a/common/commands/Cargo.toml b/common/commands/Cargo.toml index dd6e8e3895..45c9139fe3 100644 --- a/common/commands/Cargo.toml +++ b/common/commands/Cargo.toml @@ -19,10 +19,10 @@ log = { workspace = true } rand = {version = "0.6", features = ["std"] } serde = { version = "1.0", features = ["derive"] } serde_json = { workspace = true } -thiserror = "1" +thiserror = { workspace = true } time = { version = "0.3.6", features = ["parsing", "formatting"] } toml = "0.5.6" -url = "2.2" +url = { workspace = true } tap = "1" cosmrs = { workspace = true } diff --git a/common/config/Cargo.toml b/common/config/Cargo.toml index ed894e808b..d7ca649e60 100644 --- a/common/config/Cargo.toml +++ b/common/config/Cargo.toml @@ -12,7 +12,7 @@ handlebars = "3.5.5" log = { workspace = true } serde = { workspace = true, features = ["derive"] } toml = "0.7.4" -url = "2.2" +url = { workspace = true } nym-network-defaults = { path = "../network-defaults" } diff --git a/common/mixnode-common/Cargo.toml b/common/mixnode-common/Cargo.toml index 62fec9422a..b2fcf6e2a3 100644 --- a/common/mixnode-common/Cargo.toml +++ b/common/mixnode-common/Cargo.toml @@ -8,7 +8,7 @@ edition = "2021" [dependencies] bytes = "1.0" -futures = "0.3" +futures = { workspace = true } humantime-serde = "1.0" log = { workspace = true } rand = "0.8" @@ -21,8 +21,8 @@ tokio = { version = "1.24.1", features = [ "io-util", ] } tokio-util = { version = "0.7.4", features = ["codec"] } -url = "2.2" -thiserror = "1.0.37" +url = { workspace = true } +thiserror = { workspace = true } ## tracing tracing = { version = "0.1.37", optional = true } diff --git a/common/network-defaults/Cargo.toml b/common/network-defaults/Cargo.toml index f2878ad16a..bc5bddb497 100644 --- a/common/network-defaults/Cargo.toml +++ b/common/network-defaults/Cargo.toml @@ -12,6 +12,7 @@ cfg-if = { workspace = true } dotenvy = { workspace = true } hex-literal = "0.3.3" once_cell = { workspace = true } +schemars = { version = "0.8", features = ["preserve_order"] } serde = { workspace = true, features = ["derive"]} thiserror = { workspace = true } url = { workspace = true } diff --git a/common/network-defaults/src/lib.rs b/common/network-defaults/src/lib.rs index 2be09b0e70..33373dcc52 100644 --- a/common/network-defaults/src/lib.rs +++ b/common/network-defaults/src/lib.rs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use crate::var_names::{DEPRECATED_API_VALIDATOR, DEPRECATED_NYMD_VALIDATOR, NYM_API, NYXD}; +use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use std::{ env::{var, VarError}, @@ -14,14 +15,14 @@ use url::Url; pub mod mainnet; pub mod var_names; -#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] +#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize, JsonSchema)] pub struct ChainDetails { pub bech32_account_prefix: String, pub mix_denom: DenomDetailsOwned, pub stake_denom: DenomDetailsOwned, } -#[derive(Clone, Debug, Default, Deserialize, Eq, Hash, PartialEq, Serialize)] +#[derive(Clone, Debug, Default, Deserialize, Eq, Hash, PartialEq, Serialize, JsonSchema)] pub struct NymContracts { pub mixnet_contract_address: Option, pub vesting_contract_address: Option, @@ -35,7 +36,7 @@ pub struct NymContracts { // I wanted to use the simpler `NetworkDetails` name, but there's a clash // with `NetworkDetails` defined in all.rs... -#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] +#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize, JsonSchema)] pub struct NymNetworkDetails { pub network_name: String, pub chain_details: ChainDetails, @@ -104,7 +105,7 @@ impl NymNetworkDetails { .parse() .expect("denomination exponent is not u32"), }) - .with_validator_endpoint(ValidatorDetails::new( + .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")), )) @@ -205,11 +206,17 @@ impl NymNetworkDetails { } #[must_use] - pub fn with_validator_endpoint(mut self, endpoint: ValidatorDetails) -> Self { + pub fn with_additional_validator_endpoint(mut self, endpoint: ValidatorDetails) -> Self { self.endpoints.push(endpoint); self } + #[must_use] + pub fn with_validator_endpoint(mut self, endpoint: ValidatorDetails) -> Self { + self.endpoints = vec![endpoint]; + self + } + #[must_use] pub fn with_mixnet_contract>(mut self, contract: Option) -> Self { self.contracts.mixnet_contract_address = contract.map(Into::into); @@ -280,7 +287,7 @@ impl DenomDetails { } } -#[derive(Debug, Serialize, Deserialize, Hash, Clone, PartialEq, Eq)] +#[derive(Debug, Serialize, Deserialize, Hash, Clone, PartialEq, Eq, JsonSchema)] pub struct DenomDetailsOwned { pub base: String, pub display: String, @@ -308,7 +315,7 @@ impl DenomDetailsOwned { } } -#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] +#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize, JsonSchema)] pub struct ValidatorDetails { // it is assumed those values are always valid since they're being provided in our defaults file pub nyxd_url: String, diff --git a/common/node-tester-utils/Cargo.toml b/common/node-tester-utils/Cargo.toml index 39a93d4a9f..32ec845723 100644 --- a/common/node-tester-utils/Cargo.toml +++ b/common/node-tester-utils/Cargo.toml @@ -6,7 +6,7 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -futures = "0.3.28" +futures = { workspace = true } rand = "0.7.3" serde = { workspace = true } diff --git a/common/socks5-client-core/Cargo.toml b/common/socks5-client-core/Cargo.toml index 4c7df38c8e..6a5221bba0 100644 --- a/common/socks5-client-core/Cargo.toml +++ b/common/socks5-client-core/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" [dependencies] dirs = "4.0" -futures = "0.3" +futures = { workspace = true } log = { workspace = true } pin-project = "1.0" rand = { version = "0.7.3", features = ["wasm-bindgen"] } @@ -17,7 +17,7 @@ serde = { workspace = true, features = ["derive"] } # for config serialization/d tap = "1.0.1" thiserror = "1.0.34" tokio = { version = "1.24.1", features = ["rt-multi-thread", "net", "signal"] } -url = "2.2" +url = { workspace = true } nym-bandwidth-controller = { path = "../../common/bandwidth-controller" } nym-client-core = { path = "../client-core", features = ["fs-surb-storage"] } diff --git a/common/socks5/proxy-helpers/Cargo.toml b/common/socks5/proxy-helpers/Cargo.toml index 88157a22c4..6ebaaa03c9 100644 --- a/common/socks5/proxy-helpers/Cargo.toml +++ b/common/socks5/proxy-helpers/Cargo.toml @@ -12,7 +12,7 @@ tokio = { version = "1.24.1", features = [ "net", "io-util", "sync", "macros", " tokio-util = { version = "0.7.4", features = [ "io" ] } # reason for getting this guy is to to able to port to tokio 1.X more quickly by being able to use # their `read_buf` [from the util crate] replacement rather than having to rethink/reimplement `AvailableReader` with the new AsyncRead trait definition. # In the long run, the dependency should probably get removed in favour of pure-tokio implementation, but for time being it's fine. -futures = "0.3" +futures = { workspace = true } log = { workspace = true } # internal diff --git a/common/task/Cargo.toml b/common/task/Cargo.toml index 7e94b5442b..500cdb2a53 100644 --- a/common/task/Cargo.toml +++ b/common/task/Cargo.toml @@ -8,10 +8,10 @@ license.workspace = true repository.workspace = true [dependencies] -futures = "0.3" +futures = { workspace = true } log = { workspace = true } -thiserror = "1.0.37" -tokio = { version = "1.24.1", features = ["macros", "sync"] } +thiserror = { workspace = true } +tokio = { workspace = true, features = ["macros", "sync"] } [target."cfg(not(target_arch = \"wasm32\"))".dependencies.tokio] version = "1.24.1" diff --git a/common/types/Cargo.toml b/common/types/Cargo.toml index 35c7cd228a..5515ba5248 100644 --- a/common/types/Cargo.toml +++ b/common/types/Cargo.toml @@ -15,8 +15,8 @@ schemars = "0.8" serde = { version = "1.0", features = ["derive"] } serde_json = { workspace = true } strum = { version = "0.23", features = ["derive"] } -thiserror = "1.0" -url = "2.2" +thiserror = { workspace = true } +url = { workspace = true } ts-rs = "6.1.2" cosmwasm-std = { workspace = true } diff --git a/common/types/src/error.rs b/common/types/src/error.rs index 15b938da9a..4546731ff4 100644 --- a/common/types/src/error.rs +++ b/common/types/src/error.rs @@ -1,3 +1,4 @@ +use nym_validator_client::error::TendermintRpcError; use nym_validator_client::nym_api::error::NymAPIError; use nym_validator_client::{nyxd::error::NyxdError, ValidatorClientError}; use serde::{Serialize, Serializer}; @@ -18,6 +19,11 @@ pub enum TypesError { source: cosmwasm_std::StdError, }, #[error("{source}")] + TendermintRpcError { + #[from] + source: TendermintRpcError, + }, + #[error("{source}")] ErrorReport { #[from] source: eyre::Report, @@ -92,6 +98,7 @@ impl From for TypesError { ValidatorClientError::MalformedUrlProvided(e) => e.into(), ValidatorClientError::NyxdError(e) => e.into(), ValidatorClientError::NoAPIUrlAvailable => TypesError::NoNymApiUrlConfigured, + ValidatorClientError::TendermintErrorRpc(err) => err.into(), } } } diff --git a/common/wasm-utils/Cargo.toml b/common/wasm-utils/Cargo.toml index 2964e32110..fb4b25c5d8 100644 --- a/common/wasm-utils/Cargo.toml +++ b/common/wasm-utils/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -futures = "0.3" +futures = { workspace = true } js-sys = "^0.3.51" wasm-bindgen = "=0.2.83" wasm-bindgen-futures = "0.4" diff --git a/explorer-api/src/tasks.rs b/explorer-api/src/tasks.rs index 7e4ea329fa..b0b9a9701b 100644 --- a/explorer-api/src/tasks.rs +++ b/explorer-api/src/tasks.rs @@ -1,14 +1,13 @@ // Copyright 2022 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use std::future::Future; - use nym_mixnet_contract_common::GatewayBond; use nym_task::TaskClient; use nym_validator_client::models::MixNodeBondAnnotated; use nym_validator_client::nyxd::error::NyxdError; -use nym_validator_client::nyxd::{Paging, TendermintClient, ValidatorResponse}; +use nym_validator_client::nyxd::{Paging, TendermintRpcClient, ValidatorResponse}; use nym_validator_client::{QueryHttpRpcValidatorClient, ValidatorClientError}; +use std::future::Future; use crate::mix_nodes::CACHE_REFRESH_RATE; use crate::state::ExplorerApiStateContext; diff --git a/gateway/Cargo.toml b/gateway/Cargo.toml index 589c65ec8f..25e2b62375 100644 --- a/gateway/Cargo.toml +++ b/gateway/Cargo.toml @@ -25,7 +25,7 @@ colored = "2.0" dashmap = "4.0" dirs = "4.0" dotenvy = { workspace = true } -futures = "0.3" +futures = { workspace = true } humantime-serde = "1.0.1" lazy_static = "1.4.0" log = { workspace = true } diff --git a/gateway/gateway-requests/Cargo.toml b/gateway/gateway-requests/Cargo.toml index 92b2a7c8e4..dcd8ad3743 100644 --- a/gateway/gateway-requests/Cargo.toml +++ b/gateway/gateway-requests/Cargo.toml @@ -11,7 +11,7 @@ edition = "2021" [dependencies] bs58 = "0.4.0" -futures = "0.3.15" +futures = { workspace = true } generic-array = { workspace = true, features = ["serde"] } log = { workspace = true } rand = { version = "0.7.3", features = ["wasm-bindgen"] } diff --git a/mixnode/Cargo.toml b/mixnode/Cargo.toml index a670dd4f81..101ac4d513 100644 --- a/mixnode/Cargo.toml +++ b/mixnode/Cargo.toml @@ -22,7 +22,7 @@ clap = { version = "4.0", features = ["cargo", "derive"] } colored = "2.0" cupid = "0.6.1" dirs = "4.0" -futures = "0.3.0" +futures = { workspace = true } humantime-serde = "1.0" lazy_static = "1.4.0" log = { workspace = true } diff --git a/nym-api/Cargo.toml b/nym-api/Cargo.toml index f91180fd37..5e7a9488d1 100644 --- a/nym-api/Cargo.toml +++ b/nym-api/Cargo.toml @@ -22,7 +22,7 @@ cfg-if = "1.0" clap = { version = "4.0", features = ["cargo", "derive"] } console-subscriber = { version = "0.1.1", optional = true } # validator-api needs to be built with RUSTFLAGS="--cfg tokio_unstable" dirs = "4.0" -futures = "0.3.24" +futures = { workspace = true } humantime-serde = "1.0" lazy_static = "1.4.0" log = { workspace = true } @@ -33,10 +33,10 @@ rand-07 = { package = "rand", version = "0.7.3" } # required for compatibility reqwest = { workspace = true, features = ["json"] } rocket = { version = "0.5.0-rc.2", features = ["json"] } rocket_cors = { git = "https://github.com/lawliet89/rocket_cors", rev = "dfd3662c49e2f6fc37df35091cb94d82f7fb5915" } -serde = "1.0" +serde = { workspace = true } serde_json = { workspace = true } tap = "1.0" -thiserror = "1.0" +thiserror = { workspace = true } time = { version = "0.3.14", features = ["serde-human-readable", "parsing"] } tokio = { version = "1.24.1", features = [ "rt-multi-thread", @@ -45,7 +45,7 @@ tokio = { version = "1.24.1", features = [ "time", ] } tokio-stream = "0.1.11" -url = "2.2" +url = { workspace = true } ts-rs = {version = "6.1", optional = true} @@ -74,6 +74,7 @@ cosmwasm-std = { workspace = true } nym-credential-storage = { path = "../common/credential-storage" } nym-credentials = { path = "../common/credentials" } nym-crypto = { path = "../common/crypto" } +cw2 = { workspace = true } cw3 = { workspace = true } cw4 = { workspace = true } nym-dkg = { path = "../common/dkg", features = ["cw-types"] } diff --git a/nym-api/src/main.rs b/nym-api/src/main.rs index 39719ba0fe..5784247e7f 100644 --- a/nym-api/src/main.rs +++ b/nym-api/src/main.rs @@ -5,6 +5,7 @@ extern crate rocket; use crate::epoch_operations::RewardedSetUpdater; +use crate::network::models::NetworkDetails; use crate::node_status_api::uptime_updater::HistoricalUptimeUpdater; use crate::support::cli; use crate::support::cli::CliArgs; @@ -29,6 +30,7 @@ use support::{http, nyxd}; mod circulating_supply_api; mod coconut; mod epoch_operations; +pub(crate) mod network; mod network_monitor; pub(crate) mod node_status_api; pub(crate) mod nym_contract_cache; @@ -58,14 +60,16 @@ async fn start_nym_api_tasks( config: Config, ) -> Result> { let nyxd_client = nyxd::Client::new(&config); - let mix_denom = nyxd_client.chain_details().await.mix_denom.base; + let connected_nyxd = config.get_nyxd_url(); + let nym_network_details = config.get_network_details(); + let network_details = NetworkDetails::new(connected_nyxd.to_string(), nym_network_details); let coconut_keypair = coconut::keypair::KeyPair::new(); // let's build our rocket! let rocket = http::setup_rocket( &config, - mix_denom, + network_details, nyxd_client.clone(), coconut_keypair.clone(), ) diff --git a/nym-api/src/network/mod.rs b/nym-api/src/network/mod.rs new file mode 100644 index 0000000000..f06bc5bf16 --- /dev/null +++ b/nym-api/src/network/mod.rs @@ -0,0 +1,16 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use okapi::openapi3::OpenApi; +use rocket::Route; +use rocket_okapi::openapi_get_routes_spec; +use rocket_okapi::settings::OpenApiSettings; + +pub(crate) mod models; +mod routes; + +pub(crate) fn network_routes(settings: &OpenApiSettings) -> (Vec, OpenApi) { + openapi_get_routes_spec![ + settings: routes::network_details, routes::nym_contracts, routes::nym_contracts_detailed + ] +} diff --git a/nym-api/src/network/models.rs b/nym-api/src/network/models.rs new file mode 100644 index 0000000000..518b4352f1 --- /dev/null +++ b/nym-api/src/network/models.rs @@ -0,0 +1,28 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use nym_config::defaults::NymNetworkDetails; +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Serialize, Deserialize, JsonSchema)] +pub struct NetworkDetails { + pub(crate) connected_nyxd: String, + pub(crate) network: NymNetworkDetails, +} + +impl NetworkDetails { + pub fn new(connected_nyxd: String, network: NymNetworkDetails) -> Self { + Self { + connected_nyxd, + network, + } + } +} + +#[derive(Serialize, Deserialize, Clone, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub struct ContractInformation { + pub(crate) address: Option, + pub(crate) details: Option, +} diff --git a/nym-api/src/network/routes.rs b/nym-api/src/network/routes.rs new file mode 100644 index 0000000000..77f60f0fa9 --- /dev/null +++ b/nym-api/src/network/routes.rs @@ -0,0 +1,63 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::network::models::{ContractInformation, NetworkDetails}; +use crate::nym_contract_cache::cache::NymContractCache; +use nym_contracts_common::ContractBuildInformation; +use rocket::serde::json::Json; +use rocket::State; +use rocket_okapi::openapi; +use std::collections::HashMap; +use std::ops::Deref; + +#[openapi(tag = "network")] +#[get("/details")] +pub(crate) fn network_details(details: &State) -> Json { + Json(details.deref().clone()) +} + +// I agree, it feels weird to be pulling contract cache here, but I feel like it makes +// more sense to return this information here rather than in the generic cache route +#[openapi(tag = "network")] +#[get("/nym-contracts")] +pub(crate) async fn nym_contracts( + cache: &State, +) -> Json>> { + let info = cache.contract_details().await; + Json( + info.value + .into_iter() + .map(|(contract, info)| { + ( + contract, + ContractInformation { + address: info.address.map(|a| a.to_string()), + details: info.base, + }, + ) + }) + .collect(), + ) +} + +#[openapi(tag = "network")] +#[get("/nym-contracts-detailed")] +pub(crate) async fn nym_contracts_detailed( + cache: &State, +) -> Json>> { + let info = cache.contract_details().await; + Json( + info.value + .into_iter() + .map(|(contract, info)| { + ( + contract, + ContractInformation { + address: info.address.map(|a| a.to_string()), + details: info.detailed, + }, + ) + }) + .collect(), + ) +} diff --git a/nym-api/src/nym_contract_cache/cache/data.rs b/nym-api/src/nym_contract_cache/cache/data.rs index 27285db41a..ede4bc6838 100644 --- a/nym-api/src/nym_contract_cache/cache/data.rs +++ b/nym-api/src/nym_contract_cache/cache/data.rs @@ -2,13 +2,15 @@ // SPDX-License-Identifier: Apache-2.0 use crate::support::caching::Cache; +use nym_contracts_common::ContractBuildInformation; use nym_mixnet_contract_common::{ families::FamilyHead, GatewayBond, IdentityKey, Interval, MixId, MixNodeDetails, RewardingParams, }; use nym_name_service_common::RegisteredName; use nym_service_provider_directory_common::Service; -use std::collections::HashSet; +use nym_validator_client::nyxd::AccountId; +use std::collections::{HashMap, HashSet}; pub(crate) struct ValidatorCacheData { pub(crate) mixnodes: Cache>, @@ -27,6 +29,8 @@ pub(crate) struct ValidatorCacheData { pub(crate) service_providers: Cache>, pub(crate) registered_names: Cache>, + + pub(crate) contracts_info: Cache, } impl ValidatorCacheData { @@ -43,6 +47,31 @@ impl ValidatorCacheData { mix_to_family: Cache::default(), service_providers: Cache::default(), registered_names: Cache::default(), + contracts_info: Cache::default(), + } + } +} + +type ContractAddress = String; +pub type CachedContractsInfo = HashMap; + +#[derive(Clone)] +pub struct CachedContractInfo { + pub(crate) address: Option, + pub(crate) base: Option, + pub(crate) detailed: Option, +} + +impl CachedContractInfo { + pub fn new( + address: Option<&AccountId>, + base: Option, + detailed: Option, + ) -> Self { + Self { + address: address.cloned(), + base, + detailed, } } } diff --git a/nym-api/src/nym_contract_cache/cache/mod.rs b/nym-api/src/nym_contract_cache/cache/mod.rs index 2eac4f0c61..ec0ce7f8e5 100644 --- a/nym-api/src/nym_contract_cache/cache/mod.rs +++ b/nym-api/src/nym_contract_cache/cache/mod.rs @@ -1,3 +1,4 @@ +use crate::nym_contract_cache::cache::data::CachedContractsInfo; use crate::support::caching::Cache; use data::ValidatorCacheData; use nym_api_requests::models::MixnodeStatus; @@ -54,6 +55,7 @@ impl NymContractCache { mix_to_family: Vec<(IdentityKey, FamilyHead)>, services: Option>, names: Option>, + nym_contracts_info: CachedContractsInfo, ) { match time::timeout(Duration::from_millis(100), self.inner.write()).await { Ok(mut cache) => { @@ -67,6 +69,7 @@ impl NymContractCache { // Just return empty lists when these are not available cache.service_providers.update(services.unwrap_or_default()); cache.registered_names.update(names.unwrap_or_default()); + cache.contracts_info.update(nym_contracts_info) } Err(err) => { error!("{err}"); @@ -267,6 +270,16 @@ impl NymContractCache { } } + pub(crate) async fn contract_details(&self) -> Cache { + match time::timeout(Duration::from_millis(100), self.inner.read()).await { + Ok(cache) => cache.contracts_info.clone(), + Err(err) => { + error!("{err}"); + Cache::default() + } + } + } + pub async fn mixnode_details(&self, mix_id: MixId) -> (Option, MixnodeStatus) { // it might not be the most optimal to possibly iterate the entire vector to find (or not) // the relevant value. However, the vectors are relatively small (< 10_000 elements, < 1000 for active set) diff --git a/nym-api/src/nym_contract_cache/cache/refresher.rs b/nym-api/src/nym_contract_cache/cache/refresher.rs index c6bbe1f81a..e1fa5cf18f 100644 --- a/nym-api/src/nym_contract_cache/cache/refresher.rs +++ b/nym-api/src/nym_contract_cache/cache/refresher.rs @@ -1,12 +1,16 @@ use super::NymContractCache; +use crate::nym_contract_cache::cache::data::{CachedContractInfo, CachedContractsInfo}; use crate::nyxd::Client; use crate::support::caching::CacheNotification; use anyhow::Result; +use futures::future::join_all; use nym_mixnet_contract_common::{MixId, MixNodeDetails, RewardedSetNodeStatus}; use nym_task::TaskClient; use nym_validator_client::nyxd::contract_traits::{ - PagedNameServiceQueryClient, PagedSpDirectoryQueryClient, + MixnetQueryClient, NameServiceQueryClient, NymContractsProvider, PagedNameServiceQueryClient, + PagedSpDirectoryQueryClient, SpDirectoryQueryClient, VestingQueryClient, }; +use nym_validator_client::nyxd::CosmWasmClient; use std::{collections::HashMap, sync::atomic::Ordering, time::Duration}; use tokio::sync::watch; use tokio::time; @@ -39,6 +43,129 @@ impl NymContractCacheRefresher { self.update_notifier.subscribe() } + async fn get_nym_contracts_info(&self) -> Result { + let mut updated = HashMap::new(); + + let client_guard = self.nyxd_client.read().await; + + let mixnet = client_guard.mixnet_contract_address(); + let vesting = client_guard.vesting_contract_address(); + let name_service = client_guard.name_service_contract_address(); + let service_provider = client_guard.service_provider_contract_address(); + let coconut_bandwidth = client_guard.coconut_bandwidth_contract_address(); + let coconut_dkg = client_guard.dkg_contract_address(); + let group = client_guard.group_contract_address(); + let multisig = client_guard.multisig_contract_address(); + + // get cw2 versions + let mixnet_cw2_future = client_guard.get_mixnet_contract_cw2_version(); + let vesting_cw2_future = client_guard.get_vesting_contract_cw2_version(); + let service_provider_cw2_future = client_guard.get_name_service_contract_cw2_version(); + let name_service_cw2_future = client_guard.get_name_service_contract_cw2_version(); + + // group and multisig contract save that information in their storage but don't expose it via queries + // so a temporary workaround... + let multisig_cw2 = if let Some(multisig_contract) = multisig { + client_guard + .query_contract_raw(multisig_contract, b"contract_info".to_vec()) + .await + .map(|r| serde_json::from_slice(&r).ok()) + .ok() + .flatten() + } else { + None + }; + let group_cw2 = if let Some(group_contract) = group { + client_guard + .query_contract_raw(group_contract, b"contract_info".to_vec()) + .await + .map(|r| serde_json::from_slice(&r).ok()) + .ok() + .flatten() + } else { + None + }; + + let mut cw2_info = join_all(vec![ + mixnet_cw2_future, + vesting_cw2_future, + service_provider_cw2_future, + name_service_cw2_future, + ]) + .await; + + // get detailed build info + let mixnet_detailed_future = client_guard.get_mixnet_contract_version(); + let vesting_detailed_future = client_guard.get_vesting_contract_version(); + let service_provider_detailed_future = client_guard.get_sp_contract_version(); + let name_service_detailed_future = client_guard.get_name_service_contract_version(); + + let mut build_info = join_all(vec![ + mixnet_detailed_future, + vesting_detailed_future, + service_provider_detailed_future, + name_service_detailed_future, + ]) + .await; + + // the below unwraps are fine as we definitely have the specified number of entries + // Note to whoever updates this code in the future: `pop` removes **LAST** element, + // so make sure you call them in correct order, depending on what's specified in the `join_all` + updated.insert( + "nym-name-service-contract".to_string(), + CachedContractInfo::new( + name_service, + cw2_info.pop().unwrap().ok(), + build_info.pop().unwrap().ok(), + ), + ); + + updated.insert( + "nym-service-provider-directory-contract".to_string(), + CachedContractInfo::new( + service_provider, + cw2_info.pop().unwrap().ok(), + build_info.pop().unwrap().ok(), + ), + ); + + updated.insert( + "nym-vesting-contract".to_string(), + CachedContractInfo::new( + vesting, + cw2_info.pop().unwrap().ok(), + build_info.pop().unwrap().ok(), + ), + ); + updated.insert( + "nym-mixnet-contract".to_string(), + CachedContractInfo::new( + mixnet, + cw2_info.pop().unwrap().ok(), + build_info.pop().unwrap().ok(), + ), + ); + + updated.insert( + "nym-coconut-bandwidth-contract".to_string(), + CachedContractInfo::new(coconut_bandwidth, None, None), + ); + updated.insert( + "nym-coconut-dkg-contract".to_string(), + CachedContractInfo::new(coconut_dkg, None, None), + ); + updated.insert( + "nym-cw3-multisig-contract".to_string(), + CachedContractInfo::new(multisig, multisig_cw2, None), + ); + updated.insert( + "nym-cw4-group-contract".to_string(), + CachedContractInfo::new(group, group_cw2, None), + ); + + Ok(updated) + } + async fn refresh(&self) -> Result<()> { let rewarding_params = self.nyxd_client.get_current_rewarding_parameters().await?; let current_interval = self.nyxd_client.get_current_interval().await?.interval; @@ -56,6 +183,7 @@ impl NymContractCacheRefresher { // The service providers and names are optional let services = self.nyxd_client.get_all_services().await.ok(); let names = self.nyxd_client.get_all_names().await.ok(); + let contract_info = self.get_nym_contracts_info().await?; info!( "Updating validator cache. There are {} mixnodes and {} gateways", @@ -74,6 +202,7 @@ impl NymContractCacheRefresher { mix_to_family, services, names, + contract_info, ) .await; diff --git a/nym-api/src/support/caching/mod.rs b/nym-api/src/support/caching/mod.rs index ad2e40e80d..0d2615d327 100644 --- a/nym-api/src/support/caching/mod.rs +++ b/nym-api/src/support/caching/mod.rs @@ -2,13 +2,13 @@ use serde::Serialize; use std::ops::Deref; use time::OffsetDateTime; -#[derive(Default, Serialize, Clone)] +#[derive(Serialize, Clone)] pub struct Cache { pub value: T, as_at: i64, } -impl Cache { +impl Cache { pub fn new(value: T) -> Self { Cache { value, @@ -38,6 +38,18 @@ impl Deref for Cache { } } +impl Default for Cache +where + T: Default, +{ + fn default() -> Self { + Cache { + value: T::default(), + as_at: 0, + } + } +} + fn current_unix_timestamp() -> i64 { let now = OffsetDateTime::now_utc(); now.unix_timestamp() diff --git a/nym-api/src/support/config/mod.rs b/nym-api/src/support/config/mod.rs index 51f2c6726c..163eaa44db 100644 --- a/nym-api/src/support/config/mod.rs +++ b/nym-api/src/support/config/mod.rs @@ -5,7 +5,7 @@ use crate::support::config::persistence::{ CoconutSignerPaths, NetworkMonitorPaths, NodeStatusAPIPaths, }; use crate::support::config::template::CONFIG_TEMPLATE; -use nym_config::defaults::mainnet; +use nym_config::defaults::{mainnet, NymNetworkDetails}; 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, @@ -98,6 +98,16 @@ pub struct Config { pub coconut_signer: CoconutSigner, } +impl<'a> From<&'a Config> for NymNetworkDetails { + fn from(value: &'a Config) -> Self { + // we get the current environmental details and then overwrite whatever is appropriate with + // the values from the config + NymNetworkDetails::new_from_env() + .with_mixnet_contract(Some(value.get_mixnet_contract_address().as_ref())) + .with_vesting_contract(Some(value.get_vesting_contract_address().as_ref())) + } +} + impl NymConfigTemplate for Config { fn template() -> &'static str { CONFIG_TEMPLATE @@ -134,6 +144,10 @@ impl Config { save_formatted_config_to_file(self, config_save_location) } + pub fn get_network_details(&self) -> NymNetworkDetails { + self.into() + } + pub fn with_network_monitor_enabled(mut self, enabled: bool) -> Self { self.network_monitor.enabled = enabled; self diff --git a/nym-api/src/support/http/mod.rs b/nym-api/src/support/http/mod.rs index 572d1c281b..b21ccdb381 100644 --- a/nym-api/src/support/http/mod.rs +++ b/nym-api/src/support/http/mod.rs @@ -3,6 +3,8 @@ use crate::circulating_supply_api::cache::CirculatingSupplyCache; use crate::coconut::{self, comm::QueryCommunicationChannel, InternalSignRequest}; +use crate::network::models::NetworkDetails; +use crate::network::network_routes; use crate::node_status_api::{self, NodeStatusCache}; use crate::nym_contract_cache::cache::NymContractCache; use crate::support::config::Config; @@ -19,13 +21,15 @@ pub(crate) mod openapi; pub(crate) async fn setup_rocket( config: &Config, - mix_denom: String, + network_details: NetworkDetails, _nyxd_client: nyxd::Client, coconut_keypair: coconut::keypair::KeyPair, ) -> anyhow::Result> { let openapi_settings = rocket_okapi::settings::OpenApiSettings::default(); let mut rocket = rocket::build(); + let mix_denom = network_details.network.chain_details.mix_denom.base.clone(); + mount_endpoints_and_merged_docs! { rocket, "/v1".to_owned(), @@ -34,9 +38,11 @@ pub(crate) async fn setup_rocket( "" => circulating_supply_api::circulating_supply_routes(&openapi_settings), "" => nym_contract_cache::nym_contract_cache_routes(&openapi_settings), "/status" => node_status_api::node_status_routes(&openapi_settings, config.network_monitor.enabled), + "/network" => network_routes(&openapi_settings), } let rocket = rocket + .manage(network_details) .mount("/swagger", make_swagger_ui(&openapi::get_docs())) .attach(setup_cors()?) .attach(NymContractCache::stage()) diff --git a/nym-api/src/support/nyxd/mod.rs b/nym-api/src/support/nyxd/mod.rs index 861b485307..501be9e581 100644 --- a/nym-api/src/support/nyxd/mod.rs +++ b/nym-api/src/support/nyxd/mod.rs @@ -16,7 +16,7 @@ use nym_coconut_dkg_common::{ types::{EncodedBTEPublicKeyWithProof, Epoch, EpochId}, verification_key::{ContractVKShare, VerificationKeyShare}, }; -use nym_config::defaults::{ChainDetails, NymNetworkDetails}; +use nym_config::defaults::ChainDetails; use nym_contracts_common::dealings::ContractSafeBytes; use nym_mixnet_contract_common::families::FamilyHead; use nym_mixnet_contract_common::mixnode::MixNodeDetails; @@ -47,7 +47,7 @@ use nym_validator_client::{nyxd, DirectSigningHttpRpcNyxdClient}; use nym_vesting_contract_common::AccountVestingCoins; use serde::Deserialize; use std::sync::Arc; -use tokio::sync::RwLock; +use tokio::sync::{RwLock, RwLockReadGuard}; pub(crate) struct Client(pub(crate) Arc>); @@ -59,12 +59,9 @@ impl Clone for Client { impl Client { pub(crate) fn new(config: &Config) -> Self { + let details = config.get_network_details(); let nyxd_url = config.get_nyxd_url(); - let details = NymNetworkDetails::new_from_env() - .with_mixnet_contract(Some(config.get_mixnet_contract_address().as_ref())) - .with_vesting_contract(Some(config.get_vesting_contract_address().as_ref())); - let client_config = nyxd::Config::try_from_nym_network_details(&details) .expect("failed to construct valid validator client config with the provided network"); @@ -80,6 +77,10 @@ impl Client { Client(Arc::new(RwLock::new(inner))) } + pub(crate) async fn read(&self) -> RwLockReadGuard<'_, DirectSigningHttpRpcNyxdClient> { + self.0.read().await + } + pub(crate) async fn client_address(&self) -> AccountId { self.0.read().await.address() } diff --git a/nym-connect/desktop/Cargo.lock b/nym-connect/desktop/Cargo.lock index b1aa136deb..51641a7a86 100644 --- a/nym-connect/desktop/Cargo.lock +++ b/nym-connect/desktop/Cargo.lock @@ -4122,6 +4122,7 @@ dependencies = [ name = "nym-explorer-api-requests" version = "0.1.0" dependencies = [ + "nym-api-requests", "nym-contracts-common", "nym-mixnet-contract-common", "schemars", @@ -4245,6 +4246,7 @@ dependencies = [ "dotenvy", "hex-literal", "once_cell", + "schemars", "serde", "thiserror", "url", @@ -4593,6 +4595,7 @@ dependencies = [ "thiserror", "tokio", "url", + "wasmtimer", "zeroize", ] diff --git a/nym-connect/desktop/src-tauri/Cargo.toml b/nym-connect/desktop/src-tauri/Cargo.toml index f1176cdc7c..192b1bb391 100644 --- a/nym-connect/desktop/src-tauri/Cargo.toml +++ b/nym-connect/desktop/src-tauri/Cargo.toml @@ -41,7 +41,7 @@ tauri = { version = "^1.2.2", features = ["clipboard-write-text", "macos-private thiserror = "1.0" time = { version = "0.3.17", features = ["local-offset"] } tokio = { version = "1.24.1", features = ["sync", "time"] } -url = "2.2" +url = "2.4" yaml-rust = "0.4" toml = "0.7" sentry = { version = "0.31.5", features = [ "anyhow" ] } diff --git a/nym-wallet/Cargo.lock b/nym-wallet/Cargo.lock index ba0ebb18e0..fbd4a02504 100644 --- a/nym-wallet/Cargo.lock +++ b/nym-wallet/Cargo.lock @@ -3334,6 +3334,7 @@ dependencies = [ "dotenvy", "hex-literal", "once_cell", + "schemars", "serde", "thiserror", "url", @@ -3448,6 +3449,7 @@ dependencies = [ "thiserror", "tokio", "url", + "wasmtimer", "zeroize", ] @@ -6110,6 +6112,20 @@ version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" +[[package]] +name = "wasmtimer" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f656cd8858a5164932d8a90f936700860976ec21eb00e0fe2aa8cab13f6b4cf" +dependencies = [ + "futures", + "js-sys", + "parking_lot", + "pin-utils", + "slab", + "wasm-bindgen", +] + [[package]] name = "web-sys" version = "0.3.64" diff --git a/nym-wallet/src-tauri/src/error.rs b/nym-wallet/src-tauri/src/error.rs index 3d9374c22a..7f542d257c 100644 --- a/nym-wallet/src-tauri/src/error.rs +++ b/nym-wallet/src-tauri/src/error.rs @@ -196,11 +196,6 @@ impl From for BackendError { impl From for BackendError { fn from(e: ValidatorClientError) -> Self { - match e { - ValidatorClientError::NymAPIError { source } => source.into(), - ValidatorClientError::MalformedUrlProvided(e) => e.into(), - ValidatorClientError::NyxdError(e) => e.into(), - ValidatorClientError::NoAPIUrlAvailable => TypesError::NoNymApiUrlConfigured.into(), - } + TypesError::from(e).into() } } diff --git a/sdk/lib/socks5-listener/Cargo.toml b/sdk/lib/socks5-listener/Cargo.toml index 6960745920..fe2ff08134 100644 --- a/sdk/lib/socks5-listener/Cargo.toml +++ b/sdk/lib/socks5-listener/Cargo.toml @@ -18,7 +18,7 @@ codegen-units = 1 [dependencies] anyhow = { workspace = true } -futures = "0.3" +futures = { workspace = true } lazy_static = "1.4.0" nym-bin-common = { path = "../../../common/bin-common"} nym-client-core = { path = "../../../common/client-core", default-features = false } diff --git a/sdk/rust/nym-sdk/Cargo.toml b/sdk/rust/nym-sdk/Cargo.toml index 97751d4e72..c034e733a1 100644 --- a/sdk/rust/nym-sdk/Cargo.toml +++ b/sdk/rust/nym-sdk/Cargo.toml @@ -20,12 +20,12 @@ nym-topology = { path = "../../../common/topology" } nym-socks5-client-core = { path = "../../../common/socks5-client-core" } nym-validator-client = { path = "../../../common/client-libs/validator-client", features = ["http-client"] } -futures = "0.3" +futures = { workspace = true } log = { workspace = true } rand = { version = "0.7.3" } tap = "1.0.1" -thiserror = "1.0.38" -url = "2.2" +thiserror = { workspace = true } +url = { workspace = true } toml = "0.5.10" [dev-dependencies] diff --git a/service-providers/network-requester/Cargo.toml b/service-providers/network-requester/Cargo.toml index c76662dfde..713552f812 100644 --- a/service-providers/network-requester/Cargo.toml +++ b/service-providers/network-requester/Cargo.toml @@ -15,7 +15,7 @@ async-trait = { workspace = true } bs58 = "0.4.0" clap = {version = "4.0", features = ["cargo", "derive"]} dirs = "4.0" -futures = "0.3.24" +futures = { workspace = true } humantime-serde = "1.1.1" ipnetwork = "0.20.0" lazy_static = { workspace = true } From e849dc13fd0da8ed6e37b568fd08907f29b58a2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Thu, 17 Aug 2023 10:59:09 +0100 Subject: [PATCH 24/24] post-rebase fixes --- .../mixnet/operators/name/register_sign_payload.rs | 6 +++--- nym-wallet/Cargo.lock | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/common/commands/src/validator/mixnet/operators/name/register_sign_payload.rs b/common/commands/src/validator/mixnet/operators/name/register_sign_payload.rs index 05774ac30b..e293f23c2e 100644 --- a/common/commands/src/validator/mixnet/operators/name/register_sign_payload.rs +++ b/common/commands/src/validator/mixnet/operators/name/register_sign_payload.rs @@ -14,7 +14,7 @@ use nym_name_service_common::{ signing_types::construct_name_register_sign_payload, Address, NymName, }; use nym_sphinx::addressing::clients::Recipient; -use nym_validator_client::nyxd::{error::NyxdError, traits::NameServiceQueryClient}; +use nym_validator_client::nyxd::{contract_traits::NameServiceQueryClient, error::NyxdError}; #[derive(Debug, Parser)] pub struct Args { @@ -45,7 +45,7 @@ pub async fn create_payload(args: Args, client: SigningClient) -> Result<(), Nyx let denom = client.current_chain_details().mix_denom.base.as_str(); let deposit = Coin::new(args.amount, denom); - let nonce = match client.get_name_signing_nonce(client.address()).await { + let nonce = match client.get_name_signing_nonce(&client.address()).await { Ok(nonce) => nonce, Err(err) => { eprint!( @@ -56,7 +56,7 @@ pub async fn create_payload(args: Args, client: SigningClient) -> Result<(), Nyx } }; - let address = account_id_to_cw_addr(client.address()); + let address = account_id_to_cw_addr(&client.address()); let payload = construct_name_register_sign_payload(nonce, address, deposit, name); let wrapper = DataWrapper::new(payload.to_base58_string().unwrap()); println!("{}", args.output.format(&wrapper)); diff --git a/nym-wallet/Cargo.lock b/nym-wallet/Cargo.lock index fbd4a02504..72ea6b5683 100644 --- a/nym-wallet/Cargo.lock +++ b/nym-wallet/Cargo.lock @@ -3501,7 +3501,7 @@ dependencies = [ [[package]] name = "nym_wallet" -version = "1.2.6" +version = "1.2.7" dependencies = [ "async-trait", "base64 0.13.1",