Feature/include nymd client in gateway (#1398)
* Reinclude custom validators in coconut * Check mnemonic validity early * Include nymd client in coconut verifier and simplify the erc20 bridge part
This commit is contained in:
committed by
GitHub
parent
6b07f31a87
commit
ae88e25300
@@ -43,6 +43,10 @@ pub struct Init {
|
||||
#[clap(long)]
|
||||
validator_apis: Option<String>,
|
||||
|
||||
/// Comma separated list of endpoints of the validator
|
||||
#[clap(long)]
|
||||
validators: Option<String>,
|
||||
|
||||
/// Cosmos wallet mnemonic needed for double spending protection
|
||||
#[clap(long)]
|
||||
mnemonic: Option<String>,
|
||||
@@ -64,11 +68,6 @@ pub struct Init {
|
||||
/// URL where a statistics aggregator is running. The default value is a Nym aggregator server
|
||||
#[clap(long)]
|
||||
statistics_service_url: Option<String>,
|
||||
|
||||
/// Comma separated list of endpoints of the validator
|
||||
#[cfg(all(feature = "eth", not(feature = "coconut")))]
|
||||
#[clap(long)]
|
||||
validators: Option<String>,
|
||||
}
|
||||
|
||||
impl From<Init> for OverrideConfig {
|
||||
@@ -81,6 +80,7 @@ impl From<Init> for OverrideConfig {
|
||||
datastore: init_config.datastore,
|
||||
announce_host: init_config.announce_host,
|
||||
validator_apis: init_config.validator_apis,
|
||||
validators: init_config.validators,
|
||||
mnemonic: init_config.mnemonic,
|
||||
|
||||
#[cfg(all(feature = "eth", not(feature = "coconut")))]
|
||||
@@ -91,9 +91,6 @@ impl From<Init> for OverrideConfig {
|
||||
|
||||
enabled_statistics: init_config.enabled_statistics,
|
||||
statistics_service_url: init_config.statistics_service_url,
|
||||
|
||||
#[cfg(all(feature = "eth", not(feature = "coconut")))]
|
||||
validators: init_config.validators,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -174,15 +171,14 @@ mod tests {
|
||||
announce_host: Some("foo-announce-host".to_string()),
|
||||
datastore: Some("foo-datastore".to_string()),
|
||||
validator_apis: None,
|
||||
mnemonic: Some("a b c".to_string()),
|
||||
validators: None,
|
||||
mnemonic: None,
|
||||
statistics_service_url: None,
|
||||
enabled_statistics: None,
|
||||
#[cfg(all(feature = "eth", not(feature = "coconut")))]
|
||||
enabled_credentials_mode: None,
|
||||
#[cfg(all(feature = "eth", not(feature = "coconut")))]
|
||||
eth_endpoint: "".to_string(),
|
||||
#[cfg(all(feature = "eth", not(feature = "coconut")))]
|
||||
validators: None,
|
||||
};
|
||||
|
||||
let config = Config::new(&args.id);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright 2020 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use std::process;
|
||||
use std::{process, str::FromStr};
|
||||
|
||||
use crate::{config::Config, Cli};
|
||||
use clap::Subcommand;
|
||||
@@ -17,9 +17,6 @@ pub(crate) mod upgrade;
|
||||
|
||||
#[cfg(all(not(feature = "eth"), not(feature = "coconut")))]
|
||||
const DEFAULT_ETH_ENDPOINT: &str = "https://rinkeby.infura.io/v3/00000000000000000000000000000000";
|
||||
#[cfg(all(not(feature = "eth"), not(feature = "coconut")))]
|
||||
const DEFAULT_VALIDATOR_ENDPOINT: &str = "http://localhost:26657";
|
||||
|
||||
#[derive(Subcommand)]
|
||||
pub(crate) enum Commands {
|
||||
/// Initialise the gateway
|
||||
@@ -49,6 +46,7 @@ pub(crate) struct OverrideConfig {
|
||||
enabled_statistics: Option<bool>,
|
||||
statistics_service_url: Option<String>,
|
||||
validator_apis: Option<String>,
|
||||
validators: Option<String>,
|
||||
mnemonic: Option<String>,
|
||||
|
||||
#[cfg(all(feature = "eth", not(feature = "coconut")))]
|
||||
@@ -56,9 +54,6 @@ pub(crate) struct OverrideConfig {
|
||||
|
||||
#[cfg(all(feature = "eth", not(feature = "coconut")))]
|
||||
eth_endpoint: Option<String>,
|
||||
|
||||
#[cfg(all(feature = "eth", not(feature = "coconut")))]
|
||||
validators: Option<String>,
|
||||
}
|
||||
|
||||
pub(crate) async fn execute(args: Cli) {
|
||||
@@ -120,6 +115,10 @@ pub(crate) fn override_config(mut config: Config, args: OverrideConfig) -> Confi
|
||||
config = config.with_custom_validator_apis(parse_validators(&raw_validators));
|
||||
}
|
||||
|
||||
if let Some(raw_validators) = args.validators {
|
||||
config = config.with_custom_validator_nymd(parse_validators(&raw_validators));
|
||||
}
|
||||
|
||||
if let Some(wallet_address) = args.wallet_address {
|
||||
let trimmed = wallet_address.trim();
|
||||
validate_bech32_address_or_exit(trimmed);
|
||||
@@ -131,12 +130,13 @@ pub(crate) fn override_config(mut config: Config, args: OverrideConfig) -> Confi
|
||||
}
|
||||
|
||||
if let Some(cosmos_mnemonic) = args.mnemonic {
|
||||
config = config.with_cosmos_mnemonic(cosmos_mnemonic);
|
||||
config = config.with_cosmos_mnemonic(
|
||||
bip39::Mnemonic::from_str(&cosmos_mnemonic).expect("Provided mnemonic is invalid"),
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(all(not(feature = "eth"), not(feature = "coconut")))]
|
||||
{
|
||||
config = config.with_custom_validator_nymd(parse_validators(DEFAULT_VALIDATOR_ENDPOINT));
|
||||
config = config.with_eth_endpoint(String::from(DEFAULT_ETH_ENDPOINT));
|
||||
}
|
||||
|
||||
|
||||
@@ -43,6 +43,10 @@ pub struct Run {
|
||||
#[clap(long)]
|
||||
validator_apis: Option<String>,
|
||||
|
||||
/// Comma separated list of endpoints of the validator
|
||||
#[clap(long)]
|
||||
validators: Option<String>,
|
||||
|
||||
/// Cosmos wallet mnemonic
|
||||
#[clap(long)]
|
||||
mnemonic: Option<String>,
|
||||
@@ -64,11 +68,6 @@ pub struct Run {
|
||||
/// URL where a statistics aggregator is running. The default value is a Nym aggregator server
|
||||
#[clap(long)]
|
||||
statistics_service_url: Option<String>,
|
||||
|
||||
/// Comma separated list of endpoints of the validator
|
||||
#[cfg(all(feature = "eth", not(feature = "coconut")))]
|
||||
#[clap(long)]
|
||||
validators: Option<String>,
|
||||
}
|
||||
|
||||
impl From<Run> for OverrideConfig {
|
||||
@@ -81,6 +80,7 @@ impl From<Run> for OverrideConfig {
|
||||
datastore: run_config.datastore,
|
||||
announce_host: run_config.announce_host,
|
||||
validator_apis: run_config.validator_apis,
|
||||
validators: run_config.validators,
|
||||
mnemonic: run_config.mnemonic,
|
||||
|
||||
#[cfg(all(feature = "eth", not(feature = "coconut")))]
|
||||
@@ -91,9 +91,6 @@ impl From<Run> for OverrideConfig {
|
||||
|
||||
enabled_statistics: run_config.enabled_statistics,
|
||||
statistics_service_url: run_config.statistics_service_url,
|
||||
|
||||
#[cfg(all(feature = "eth", not(feature = "coconut")))]
|
||||
validators: run_config.validators,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ use log::error;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::net::IpAddr;
|
||||
use std::path::PathBuf;
|
||||
use std::str::FromStr;
|
||||
use std::time::Duration;
|
||||
use url::Url;
|
||||
|
||||
@@ -142,13 +143,12 @@ impl Config {
|
||||
self
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "coconut"))]
|
||||
pub fn with_custom_validator_nymd(mut self, validator_nymd_urls: Vec<Url>) -> Self {
|
||||
self.gateway.validator_nymd_urls = validator_nymd_urls;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_cosmos_mnemonic(mut self, cosmos_mnemonic: String) -> Self {
|
||||
pub fn with_cosmos_mnemonic(mut self, cosmos_mnemonic: bip39::Mnemonic) -> Self {
|
||||
self.gateway.cosmos_mnemonic = cosmos_mnemonic;
|
||||
self
|
||||
}
|
||||
@@ -249,12 +249,11 @@ impl Config {
|
||||
self.gateway.validator_api_urls.clone()
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "coconut"))]
|
||||
pub fn get_validator_nymd_endpoints(&self) -> Vec<Url> {
|
||||
self.gateway.validator_nymd_urls.clone()
|
||||
}
|
||||
|
||||
pub fn _get_cosmos_mnemonic(&self) -> String {
|
||||
pub fn get_cosmos_mnemonic(&self) -> bip39::Mnemonic {
|
||||
self.gateway.cosmos_mnemonic.clone()
|
||||
}
|
||||
|
||||
@@ -367,11 +366,10 @@ pub struct Gateway {
|
||||
validator_api_urls: Vec<Url>,
|
||||
|
||||
/// Addresses to validators which the node uses to check for double spending of ERC20 tokens.
|
||||
#[cfg(not(feature = "coconut"))]
|
||||
validator_nymd_urls: Vec<Url>,
|
||||
|
||||
/// Mnemonic of a cosmos wallet used in checking for double spending.
|
||||
cosmos_mnemonic: String,
|
||||
cosmos_mnemonic: bip39::Mnemonic,
|
||||
|
||||
/// nym_home_directory specifies absolute path to the home nym gateways directory.
|
||||
/// It is expected to use default value and hence .toml file should not redefine this field.
|
||||
@@ -426,9 +424,8 @@ impl Default for Gateway {
|
||||
enabled_statistics: false,
|
||||
statistics_service_url: default_statistics_service_url(),
|
||||
validator_api_urls: default_api_endpoints(),
|
||||
#[cfg(not(feature = "coconut"))]
|
||||
validator_nymd_urls: default_nymd_endpoints(),
|
||||
cosmos_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(),
|
||||
cosmos_mnemonic: bip39::Mnemonic::from_str("exact antique hybrid width raise anchor puzzle degree fee quit long crack net vague hip despair write put useless civil mechanic broom music day").unwrap(),
|
||||
nym_root_directory: Config::default_root_directory(),
|
||||
persistent_storage: Default::default(),
|
||||
wallet_address: "nymXXXXXXXX".to_string(),
|
||||
|
||||
@@ -2,17 +2,26 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use coconut_interface::VerificationKey;
|
||||
use validator_client::ApiClient;
|
||||
use validator_client::{
|
||||
nymd::{NymdClient, SigningNymdClient},
|
||||
ApiClient,
|
||||
};
|
||||
|
||||
pub struct CoconutVerifier {
|
||||
api_clients: Vec<ApiClient>,
|
||||
_nymd_client: NymdClient<SigningNymdClient>,
|
||||
aggregated_verification_key: VerificationKey,
|
||||
}
|
||||
|
||||
impl CoconutVerifier {
|
||||
pub fn new(api_clients: Vec<ApiClient>, aggregated_verification_key: VerificationKey) -> Self {
|
||||
pub fn new(
|
||||
api_clients: Vec<ApiClient>,
|
||||
_nymd_client: NymdClient<SigningNymdClient>,
|
||||
aggregated_verification_key: VerificationKey,
|
||||
) -> Self {
|
||||
CoconutVerifier {
|
||||
api_clients,
|
||||
_nymd_client,
|
||||
aggregated_verification_key,
|
||||
}
|
||||
}
|
||||
@@ -21,6 +30,10 @@ impl CoconutVerifier {
|
||||
&self.api_clients
|
||||
}
|
||||
|
||||
pub fn _nymd_client(&self) -> &NymdClient<SigningNymdClient> {
|
||||
&self._nymd_client
|
||||
}
|
||||
|
||||
pub fn aggregated_verification_key(&self) -> &VerificationKey {
|
||||
&self.aggregated_verification_key
|
||||
}
|
||||
|
||||
@@ -1,12 +1,7 @@
|
||||
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use bip39::core::str::FromStr;
|
||||
use bip39::Mnemonic;
|
||||
use config::defaults::DEFAULT_NETWORK;
|
||||
use rand::seq::SliceRandom;
|
||||
use rand::thread_rng;
|
||||
use url::Url;
|
||||
use std::str::FromStr;
|
||||
use web3::contract::tokens::Detokenize;
|
||||
use web3::contract::{Contract, Error};
|
||||
use web3::ethabi::Token;
|
||||
@@ -31,17 +26,9 @@ pub(crate) struct ERC20Bridge {
|
||||
}
|
||||
|
||||
impl ERC20Bridge {
|
||||
pub fn new(eth_endpoint: String, nymd_urls: Vec<Url>, cosmos_mnemonic: String) -> Self {
|
||||
pub fn new(eth_endpoint: String, nymd_client: NymdClient<SigningNymdClient>) -> Self {
|
||||
let transport = Http::new(ð_endpoint).expect("Invalid Ethereum endpoint");
|
||||
let web3 = Web3::new(transport);
|
||||
let nymd_url = nymd_urls
|
||||
.choose(&mut thread_rng())
|
||||
.expect("The list of validators is empty");
|
||||
let mnemonic =
|
||||
Mnemonic::from_str(&cosmos_mnemonic).expect("Invalid Cosmos mnemonic provided");
|
||||
let nymd_client =
|
||||
NymdClient::connect_with_mnemonic(DEFAULT_NETWORK, nymd_url.as_ref(), mnemonic, None)
|
||||
.expect("Could not create nymd client");
|
||||
|
||||
ERC20Bridge {
|
||||
contract: eth_contract(web3.clone()),
|
||||
|
||||
+26
-7
@@ -9,6 +9,7 @@ use crate::node::client_handling::websocket;
|
||||
use crate::node::mixnet_handling::receiver::connection_handler::ConnectionHandler;
|
||||
use crate::node::statistics::collector::GatewayStatisticsCollector;
|
||||
use crate::node::storage::Storage;
|
||||
use config::defaults::DEFAULT_NETWORK;
|
||||
use crypto::asymmetric::{encryption, identity};
|
||||
use log::*;
|
||||
use mixnet_client::forwarder::{MixForwardingSender, PacketForwarder};
|
||||
@@ -239,6 +240,23 @@ where
|
||||
validator_client::ApiClient::new(validator_api.clone())
|
||||
}
|
||||
|
||||
fn random_nymd_client(
|
||||
&self,
|
||||
) -> validator_client::nymd::NymdClient<validator_client::nymd::SigningNymdClient> {
|
||||
let endpoints = self.config.get_validator_nymd_endpoints();
|
||||
let validator_nymd = endpoints
|
||||
.choose(&mut thread_rng())
|
||||
.expect("The list of validators is empty");
|
||||
|
||||
validator_client::nymd::NymdClient::connect_with_mnemonic(
|
||||
DEFAULT_NETWORK,
|
||||
validator_nymd.as_ref(),
|
||||
self.config.get_cosmos_mnemonic(),
|
||||
None,
|
||||
)
|
||||
.expect("Could not connect with mnemonic")
|
||||
}
|
||||
|
||||
#[cfg(feature = "coconut")]
|
||||
fn all_api_clients(&self) -> Vec<validator_client::ApiClient> {
|
||||
self.config
|
||||
@@ -288,16 +306,17 @@ where
|
||||
obtain_aggregate_verification_key(&self.config.get_validator_api_endpoints())
|
||||
.await
|
||||
.expect("failed to contact validators to obtain their verification keys");
|
||||
|
||||
let nymd_client = self.random_nymd_client();
|
||||
#[cfg(feature = "coconut")]
|
||||
let coconut_verifier =
|
||||
CoconutVerifier::new(self.all_api_clients(), validators_verification_key);
|
||||
let coconut_verifier = CoconutVerifier::new(
|
||||
self.all_api_clients(),
|
||||
nymd_client,
|
||||
validators_verification_key,
|
||||
);
|
||||
|
||||
#[cfg(not(feature = "coconut"))]
|
||||
let erc20_bridge = ERC20Bridge::new(
|
||||
self.config.get_eth_endpoint(),
|
||||
self.config.get_validator_nymd_endpoints(),
|
||||
self.config._get_cosmos_mnemonic(),
|
||||
);
|
||||
let erc20_bridge = ERC20Bridge::new(self.config.get_eth_endpoint(), nymd_client);
|
||||
|
||||
let mix_forwarding_channel = self.start_packet_forwarder();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user