Chore/network config (#1335)

* Definition of NymNetworkDetails

* Initial attempt at changing network usage for nymd client

* Removed deprecated denom call and added constructor for custom network

* Cargo fmt
This commit is contained in:
Jędrzej Stuczyński
2022-06-28 15:10:20 +01:00
committed by GitHub
parent a646f84221
commit a2409c0a84
22 changed files with 569 additions and 264 deletions
+7 -7
View File
@@ -1,14 +1,13 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use bip39::Mnemonic;
use std::str::FromStr;
use url::Url;
use crate::error::Result;
use crate::{MNEMONIC, NYMD_URL};
use bip39::Mnemonic;
use network_defaults::{DEFAULT_NETWORK, MIX_DENOM, VOUCHER_INFO};
use std::str::FromStr;
use url::Url;
use validator_client::nymd;
use validator_client::nymd::traits::CoconutBandwidthSigningClient;
use validator_client::nymd::{Coin, Fee, NymdClient, SigningNymdClient};
@@ -20,9 +19,10 @@ impl Client {
pub fn new() -> Self {
let nymd_url = Url::from_str(NYMD_URL).unwrap();
let mnemonic = Mnemonic::from_str(MNEMONIC).unwrap();
let config = nymd::Config::try_from_nym_network_details(&DEFAULT_NETWORK.details())
.expect("failed to construct valid validator client config with the provided network");
let nymd_client =
NymdClient::connect_with_mnemonic(DEFAULT_NETWORK, nymd_url.as_ref(), mnemonic, None)
.unwrap();
NymdClient::connect_with_mnemonic(config, nymd_url.as_ref(), mnemonic, None).unwrap();
Client { nymd_client }
}
+2 -1
View File
@@ -24,7 +24,8 @@
},
"../pkg": {
"name": "@nymproject/nym-client-wasm",
"version": "0.0.1"
"version": "1.0.1",
"license": "Apache-2.0"
},
"node_modules/@discoveryjs/json-ext": {
"version": "0.5.7",
@@ -9,20 +9,17 @@ use validator_api_requests::coconut::{
ProposeReleaseFundsRequestBody, ProposeReleaseFundsResponse, VerificationKeyResponse,
VerifyCredentialBody, VerifyCredentialResponse,
};
use validator_api_requests::models::{
CoreNodeStatusResponse, MixnodeStatusResponse, RewardEstimationResponse,
StakeSaturationResponse,
};
#[cfg(feature = "nymd-client")]
use validator_api_requests::models::{MixNodeBondAnnotated, UptimeResponse};
#[cfg(feature = "nymd-client")]
use network_defaults::DEFAULT_NETWORK;
#[cfg(feature = "nymd-client")]
use crate::nymd::{
error::NymdError, CosmWasmClient, NymdClient, QueryNymdClient, SigningNymdClient,
self, error::NymdError, CosmWasmClient, NymdClient, QueryNymdClient, SigningNymdClient,
};
#[cfg(feature = "nymd-client")]
@@ -31,19 +28,20 @@ use mixnet_contract_common::{
MixnetContractVersion, MixnodeRewardingStatusResponse, RewardedSetNodeStatus,
RewardedSetUpdateDetails,
};
use network_defaults::all::Network;
#[cfg(feature = "nymd-client")]
use network_defaults::NymNetworkDetails;
#[cfg(feature = "nymd-client")]
use std::collections::{HashMap, HashSet};
#[cfg(feature = "nymd-client")]
#[must_use]
#[derive(Debug)]
#[derive(Debug, Clone)]
pub struct Config {
network: network_defaults::all::Network,
api_url: Url,
nymd_url: Url,
mixnet_contract_address: cosmrs::AccountId,
vesting_contract_address: cosmrs::AccountId,
bandwidth_claim_contract_address: cosmrs::AccountId,
nymd_config: nymd::Config,
mixnode_page_limit: Option<u32>,
gateway_page_limit: Option<u32>,
@@ -53,42 +51,44 @@ pub struct Config {
#[cfg(feature = "nymd-client")]
impl Config {
pub fn new(network: network_defaults::all::Network, nymd_url: Url, api_url: Url) -> Self {
Config {
network,
nymd_url,
mixnet_contract_address: DEFAULT_NETWORK
.mixnet_contract_address()
pub fn try_from_nym_network_details(
details: &NymNetworkDetails,
) -> Result<Self, ValidatorClientError> {
let mut api_url = details
.endpoints
.iter()
.filter_map(|d| d.api_url.as_ref())
.map(|url| Url::parse(url))
.collect::<Result<Vec<_>, _>>()?;
if api_url.is_empty() {
return Err(ValidatorClientError::NoAPIUrlAvailable);
}
Ok(Config {
api_url: api_url.pop().unwrap(),
nymd_url: details.endpoints[0]
.nymd_url
.parse()
.expect("Error parsing mixnet contract address"),
vesting_contract_address: DEFAULT_NETWORK
.vesting_contract_address()
.parse()
.expect("Error parsing vesting contract address"),
bandwidth_claim_contract_address: DEFAULT_NETWORK
.bandwidth_claim_contract_address()
.parse()
.expect("Error parsing bandwidth claim contract address"),
api_url,
.map_err(ValidatorClientError::MalformedUrlProvided)?,
nymd_config: nymd::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,
}
})
}
pub fn with_mixnode_contract_address(mut self, address: cosmrs::AccountId) -> Self {
self.mixnet_contract_address = address;
// TODO: this method shouldn't really exist as all information should be included immediately
// via `from_nym_network_details`, but it's here for, you guessed it, legacy compatibility
pub fn with_urls(mut self, nymd_url: Url, api_url: Url) -> Self {
self.nymd_url = nymd_url;
self.api_url = api_url;
self
}
pub fn with_vesting_contract_address(mut self, address: cosmrs::AccountId) -> Self {
self.vesting_contract_address = address;
self
}
pub fn with_bandwidth_claim_contract_address(mut self, address: cosmrs::AccountId) -> Self {
self.bandwidth_claim_contract_address = address;
pub fn with_nymd_url(mut self, nymd_url: Url) -> Self {
self.nymd_url = nymd_url;
self
}
@@ -115,10 +115,11 @@ impl Config {
#[cfg(feature = "nymd-client")]
pub struct Client<C> {
pub network: network_defaults::all::Network,
mixnet_contract_address: cosmrs::AccountId,
vesting_contract_address: cosmrs::AccountId,
bandwidth_claim_contract_address: cosmrs::AccountId,
// compatibility : (
pub network: Network,
// TODO: we really shouldn't be storing a mnemonic here, but removing it would be
// non-trivial amount of work and it's out of scope of the current branch
mnemonic: Option<bip39::Mnemonic>,
mixnode_page_limit: Option<u32>,
@@ -135,29 +136,26 @@ pub struct Client<C> {
impl Client<SigningNymdClient> {
pub fn new_signing(
config: Config,
// we need to provide network argument due to compatibility with other components (wallet...)
// that rely on its existence...
network: Network,
mnemonic: bip39::Mnemonic,
) -> Result<Client<SigningNymdClient>, ValidatorClientError> {
let validator_api_client = validator_api::Client::new(config.api_url.clone());
let nymd_client = NymdClient::connect_with_mnemonic(
config.network,
config.nymd_config.clone(),
config.nymd_url.as_str(),
mnemonic.clone(),
None,
)?
.with_mixnet_contract_address(config.mixnet_contract_address.clone())
.with_vesting_contract_address(config.vesting_contract_address.clone())
.with_bandwidth_claim_contract_address(config.bandwidth_claim_contract_address.clone());
)?;
Ok(Client {
network: config.network,
mixnet_contract_address: config.mixnet_contract_address,
vesting_contract_address: config.vesting_contract_address,
bandwidth_claim_contract_address: config.bandwidth_claim_contract_address,
network,
mnemonic: Some(mnemonic),
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: None,
rewarded_set_page_limit: config.rewarded_set_page_limit,
validator_api: validator_api_client,
nymd: nymd_client,
})
@@ -165,14 +163,11 @@ impl Client<SigningNymdClient> {
pub fn change_nymd(&mut self, new_endpoint: Url) -> Result<(), ValidatorClientError> {
self.nymd = NymdClient::connect_with_mnemonic(
self.network,
self.nymd.current_config().clone(),
new_endpoint.as_ref(),
self.mnemonic.clone().unwrap(),
None,
)?
.with_mixnet_contract_address(self.mixnet_contract_address.clone())
.with_vesting_contract_address(self.vesting_contract_address.clone())
.with_bandwidth_claim_contract_address(self.bandwidth_claim_contract_address.clone());
)?;
Ok(())
}
@@ -183,17 +178,18 @@ impl Client<SigningNymdClient> {
#[cfg(feature = "nymd-client")]
impl Client<QueryNymdClient> {
pub fn new_query(config: Config) -> Result<Client<QueryNymdClient>, ValidatorClientError> {
pub fn new_query(
config: Config,
// we need to provide network argument due to compatibility with other components (wallet...)
// that rely on its existence...
network: Network,
) -> Result<Client<QueryNymdClient>, ValidatorClientError> {
let validator_api_client = validator_api::Client::new(config.api_url.clone());
let nymd_client = NymdClient::connect(config.nymd_url.as_str())?
.with_mixnet_contract_address(config.mixnet_contract_address.clone())
.with_vesting_contract_address(config.vesting_contract_address.clone());
let nymd_client =
NymdClient::connect(config.nymd_config.clone(), config.nymd_url.as_str())?;
Ok(Client {
network: config.network,
mixnet_contract_address: config.mixnet_contract_address,
vesting_contract_address: config.vesting_contract_address,
bandwidth_claim_contract_address: config.bandwidth_claim_contract_address,
network,
mnemonic: None,
mixnode_page_limit: config.mixnode_page_limit,
gateway_page_limit: config.gateway_page_limit,
@@ -205,10 +201,7 @@ impl Client<QueryNymdClient> {
}
pub fn change_nymd(&mut self, new_endpoint: Url) -> Result<(), ValidatorClientError> {
self.nymd = NymdClient::connect(new_endpoint.as_ref())?
.with_mixnet_contract_address(self.mixnet_contract_address.clone())
.with_vesting_contract_address(self.vesting_contract_address.clone())
.with_bandwidth_claim_contract_address(self.bandwidth_claim_contract_address.clone());
self.nymd = NymdClient::connect(self.nymd.current_config().clone(), new_endpoint.as_ref())?;
Ok(())
}
}
@@ -222,11 +215,12 @@ impl<C> Client<C> {
// 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
pub fn set_mixnet_contract_address(&mut self, mixnet_contract_address: cosmrs::AccountId) {
self.mixnet_contract_address = mixnet_contract_address
self.nymd
.set_mixnet_contract_address(mixnet_contract_address)
}
pub fn get_mixnet_contract_address(&self) -> cosmrs::AccountId {
self.mixnet_contract_address.clone()
self.nymd.mixnet_contract_address().clone()
}
pub async fn get_cached_mixnodes(&self) -> Result<Vec<MixNodeBond>, ValidatorClientError> {
@@ -1,5 +1,5 @@
use crate::nymd::error::NymdError;
use crate::nymd::{NymdClient, QueryNymdClient};
use crate::nymd::{Config as ClientConfig, NymdClient, QueryNymdClient};
use crate::ApiClient;
use network_defaults::all::Network;
@@ -54,10 +54,20 @@ fn setup_connection_tests<H: BuildHasher + 'static>(
.get(&network)
.expect("No configured contract address")
.clone();
NymdClient::<QueryNymdClient>::connect(url.as_str())
.map(|client| client.with_mixnet_contract_address(address))
.map(move |client| ClientForConnectionTest::Nymd(network, url, Box::new(client)))
.ok()
let config = ClientConfig::try_from_nym_network_details(&network.details())
.expect("failed to create valid nymd client config");
if let Ok(mut client) = NymdClient::<QueryNymdClient>::connect(config, url.as_str()) {
// possibly redundant, but lets just leave it here
client.set_mixnet_contract_address(address);
Some(ClientForConnectionTest::Nymd(
network,
url,
Box::new(client),
))
} else {
None
}
});
let api_connection_test_clients = api_urls.map(|(network, url)| {
@@ -76,7 +86,7 @@ fn extract_and_collect_results_into_map(
.filter(|c| &c.url_type() == url_type)
.map(|c| {
let (network, url, result) = c.result();
(*network, (url.clone(), *result))
(network.clone(), (url.clone(), *result))
})
.into_group_map()
}
@@ -18,4 +18,7 @@ pub enum ValidatorClientError {
#[cfg(feature = "nymd-client")]
#[error("There was an issue with the Nymd client - {0}")]
NymdError(#[from] crate::nymd::error::NymdError),
#[error("No validator API url has been provided")]
NoAPIUrlAvailable,
}
@@ -130,6 +130,9 @@ pub enum NymdError {
#[error("Coconut interface error: {0}")]
CoconutInterfaceError(#[from] coconut_interface::error::CoconutInterfaceError),
#[error("Account had an unexpected bech32 prefix. Expected: {expected}, got: {got}")]
UnexpectedBech32Prefix { got: String, expected: String },
}
impl NymdError {
@@ -24,7 +24,6 @@ use mixnet_contract_common::{
PagedMixDelegationsResponse, PagedMixnodeResponse, PagedRewardedSetResponse, QueryMsg,
RewardedSetUpdateDetails,
};
use network_defaults::DEFAULT_NETWORK;
use serde::Serialize;
use std::convert::TryInto;
use vesting_contract_common::ExecuteMsg as VestingExecuteMsg;
@@ -50,6 +49,7 @@ pub use cosmrs::Coin as CosmosCoin;
pub use cosmrs::{bip32, AccountId, Decimal, Denom};
pub use cosmwasm_std::Coin as CosmWasmCoin;
pub use fee::{gas_price::GasPrice, GasAdjustable, GasAdjustment};
use network_defaults::{ChainDetails, NymNetworkDetails};
pub use signing_client::Client as SigningNymdClient;
pub use traits::{VestingQueryClient, VestingSigningClient};
@@ -60,67 +60,92 @@ pub mod fee;
pub mod traits;
pub mod wallet;
#[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<AccountId>,
pub(crate) vesting_contract_address: Option<AccountId>,
pub(crate) bandwidth_claim_contract_address: Option<AccountId>,
pub(crate) coconut_bandwidth_contract_address: Option<AccountId>,
pub(crate) multisig_contract_address: Option<AccountId>,
// TODO: add this in later commits
// pub(crate) gas_price: GasPrice,
}
impl Config {
fn parse_optional_account(
raw: Option<&String>,
expected_prefix: &str,
) -> Result<Option<AccountId>, NymdError> {
if let Some(address) = raw {
let parsed: AccountId = address
.parse()
.map_err(|_| NymdError::MalformedAccountAddress(address.clone()))?;
if parsed.prefix() != expected_prefix {
Err(NymdError::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<Self, NymdError> {
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,
)?,
bandwidth_claim_contract_address: Self::parse_optional_account(
details.contracts.bandwidth_claim_contract_address.as_ref(),
prefix,
)?,
coconut_bandwidth_contract_address: Self::parse_optional_account(
details
.contracts
.coconut_bandwidth_contract_address
.as_ref(),
prefix,
)?,
multisig_contract_address: Self::parse_optional_account(
details.contracts.multisig_contract_address.as_ref(),
prefix,
)?,
})
}
}
#[derive(Debug)]
pub struct NymdClient<C> {
client: C,
mixnet_contract_address: AccountId,
vesting_contract_address: AccountId,
bandwidth_claim_contract_address: AccountId,
coconut_bandwidth_contract_address: AccountId,
multisig_contract_address: AccountId,
config: Config,
client_address: Option<Vec<AccountId>>,
simulated_gas_multiplier: f32,
}
impl<C> NymdClient<C> {
pub fn with_mixnet_contract_address(mut self, address: AccountId) -> Self {
self.mixnet_contract_address = address;
self
}
pub fn with_vesting_contract_address(mut self, address: AccountId) -> Self {
self.vesting_contract_address = address;
self
}
pub fn with_bandwidth_claim_contract_address(mut self, address: AccountId) -> Self {
self.bandwidth_claim_contract_address = address;
self
}
pub fn with_coconut_bandwidth_contract_address(mut self, address: AccountId) -> Self {
self.coconut_bandwidth_contract_address = address;
self
}
pub fn with_multisig_contract_address(mut self, address: AccountId) -> Self {
self.multisig_contract_address = address;
self
}
}
impl NymdClient<QueryNymdClient> {
pub fn connect<U>(endpoint: U) -> Result<NymdClient<QueryNymdClient>, NymdError>
pub fn connect<U>(config: Config, endpoint: U) -> Result<NymdClient<QueryNymdClient>, NymdError>
where
U: TryInto<HttpClientUrl, Error = TendermintRpcError>,
{
Ok(NymdClient {
client: QueryNymdClient::new(endpoint)?,
config,
client_address: None,
simulated_gas_multiplier: DEFAULT_SIMULATED_GAS_MULTIPLIER,
mixnet_contract_address: DEFAULT_NETWORK
.mixnet_contract_address()
.parse()
.expect("Error parsing mixnet contract address"),
vesting_contract_address: DEFAULT_NETWORK
.vesting_contract_address()
.parse()
.expect("Error parsing vesting contract address"),
bandwidth_claim_contract_address: DEFAULT_NETWORK
.bandwidth_claim_contract_address()
.parse()
.expect("Error parsing bandwidth claim contract address"),
coconut_bandwidth_contract_address: DEFAULT_NETWORK
.coconut_bandwidth_contract_address()
.parse()
.unwrap(),
multisig_contract_address: DEFAULT_NETWORK.multisig_contract_address().parse().unwrap(),
})
}
}
@@ -128,6 +153,7 @@ impl NymdClient<QueryNymdClient> {
impl NymdClient<SigningNymdClient> {
// maybe the wallet could be made into a generic, but for now, let's just have this one implementation
pub fn connect_with_signer<U: Clone>(
config: Config,
network: config::defaults::all::Network,
endpoint: U,
signer: DirectSecp256k1HdWallet,
@@ -136,40 +162,24 @@ impl NymdClient<SigningNymdClient> {
where
U: TryInto<HttpClientUrl, Error = TendermintRpcError>,
{
let denom = network.mix_denom().base;
let denom = network.base_mix_denom();
let client_address = signer
.try_derive_accounts()?
.into_iter()
.map(|account| account.address)
.collect();
let gas_price = gas_price.unwrap_or(GasPrice::new_with_default_price(denom)?);
let gas_price = gas_price.unwrap_or(GasPrice::new_with_default_price(&denom)?);
Ok(NymdClient {
client: SigningNymdClient::connect_with_signer(endpoint, signer, gas_price)?,
config,
client_address: Some(client_address),
simulated_gas_multiplier: DEFAULT_SIMULATED_GAS_MULTIPLIER,
mixnet_contract_address: DEFAULT_NETWORK
.mixnet_contract_address()
.parse()
.expect("Error parsing mixnet contract address"),
vesting_contract_address: DEFAULT_NETWORK
.vesting_contract_address()
.parse()
.expect("Error parsing vesting contract address"),
bandwidth_claim_contract_address: DEFAULT_NETWORK
.bandwidth_claim_contract_address()
.parse()
.expect("Error parsing bandwidth claim contract address"),
coconut_bandwidth_contract_address: DEFAULT_NETWORK
.coconut_bandwidth_contract_address()
.parse()
.unwrap(),
multisig_contract_address: DEFAULT_NETWORK.multisig_contract_address().parse().unwrap(),
})
}
pub fn connect_with_mnemonic<U: Clone>(
network: config::defaults::all::Network,
config: Config,
endpoint: U,
mnemonic: bip39::Mnemonic,
gas_price: Option<GasPrice>,
@@ -177,8 +187,8 @@ impl NymdClient<SigningNymdClient> {
where
U: TryInto<HttpClientUrl, Error = TendermintRpcError>,
{
let prefix = network.bech32_prefix();
let denom = network.mix_denom().base;
let prefix = &config.chain_details.bech32_account_prefix;
let denom = &config.chain_details.mix_denom.base;
let wallet = DirectSecp256k1HdWallet::from_mnemonic(prefix, mnemonic)?;
let client_address = wallet
.try_derive_accounts()?
@@ -189,48 +199,82 @@ impl NymdClient<SigningNymdClient> {
Ok(NymdClient {
client: SigningNymdClient::connect_with_signer(endpoint, wallet, gas_price)?,
config,
client_address: Some(client_address),
simulated_gas_multiplier: DEFAULT_SIMULATED_GAS_MULTIPLIER,
mixnet_contract_address: network
.mixnet_contract_address()
.parse()
.expect("Error parsing mixnet contract address"),
vesting_contract_address: network
.vesting_contract_address()
.parse()
.expect("Error parsing vesting contract address"),
bandwidth_claim_contract_address: network
.bandwidth_claim_contract_address()
.parse()
.expect("Error parsing bandwidth claim contract address"),
coconut_bandwidth_contract_address: network
.coconut_bandwidth_contract_address()
.parse()
.unwrap(),
multisig_contract_address: network.multisig_contract_address().parse().unwrap(),
})
}
}
impl<C> NymdClient<C> {
pub fn current_config(&self) -> &Config {
&self.config
}
pub fn set_mixnet_contract_address(&mut self, address: AccountId) {
self.config.mixnet_contract_address = Some(address);
}
pub fn set_vesting_contract_address(&mut self, address: AccountId) {
self.config.vesting_contract_address = Some(address);
}
pub fn set_bandwidth_claim_contract_address(&mut self, address: AccountId) {
self.config.bandwidth_claim_contract_address = Some(address);
}
pub fn set_coconut_bandwidth_contract_address(&mut self, address: AccountId) {
self.config.coconut_bandwidth_contract_address = Some(address);
}
pub fn set_multisig_contract_address(&mut self, address: AccountId) {
self.config.multisig_contract_address = Some(address);
}
// TODO: this should get changed into Result<&AccountId, NymdError> (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.mixnet_contract_address
self.config.mixnet_contract_address.as_ref().unwrap()
}
// TODO: this should get changed into Result<&AccountId, NymdError> (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.vesting_contract_address
self.config.vesting_contract_address.as_ref().unwrap()
}
// TODO: this should get changed into Result<&AccountId, NymdError> (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 bandwidth_claim_contract_address(&self) -> &AccountId {
&self.bandwidth_claim_contract_address
self.config
.bandwidth_claim_contract_address
.as_ref()
.unwrap()
}
// TODO: this should get changed into Result<&AccountId, NymdError> (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.coconut_bandwidth_contract_address
self.config
.coconut_bandwidth_contract_address
.as_ref()
.unwrap()
}
// TODO: this should get changed into Result<&AccountId, NymdError> (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.multisig_contract_address
self.config.multisig_contract_address.as_ref().unwrap()
}
pub fn set_simulated_gas_multiplier(&mut self, multiplier: f32) {
@@ -214,7 +214,7 @@ mod tests {
];
for prefix in prefixes {
let addrs = match prefix {
let addrs = match prefix.as_ref() {
"nymt" => vec![
"nymt1jw6mp7d5xqc7w6xm79lha27glmd0vdt339me94",
"nymt1h5hgn94nsq4kh99rjj794hr5h5q6yfm23rjshv",
@@ -229,7 +229,7 @@ mod tests {
};
for (idx, mnemonic) in mnemonics.iter().enumerate() {
let wallet =
DirectSecp256k1HdWallet::from_mnemonic(prefix, mnemonic.parse().unwrap())
DirectSecp256k1HdWallet::from_mnemonic(&prefix, mnemonic.parse().unwrap())
.unwrap();
assert_eq!(
wallet.try_derive_accounts().unwrap()[0].address,
+93 -35
View File
@@ -1,14 +1,12 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::{
DefaultNetworkDetails, DenomDetailsOwned, NymNetworkDetails, ValidatorDetails,
MAINNET_DEFAULTS, QA_DEFAULTS, SANDBOX_DEFAULTS,
};
use serde::{Deserialize, Serialize};
use std::{collections::HashMap, fmt, str::FromStr};
use crate::{
DefaultNetworkDetails, DenomDetails, DenomDetailsOwned, ValidatorDetails, MAINNET_DEFAULTS,
QA_DEFAULTS, SANDBOX_DEFAULTS,
};
use thiserror::Error;
#[derive(Error, Debug)]
@@ -17,64 +15,95 @@ pub enum NetworkDefaultsError {
MalformedNetworkProvided(String),
}
#[derive(Copy, Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
// the reason for allowing it is that this is just a temporary solution
#[allow(clippy::large_enum_variant)]
#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
pub enum Network {
QA,
SANDBOX,
MAINNET,
CUSTOM { details: NymNetworkDetails },
}
impl Network {
fn details(&self) -> &DefaultNetworkDetails {
pub fn new_custom(details: NymNetworkDetails) -> Self {
Network::CUSTOM { details }
}
pub fn details(&self) -> NymNetworkDetails {
match self {
Self::QA => &QA_DEFAULTS,
Self::SANDBOX => &SANDBOX_DEFAULTS,
Self::MAINNET => &MAINNET_DEFAULTS,
Self::QA => (&*QA_DEFAULTS).into(),
Self::SANDBOX => (&*SANDBOX_DEFAULTS).into(),
Self::MAINNET => (&*MAINNET_DEFAULTS).into(),
// I dislike the clone here, but for compatibility reasons we cannot define other networks with `NymNetworkDetails` directly yet
Self::CUSTOM { details } => details.clone(),
}
}
pub fn bech32_prefix(&self) -> &str {
self.details().bech32_prefix
pub fn bech32_prefix(&self) -> String {
self.details().chain_details.bech32_account_prefix
}
pub fn mix_denom(&self) -> &DenomDetails {
&self.details().mix_denom
pub fn mix_denom(&self) -> DenomDetailsOwned {
self.details().chain_details.mix_denom
}
pub fn stake_denom(&self) -> &DenomDetails {
&self.details().stake_denom
pub fn stake_denom(&self) -> DenomDetailsOwned {
self.details().chain_details.stake_denom
}
pub fn mixnet_contract_address(&self) -> &str {
self.details().mixnet_contract_address
pub fn base_mix_denom(&self) -> String {
self.details().chain_details.mix_denom.base
}
pub fn vesting_contract_address(&self) -> &str {
self.details().vesting_contract_address
pub fn base_stake_denom(&self) -> String {
self.details().chain_details.stake_denom.base
}
pub fn bandwidth_claim_contract_address(&self) -> &str {
self.details().bandwidth_claim_contract_address
pub fn mixnet_contract_address(&self) -> Option<String> {
self.details().contracts.mixnet_contract_address
}
pub fn coconut_bandwidth_contract_address(&self) -> &str {
self.details().coconut_bandwidth_contract_address
pub fn vesting_contract_address(&self) -> Option<String> {
self.details().contracts.vesting_contract_address
}
pub fn multisig_contract_address(&self) -> &str {
self.details().multisig_contract_address
pub fn bandwidth_claim_contract_address(&self) -> Option<String> {
self.details().contracts.bandwidth_claim_contract_address
}
pub fn coconut_bandwidth_contract_address(&self) -> Option<String> {
self.details().contracts.coconut_bandwidth_contract_address
}
pub fn multisig_contract_address(&self) -> Option<String> {
self.details().contracts.multisig_contract_address
}
pub fn validators(&self) -> Vec<ValidatorDetails> {
self.details().endpoints
}
// only used in mixnet contract tests, but I don't want to be messing with that code now
pub fn rewarding_validator_address(&self) -> &str {
self.details().rewarding_validator_address
match self {
Network::QA => crate::qa::REWARDING_VALIDATOR_ADDRESS,
Network::SANDBOX => crate::sandbox::REWARDING_VALIDATOR_ADDRESS,
Network::MAINNET => crate::mainnet::REWARDING_VALIDATOR_ADDRESS,
Network::CUSTOM { .. } => {
panic!("rewarding validator address is unavailable for a custom network")
}
}
}
// this should be handled differently, but I don't want to break compatibility
pub fn statistics_service_url(&self) -> &str {
self.details().statistics_service_url
}
pub fn validators(&self) -> impl Iterator<Item = &ValidatorDetails> {
self.details().validators.iter()
match self {
Network::MAINNET => crate::mainnet::STATISTICS_SERVICE_DOMAIN_ADDRESS,
_ => {
panic!("statistics service url is only available for mainnet!")
}
}
}
}
@@ -99,6 +128,7 @@ impl fmt::Display for Network {
Network::QA => f.write_str("QA"),
Network::SANDBOX => f.write_str("Sandbox"),
Network::MAINNET => f.write_str("Mainnet"),
Network::CUSTOM { .. } => f.write_str("Custom"),
}
}
}
@@ -130,6 +160,31 @@ impl From<&DefaultNetworkDetails> for NetworkDetails {
}
}
// this also has to exist for compatibility reasons since I don't want to be touching the wallet now
impl From<NymNetworkDetails> for NetworkDetails {
fn from(details: NymNetworkDetails) -> Self {
NetworkDetails {
bech32_prefix: details.chain_details.bech32_account_prefix,
mix_denom: details.chain_details.mix_denom,
stake_denom: details.chain_details.stake_denom,
mixnet_contract_address: details
.contracts
.mixnet_contract_address
.unwrap_or_default(),
vesting_contract_address: details
.contracts
.vesting_contract_address
.unwrap_or_default(),
bandwidth_claim_contract_address: details
.contracts
.bandwidth_claim_contract_address
.unwrap_or_default(),
statistics_service_url: "".to_string(),
validators: details.endpoints,
}
}
}
impl NetworkDetails {
pub fn base_mix_denom(&self) -> &str {
&self.mix_denom.base
@@ -146,7 +201,10 @@ impl SupportedNetworks {
SupportedNetworks {
networks: support
.into_iter()
.map(|n| (n, n.details().into()))
.map(|n| {
let details = n.details().into();
(n, details)
})
.collect(),
}
}
+172 -11
View File
@@ -17,7 +17,7 @@ pub mod sandbox;
cfg_if::cfg_if! {
if #[cfg(network = "mainnet")] {
pub const DEFAULT_NETWORK: all::Network = all::Network::MAINNET;
pub const MIX_DENOM: DenomDetails = mainnet::MIX_DENOM;
pub const MIX_DENOM: DenomDetails = mainnet::MIX_DENOM;
pub const STAKE_DENOM: DenomDetails = mainnet::STAKE_DENOM;
pub const ETH_CONTRACT_ADDRESS: [u8; 20] = mainnet::_ETH_CONTRACT_ADDRESS;
@@ -25,7 +25,7 @@ cfg_if::cfg_if! {
} else if #[cfg(network = "qa")] {
pub const DEFAULT_NETWORK: all::Network = all::Network::QA;
pub const MIX_DENOM: DenomDetails = qa::MIX_DENOM;
pub const MIX_DENOM: DenomDetails = qa::MIX_DENOM;
pub const STAKE_DENOM: DenomDetails = qa::STAKE_DENOM;
pub const ETH_CONTRACT_ADDRESS: [u8; 20] = qa::_ETH_CONTRACT_ADDRESS;
@@ -41,10 +41,157 @@ cfg_if::cfg_if! {
}
}
#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
pub struct ChainDetails {
pub bech32_account_prefix: String,
pub mix_denom: DenomDetailsOwned,
pub stake_denom: DenomDetailsOwned,
}
// by default we assume the same defaults as mainnet, i.e. same prefixes and denoms
impl Default for ChainDetails {
fn default() -> Self {
ChainDetails {
bech32_account_prefix: mainnet::BECH32_PREFIX.into(),
mix_denom: mainnet::MIX_DENOM.into(),
stake_denom: mainnet::STAKE_DENOM.into(),
}
}
}
#[derive(Clone, Debug, Default, Deserialize, Eq, Hash, PartialEq, Serialize)]
pub struct NymContracts {
pub mixnet_contract_address: Option<String>,
pub vesting_contract_address: Option<String>,
pub bandwidth_claim_contract_address: Option<String>,
pub coconut_bandwidth_contract_address: Option<String>,
pub multisig_contract_address: Option<String>,
}
// I wanted to use the simpler `NetworkDetails` name, but there's a clash
// with `NetworkDetails` defined in all.rs...
#[derive(Clone, Debug, Default, Deserialize, Eq, Hash, PartialEq, Serialize)]
pub struct NymNetworkDetails {
pub chain_details: ChainDetails,
pub endpoints: Vec<ValidatorDetails>,
pub contracts: NymContracts,
}
impl NymNetworkDetails {
pub fn new() -> Self {
NymNetworkDetails::default()
}
pub fn new_qa() -> Self {
(&*QA_DEFAULTS).into()
}
pub fn new_sandbox() -> Self {
(&*SANDBOX_DEFAULTS).into()
}
pub fn new_mainnet() -> Self {
(&*MAINNET_DEFAULTS).into()
}
pub fn current_default() -> Self {
// backwards compatibility reasons
DEFAULT_NETWORK.details()
}
pub fn with_bech32_account_prefix<S: Into<String>>(mut self, prefix: S) -> Self {
self.chain_details.bech32_account_prefix = prefix.into();
self
}
pub fn with_mix_denom(mut self, mix_denom: DenomDetailsOwned) -> Self {
self.chain_details.mix_denom = mix_denom;
self
}
pub fn with_stake_denom(mut self, stake_denom: DenomDetailsOwned) -> Self {
self.chain_details.stake_denom = stake_denom;
self
}
pub fn with_base_mix_denom<S: Into<String>>(mut self, base_mix_denom: S) -> Self {
self.chain_details.mix_denom = DenomDetailsOwned::base_only(base_mix_denom.into());
self
}
pub fn with_base_stake_denom<S: Into<String>>(mut self, base_stake_denom: S) -> Self {
self.chain_details.stake_denom = DenomDetailsOwned::base_only(base_stake_denom.into());
self
}
pub fn with_validator_endpoint(mut self, endpoint: ValidatorDetails) -> Self {
self.endpoints.push(endpoint);
self
}
pub fn with_mixnet_contract<S: Into<String>>(mut self, contract: Option<S>) -> Self {
self.contracts.mixnet_contract_address = contract.map(Into::into);
self
}
pub fn with_vesting_contract<S: Into<String>>(mut self, contract: Option<S>) -> Self {
self.contracts.vesting_contract_address = contract.map(Into::into);
self
}
pub fn with_bandwidth_claim_contract<S: Into<String>>(mut self, contract: Option<S>) -> Self {
self.contracts.bandwidth_claim_contract_address = contract.map(Into::into);
self
}
pub fn with_coconut_bandwidth_contract<S: Into<String>>(mut self, contract: Option<S>) -> Self {
self.contracts.coconut_bandwidth_contract_address = contract.map(Into::into);
self
}
pub fn with_multisig_contract<S: Into<String>>(mut self, contract: Option<S>) -> Self {
self.contracts.multisig_contract_address = contract.map(Into::into);
self
}
}
// This conversion only exists for convenience reasons until
// we can completely phase out `DefaultNetworkDetails`
impl<'a> From<&'a DefaultNetworkDetails> for NymNetworkDetails {
fn from(details: &'a DefaultNetworkDetails) -> Self {
fn parse_optional_str(raw: &str) -> Option<String> {
if raw.is_empty() {
None
} else {
Some(raw.into())
}
}
NymNetworkDetails {
chain_details: ChainDetails {
bech32_account_prefix: details.bech32_prefix.into(),
mix_denom: details.mix_denom.into(),
stake_denom: details.stake_denom.into(),
},
endpoints: details.validators.clone(),
contracts: NymContracts {
mixnet_contract_address: parse_optional_str(details.mixnet_contract_address),
vesting_contract_address: parse_optional_str(details.vesting_contract_address),
bandwidth_claim_contract_address: parse_optional_str(
details.bandwidth_claim_contract_address,
),
coconut_bandwidth_contract_address: parse_optional_str(
details.coconut_bandwidth_contract_address,
),
multisig_contract_address: parse_optional_str(details.multisig_contract_address),
},
}
}
}
// Since these are lazily constructed, we can afford to switch some of them to stronger types in the
// future. If we do this, and also get rid of the references we could potentially unify with
// `NetworkDetails`.
#[derive(Debug)]
pub struct DefaultNetworkDetails {
bech32_prefix: &'static str,
mix_denom: DenomDetails,
@@ -54,6 +201,7 @@ pub struct DefaultNetworkDetails {
bandwidth_claim_contract_address: &'static str,
coconut_bandwidth_contract_address: &'static str,
multisig_contract_address: &'static str,
#[allow(dead_code)]
rewarding_validator_address: &'static str,
statistics_service_url: &'static str,
validators: Vec<ValidatorDetails>,
@@ -119,7 +267,7 @@ impl DenomDetails {
}
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
pub struct DenomDetailsOwned {
pub base: String,
pub display: String,
@@ -137,27 +285,38 @@ impl From<DenomDetails> for DenomDetailsOwned {
}
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
impl DenomDetailsOwned {
pub fn base_only(base: String) -> Self {
DenomDetailsOwned {
base: base.clone(),
display: base,
display_exponent: 0,
}
}
}
#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
pub struct ValidatorDetails {
// it is assumed those values are always valid since they're being provided in our defaults file
pub nymd_url: String,
// Right now api_url is optional as we are not running the api reliably on all validators
// however, later on it should be a mandatory field
pub api_url: Option<String>,
// TODO: I'd argue this one should also have a field like `gas_price` since its a validator-specific setting
}
impl ValidatorDetails {
pub fn new(nymd_url: &str, api_url: Option<&str>) -> Self {
pub fn new<S: Into<String>>(nymd_url: S, api_url: Option<S>) -> Self {
ValidatorDetails {
nymd_url: nymd_url.to_string(),
api_url: api_url.map(ToString::to_string),
nymd_url: nymd_url.into(),
api_url: api_url.map(Into::into),
}
}
pub fn new_with_name(nymd_url: &str, api_url: Option<&str>) -> Self {
pub fn new_nymd_only<S: Into<String>>(nymd_url: S) -> Self {
ValidatorDetails {
nymd_url: nymd_url.to_string(),
api_url: api_url.map(ToString::to_string),
nymd_url: nymd_url.into(),
api_url: None,
}
}
@@ -184,6 +343,7 @@ pub fn default_statistics_service_url() -> Url {
pub fn default_nymd_endpoints() -> Vec<Url> {
DEFAULT_NETWORK
.validators()
.iter()
.map(ValidatorDetails::nymd_url)
.collect()
}
@@ -191,6 +351,7 @@ pub fn default_nymd_endpoints() -> Vec<Url> {
pub fn default_api_endpoints() -> Vec<Url> {
DEFAULT_NETWORK
.validators()
.iter()
.filter_map(ValidatorDetails::api_url)
.collect()
}
+3
View File
@@ -51,6 +51,8 @@ pub enum TypesError {
#[from]
source: cosmwasm_std::DecimalRangeExceeded,
},
#[error("No validator API URL configured")]
NoValidatorApiUrlConfigured,
#[error("{0} is not a valid amount string")]
InvalidAmount(String),
#[error("{0} is not a valid denomination string")]
@@ -78,6 +80,7 @@ impl From<ValidatorClientError> for TypesError {
ValidatorClientError::ValidatorAPIError { source } => source.into(),
ValidatorClientError::MalformedUrlProvided(e) => e.into(),
ValidatorClientError::NymdError(e) => e.into(),
ValidatorClientError::NoAPIUrlAvailable => TypesError::NoValidatorApiUrlConfigured,
}
}
}
@@ -22,7 +22,7 @@ pub mod helpers {
let env = mock_env();
let info = mock_info("creator", &[]);
instantiate(deps.as_mut(), env.clone(), info, msg).unwrap();
return deps;
deps
}
pub fn mock_app(init_funds: &[Coin]) -> App {
+6 -2
View File
@@ -26,9 +26,13 @@ pub(crate) fn new_validator_client() -> ThreadsafeValidatorClient {
let nymd_url = default_nymd_endpoints()[0].clone();
let api_url = default_api_endpoints()[0].clone();
let client_config = validator_client::Config::new(DEFAULT_NETWORK, nymd_url, api_url);
let client_config =
validator_client::Config::try_from_nym_network_details(&DEFAULT_NETWORK.details())
.expect("failed to construct valid validator client config with the provided network")
.with_urls(nymd_url, api_url);
ThreadsafeValidatorClient(Arc::new(
validator_client::Client::new_query(client_config).expect("Failed to connect to nymd!"),
validator_client::Client::new_query(client_config, DEFAULT_NETWORK)
.expect("Failed to connect to nymd!"),
))
}
@@ -1,14 +1,6 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use std::str::FromStr;
use web3::contract::tokens::Detokenize;
use web3::contract::{Contract, Error};
use web3::ethabi::Token;
use web3::transports::Http;
use web3::types::{BlockNumber, FilterBuilder, H256};
use web3::Web3;
use crate::node::client_handling::websocket::connection_handler::authenticated::RequestHandlingError;
use bandwidth_claim_contract::msg::ExecuteMsg;
use bandwidth_claim_contract::payment::LinkPaymentData;
@@ -16,7 +8,14 @@ use credentials::token::bandwidth::TokenCredential;
use crypto::asymmetric::identity::{PublicKey, Signature, SIGNATURE_LENGTH};
use gateway_client::bandwidth::eth_contract;
use network_defaults::{ETH_EVENT_NAME, ETH_MIN_BLOCK_DEPTH};
use std::str::FromStr;
use validator_client::nymd::{AccountId, NymdClient, SigningNymdClient};
use web3::contract::tokens::Detokenize;
use web3::contract::{Contract, Error};
use web3::ethabi::Token;
use web3::transports::Http;
use web3::types::{BlockNumber, FilterBuilder, H256};
use web3::Web3;
pub(crate) struct ERC20Bridge {
// This is needed because web3's Contract doesn't sufficiently expose it's eth interface
+5 -1
View File
@@ -27,6 +27,7 @@ use crate::node::client_handling::websocket::connection_handler::coconut::Coconu
use crate::node::client_handling::websocket::connection_handler::eth_events::ERC20Bridge;
#[cfg(feature = "coconut")]
use credentials::obtain_aggregate_verification_key;
use validator_client::nymd;
use self::storage::PersistentStorage;
@@ -248,8 +249,11 @@ where
.choose(&mut thread_rng())
.expect("The list of validators is empty");
let client_config = nymd::Config::try_from_nym_network_details(&DEFAULT_NETWORK.details())
.expect("failed to construct valid validator client config with the provided network");
validator_client::nymd::NymdClient::connect_with_mnemonic(
DEFAULT_NETWORK,
client_config,
validator_nymd.as_ref(),
self.config.get_cosmos_mnemonic(),
None,
+4
View File
@@ -5508,6 +5508,10 @@ dependencies = [
name = "validator-api-requests"
version = "0.1.0"
dependencies = [
"bs58",
"coconut-interface",
"cosmrs",
"getset",
"mixnet-contract-common",
"schemars",
"serde",
@@ -65,6 +65,7 @@ impl From<ConfigNetwork> for Network {
ConfigNetwork::QA => Network::QA,
ConfigNetwork::SANDBOX => Network::SANDBOX,
ConfigNetwork::MAINNET => Network::MAINNET,
ConfigNetwork::CUSTOM { .. } => panic!("custom network is not supported"),
}
}
}
+3
View File
@@ -123,6 +123,9 @@ impl From<ValidatorClientError> for BackendError {
ValidatorClientError::ValidatorAPIError { source } => source.into(),
ValidatorClientError::MalformedUrlProvided(e) => e.into(),
ValidatorClientError::NymdError(e) => e.into(),
ValidatorClientError::NoAPIUrlAvailable => {
TypesError::NoValidatorApiUrlConfigured.into()
}
}
}
}
@@ -157,7 +157,7 @@ async fn _connect_with_mnemonic(
let default_network: WalletNetwork = config::defaults::DEFAULT_NETWORK.into();
let client_for_default_network = clients
.iter()
.find(|client| WalletNetwork::from(client.network) == default_network);
.find(|client| WalletNetwork::from(client.network.clone()) == default_network);
let account_for_default_network = match client_for_default_network {
Some(client) => Ok(Account::new(
client.nymd.mixnet_contract_address().to_string(),
@@ -175,7 +175,7 @@ async fn _connect_with_mnemonic(
w_state.logout();
}
for client in clients {
let network: WalletNetwork = client.network.into();
let network: WalletNetwork = client.network.clone().into();
let mut w_state = state.write().await;
w_state.add_client(network, client);
}
@@ -252,15 +252,21 @@ fn create_clients(
log::info!("Connecting to: nymd_url: {nymd_url} for {network}");
log::info!("Connecting to: api_url: {api_url} for {network}");
let mut client = validator_client::Client::new_signing(
validator_client::Config::new(network.into(), nymd_url, api_url)
.with_mixnode_contract_address(config.get_mixnet_contract_address(network))
.with_vesting_contract_address(config.get_vesting_contract_address(network))
.with_bandwidth_claim_contract_address(
config.get_bandwidth_claim_contract_address(network),
),
mnemonic.clone(),
)?;
let network_details = Network::from(network)
.details()
.with_mixnet_contract(Some(config.get_mixnet_contract_address(network).as_ref()))
.with_vesting_contract(Some(config.get_vesting_contract_address(network).as_ref()))
.with_bandwidth_claim_contract(Some(
config
.get_bandwidth_claim_contract_address(network)
.as_ref(),
));
let config = validator_client::Config::try_from_nym_network_details(&network_details)?
.with_urls(nymd_url, api_url);
let mut client =
validator_client::Client::new_signing(config, network.into(), mnemonic.clone())?;
client.set_nymd_simulated_gas_multiplier(CUSTOM_SIMULATED_GAS_MULTIPLIER);
clients.push(client);
}
@@ -435,7 +441,7 @@ pub async fn add_account_for_password(
let address = {
let state = state.read().await;
let network: Network = state.current_network().into();
derive_address(mnemonic, network.bech32_prefix())?.to_string()
derive_address(mnemonic, &network.bech32_prefix())?.to_string()
};
// Re-read all the acccounts from the wallet to reset the state, rather than updating it
@@ -477,7 +483,7 @@ async fn set_state_with_all_accounts(
let config_network: Network = network.into();
(
network,
derive_address(mnemonic.clone(), config_network.bech32_prefix()).unwrap(),
derive_address(mnemonic.clone(), &config_network.bech32_prefix()).unwrap(),
)
})
.collect();
@@ -71,6 +71,9 @@ impl OptionalStatsProviderConfig {
network_defaults::all::Network::MAINNET => self.mainnet.clone(),
network_defaults::all::Network::SANDBOX => self.sandbox.clone(),
network_defaults::all::Network::QA => self.qa.clone(),
network_defaults::all::Network::CUSTOM { .. } => {
panic!("custom network is not supported")
}
};
entry_config.map(|e| e.stats_client_address)
}
+3 -1
View File
@@ -108,7 +108,9 @@ impl Default for Base {
local_validator: DEFAULT_LOCAL_VALIDATOR
.parse()
.expect("default local validator is malformed!"),
mixnet_contract_address: DEFAULT_NETWORK.mixnet_contract_address().to_string(),
mixnet_contract_address: DEFAULT_NETWORK
.mixnet_contract_address()
.expect("mixnet contract address is unavailable"),
mnemonic: "exact antique hybrid width raise anchor puzzle degree fee quit long crack net vague hip despair write put useless civil mechanic broom music day".to_string(),
}
}
+18 -16
View File
@@ -53,16 +53,16 @@ impl Client<QueryNymdClient> {
.unwrap();
let nymd_url = config.get_nymd_validator_url();
let network = DEFAULT_NETWORK;
let details = network
.details()
.with_mixnet_contract(Some(config.get_mixnet_contract_address()));
let mixnet_contract = config
.get_mixnet_contract_address()
.parse()
.expect("the mixnet contract address is invalid!");
let client_config = validator_client::Config::try_from_nym_network_details(&details)
.expect("failed to construct valid validator client config with the provided network")
.with_urls(nymd_url, api_url);
let client_config = validator_client::Config::new(network, nymd_url, api_url)
.with_mixnode_contract_address(mixnet_contract);
let inner =
validator_client::Client::new_query(client_config).expect("Failed to connect to nymd!");
let inner = validator_client::Client::new_query(client_config, network)
.expect("Failed to connect to nymd!");
Client(Arc::new(RwLock::new(inner)))
}
@@ -76,20 +76,22 @@ impl Client<SigningNymdClient> {
.parse()
.unwrap();
let nymd_url = config.get_nymd_validator_url();
let network = DEFAULT_NETWORK;
let mixnet_contract = config
.get_mixnet_contract_address()
.parse()
.expect("the mixnet contract address is invalid!");
let network = DEFAULT_NETWORK;
let details = network
.details()
.with_mixnet_contract(Some(config.get_mixnet_contract_address()));
let client_config = validator_client::Config::try_from_nym_network_details(&details)
.expect("failed to construct valid validator client config with the provided network")
.with_urls(nymd_url, api_url);
let mnemonic = config
.get_mnemonic()
.parse()
.expect("the mnemonic is invalid!");
let client_config = validator_client::Config::new(network, nymd_url, api_url)
.with_mixnode_contract_address(mixnet_contract);
let inner = validator_client::Client::new_signing(client_config, mnemonic)
let inner = validator_client::Client::new_signing(client_config, network, mnemonic)
.expect("Failed to connect to nymd!");
Client(Arc::new(RwLock::new(inner)))