Feature/coconut feature (#805)
* 'Coconut' feature in gateway * Enabled coconut feature in gateway-requests * Native client coconut feature * Ibid for socks5 client * Ibid for wasm client * Coconut feature flag for validator-api * Added coconut feature flag to our CI * build.yml typo * Continue on windows errors * Missing quote * Another typo in build.yml * Reclaiming disk space when building for windows on CI
This commit is contained in:
committed by
GitHub
parent
51dc8c81ed
commit
4e0e081b3e
@@ -2,7 +2,6 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::config::template::config_template;
|
||||
use coconut_interface::{Base58, KeyPair};
|
||||
use config::defaults::{
|
||||
default_api_endpoints, DEFAULT_EPOCH_LENGTH, DEFAULT_FIRST_EPOCH_START,
|
||||
DEFAULT_MIXNET_CONTRACT_ADDRESS,
|
||||
@@ -14,6 +13,9 @@ use std::time::Duration;
|
||||
use time::OffsetDateTime;
|
||||
use url::Url;
|
||||
|
||||
#[cfg(feature = "coconut")]
|
||||
use coconut_interface::{Base58, KeyPair};
|
||||
|
||||
mod template;
|
||||
|
||||
const DEFAULT_LOCAL_VALIDATOR: &str = "http://localhost:26657";
|
||||
@@ -30,7 +32,6 @@ const DEFAULT_CACHE_INTERVAL: Duration = Duration::from_secs(60);
|
||||
const DEFAULT_MONITOR_THRESHOLD: u8 = 60;
|
||||
|
||||
#[derive(Debug, Default, Deserialize, PartialEq, Serialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct Config {
|
||||
#[serde(default)]
|
||||
base: Base,
|
||||
@@ -74,7 +75,7 @@ impl NymConfig for Config {
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, PartialEq, Serialize)]
|
||||
#[serde(deny_unknown_fields, default)]
|
||||
#[serde(default)]
|
||||
pub struct Base {
|
||||
local_validator: Url,
|
||||
|
||||
@@ -82,6 +83,7 @@ pub struct Base {
|
||||
mixnet_contract_address: String,
|
||||
|
||||
// Avoid breaking derives for now
|
||||
#[cfg(feature = "coconut")]
|
||||
keypair_bs58: String,
|
||||
}
|
||||
|
||||
@@ -92,13 +94,14 @@ impl Default for Base {
|
||||
.parse()
|
||||
.expect("default local validator is malformed!"),
|
||||
mixnet_contract_address: DEFAULT_MIXNET_CONTRACT_ADDRESS.to_string(),
|
||||
#[cfg(feature = "coconut")]
|
||||
keypair_bs58: String::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, PartialEq, Serialize)]
|
||||
#[serde(deny_unknown_fields, default)]
|
||||
#[serde(default)]
|
||||
pub struct NetworkMonitor {
|
||||
/// Specifies whether network monitoring service is enabled in this process.
|
||||
enabled: bool,
|
||||
@@ -179,7 +182,7 @@ impl Default for NetworkMonitor {
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, PartialEq, Serialize)]
|
||||
#[serde(deny_unknown_fields, default)]
|
||||
#[serde(default)]
|
||||
pub struct NodeStatusAPI {
|
||||
/// Path to the database file containing uptime statuses for all mixnodes and gateways.
|
||||
database_path: PathBuf,
|
||||
@@ -200,7 +203,7 @@ impl Default for NodeStatusAPI {
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, PartialEq, Serialize)]
|
||||
#[serde(deny_unknown_fields, default)]
|
||||
#[serde(default)]
|
||||
pub struct TopologyCacher {
|
||||
#[serde(with = "humantime_serde")]
|
||||
caching_interval: Duration,
|
||||
@@ -215,7 +218,7 @@ impl Default for TopologyCacher {
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, PartialEq, Serialize)]
|
||||
#[serde(deny_unknown_fields, default)]
|
||||
#[serde(default)]
|
||||
pub struct Rewarding {
|
||||
/// Specifies whether rewarding service is enabled in this process.
|
||||
enabled: bool,
|
||||
@@ -254,6 +257,7 @@ impl Config {
|
||||
Config::default()
|
||||
}
|
||||
|
||||
#[cfg(feature = "coconut")]
|
||||
pub fn keypair(&self) -> KeyPair {
|
||||
KeyPair::try_from_bs58(self.base.keypair_bs58.clone()).unwrap()
|
||||
}
|
||||
@@ -298,6 +302,7 @@ impl Config {
|
||||
self
|
||||
}
|
||||
|
||||
#[cfg(feature = "coconut")]
|
||||
pub fn with_keypair<S: Into<String>>(mut self, keypair_bs58: S) -> Self {
|
||||
self.base.keypair_bs58 = keypair_bs58.into();
|
||||
self
|
||||
@@ -391,6 +396,8 @@ impl Config {
|
||||
self.node_status_api.database_path.clone()
|
||||
}
|
||||
|
||||
// fix dead code warnings as this method is only ever used with coconut feature
|
||||
#[cfg(feature = "coconut")]
|
||||
pub fn get_all_validator_api_endpoints(&self) -> Vec<Url> {
|
||||
self.network_monitor.all_validator_apis.clone()
|
||||
}
|
||||
|
||||
+30
-18
@@ -16,7 +16,6 @@ use ::config::NymConfig;
|
||||
use anyhow::Result;
|
||||
use cache::ValidatorCache;
|
||||
use clap::{App, Arg, ArgMatches};
|
||||
use coconut::InternalSignRequest;
|
||||
use log::{info, warn};
|
||||
use rocket::fairing::AdHoc;
|
||||
use rocket::http::Method;
|
||||
@@ -31,8 +30,10 @@ use tokio::sync::Notify;
|
||||
use url::Url;
|
||||
use validator_client::nymd::SigningNymdClient;
|
||||
|
||||
#[cfg(feature = "coconut")]
|
||||
use coconut::InternalSignRequest;
|
||||
|
||||
pub(crate) mod cache;
|
||||
mod coconut;
|
||||
pub(crate) mod config;
|
||||
mod network_monitor;
|
||||
mod node_status_api;
|
||||
@@ -40,17 +41,22 @@ pub(crate) mod nymd_client;
|
||||
mod rewarding;
|
||||
pub(crate) mod storage;
|
||||
|
||||
#[cfg(feature = "coconut")]
|
||||
mod coconut;
|
||||
|
||||
const MONITORING_ENABLED: &str = "enable-monitor";
|
||||
const REWARDING_ENABLED: &str = "enable-rewarding";
|
||||
const V4_TOPOLOGY_ARG: &str = "v4-topology-filepath";
|
||||
const V6_TOPOLOGY_ARG: &str = "v6-topology-filepath";
|
||||
const API_VALIDATORS_ARG: &str = "api-validators";
|
||||
const DETAILED_REPORT_ARG: &str = "detailed-report";
|
||||
const MIXNET_CONTRACT_ARG: &str = "mixnet-contract";
|
||||
const MNEMONIC_ARG: &str = "mnemonic";
|
||||
const WRITE_CONFIG_ARG: &str = "save-config";
|
||||
const KEYPAIR_ARG: &str = "keypair";
|
||||
const NYMD_VALIDATOR_ARG: &str = "nymd-validator";
|
||||
const API_VALIDATORS_ARG: &str = "api-validators";
|
||||
|
||||
#[cfg(feature = "coconut")]
|
||||
const KEYPAIR_ARG: &str = "keypair";
|
||||
|
||||
const EPOCH_LENGTH_ARG: &str = "epoch-length";
|
||||
const FIRST_REWARDING_EPOCH_ARG: &str = "first-epoch";
|
||||
@@ -70,7 +76,7 @@ fn parse_validators(raw: &str) -> Vec<Url> {
|
||||
}
|
||||
|
||||
fn parse_args<'a>() -> ArgMatches<'a> {
|
||||
App::new("Nym Validator API")
|
||||
let base_app = App::new("Nym Validator API")
|
||||
.author("Nymtech")
|
||||
.arg(
|
||||
Arg::with_name(MONITORING_ENABLED)
|
||||
@@ -104,12 +110,6 @@ fn parse_args<'a>() -> ArgMatches<'a> {
|
||||
.long(NYMD_VALIDATOR_ARG)
|
||||
.takes_value(true)
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(API_VALIDATORS_ARG)
|
||||
.help("specifies list of all validators on the network issuing coconut credentials. Ensure they are properly ordered")
|
||||
.long(API_VALIDATORS_ARG)
|
||||
.takes_value(true)
|
||||
)
|
||||
.arg(Arg::with_name(MIXNET_CONTRACT_ARG)
|
||||
.long(MIXNET_CONTRACT_ARG)
|
||||
.help("Address of the validator contract managing the network")
|
||||
@@ -134,10 +134,10 @@ fn parse_args<'a>() -> ArgMatches<'a> {
|
||||
.short("w")
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(KEYPAIR_ARG)
|
||||
.help("Path to the secret key file")
|
||||
Arg::with_name(API_VALIDATORS_ARG)
|
||||
.help("specifies list of all validators on the network issuing coconut credentials. Ensure they are properly ordered")
|
||||
.long(API_VALIDATORS_ARG)
|
||||
.takes_value(true)
|
||||
.long(KEYPAIR_ARG)
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(FIRST_REWARDING_EPOCH_ARG)
|
||||
@@ -159,9 +159,17 @@ fn parse_args<'a>() -> ArgMatches<'a> {
|
||||
.takes_value(true)
|
||||
.long(REWARDING_MONITOR_THRESHOLD_ARG)
|
||||
.requires(REWARDING_ENABLED)
|
||||
)
|
||||
);
|
||||
|
||||
.get_matches()
|
||||
#[cfg(feature = "coconut")]
|
||||
let base_app = base_app.arg(
|
||||
Arg::with_name(KEYPAIR_ARG)
|
||||
.help("Path to the secret key file")
|
||||
.takes_value(true)
|
||||
.long(KEYPAIR_ARG),
|
||||
);
|
||||
|
||||
base_app.get_matches()
|
||||
}
|
||||
|
||||
async fn wait_for_interrupt() {
|
||||
@@ -264,6 +272,8 @@ fn override_config(mut config: Config, matches: &ArgMatches) -> Config {
|
||||
if matches.is_present(DETAILED_REPORT_ARG) {
|
||||
config = config.with_detailed_network_monitor_report(true)
|
||||
}
|
||||
|
||||
#[cfg(feature = "coconut")]
|
||||
if let Some(keypair_path) = matches.value_of(KEYPAIR_ARG) {
|
||||
let keypair_bs58 = std::fs::read_to_string(keypair_path)
|
||||
.unwrap()
|
||||
@@ -377,8 +387,10 @@ async fn setup_rocket(config: &Config, liftoff_notify: Arc<Notify>) -> Result<Ro
|
||||
let rocket = rocket::build()
|
||||
.attach(setup_cors()?)
|
||||
.attach(setup_liftoff_notify(liftoff_notify))
|
||||
.attach(ValidatorCache::stage())
|
||||
.attach(InternalSignRequest::stage(config.keypair()));
|
||||
.attach(ValidatorCache::stage());
|
||||
|
||||
#[cfg(feature = "coconut")]
|
||||
let rocket = rocket.attach(InternalSignRequest::stage(config.keypair()));
|
||||
|
||||
// see if we should start up network monitor and if so, attach the node status api
|
||||
if config.get_network_monitor_enabled() {
|
||||
|
||||
@@ -15,9 +15,6 @@ use crate::network_monitor::monitor::summary_producer::SummaryProducer;
|
||||
use crate::network_monitor::monitor::Monitor;
|
||||
use crate::network_monitor::tested_network::TestedNetwork;
|
||||
use crate::storage::NodeStatusStorage;
|
||||
use coconut_interface::Credential;
|
||||
use credentials::bandwidth::prepare_for_spending;
|
||||
use credentials::obtain_aggregate_verification_key;
|
||||
use crypto::asymmetric::{encryption, identity};
|
||||
use futures::channel::mpsc;
|
||||
use log::info;
|
||||
@@ -25,6 +22,11 @@ use nymsphinx::addressing::clients::Recipient;
|
||||
use std::sync::Arc;
|
||||
use topology::NymTopology;
|
||||
|
||||
#[cfg(feature = "coconut")]
|
||||
use coconut_interface::Credential;
|
||||
#[cfg(feature = "coconut")]
|
||||
use credentials::{bandwidth::prepare_for_spending, obtain_aggregate_verification_key};
|
||||
|
||||
pub(crate) mod chunker;
|
||||
pub(crate) mod gateways_reader;
|
||||
pub(crate) mod monitor;
|
||||
@@ -90,6 +92,7 @@ impl<'a> NetworkMonitorBuilder<'a> {
|
||||
*encryption_keypair.public_key(),
|
||||
);
|
||||
|
||||
#[cfg(feature = "coconut")]
|
||||
let bandwidth_credential =
|
||||
TEMPORARY_obtain_bandwidth_credential(self.config, identity_keypair.public_key()).await;
|
||||
|
||||
@@ -97,8 +100,9 @@ impl<'a> NetworkMonitorBuilder<'a> {
|
||||
self.config,
|
||||
gateway_status_update_sender,
|
||||
Arc::clone(&identity_keypair),
|
||||
bandwidth_credential,
|
||||
self.config.get_gateway_sending_rate(),
|
||||
#[cfg(feature = "coconut")]
|
||||
bandwidth_credential,
|
||||
);
|
||||
|
||||
let received_processor = new_received_processor(
|
||||
@@ -163,6 +167,7 @@ fn new_packet_preparer(
|
||||
|
||||
// SECURITY:
|
||||
// this implies we are re-using the same credential for all gateways all the time (which unfortunately is true!)
|
||||
#[cfg(feature = "coconut")]
|
||||
#[allow(non_snake_case)]
|
||||
async fn TEMPORARY_obtain_bandwidth_credential(
|
||||
config: &Config,
|
||||
@@ -192,17 +197,18 @@ fn new_packet_sender(
|
||||
config: &Config,
|
||||
gateways_status_updater: GatewayClientUpdateSender,
|
||||
local_identity: Arc<identity::KeyPair>,
|
||||
bandwidth_credential: Credential,
|
||||
max_sending_rate: usize,
|
||||
#[cfg(feature = "coconut")] bandwidth_credential: Credential,
|
||||
) -> PacketSender {
|
||||
PacketSender::new(
|
||||
gateways_status_updater,
|
||||
local_identity,
|
||||
bandwidth_credential,
|
||||
config.get_gateway_response_timeout(),
|
||||
config.get_gateway_connection_timeout(),
|
||||
config.get_max_concurrent_gateway_clients(),
|
||||
max_sending_rate,
|
||||
#[cfg(feature = "coconut")]
|
||||
bandwidth_credential,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::network_monitor::monitor::receiver::{GatewayClientUpdate, GatewayClientUpdateSender};
|
||||
use coconut_interface::Credential;
|
||||
use crypto::asymmetric::identity::{self, PUBLIC_KEY_LENGTH};
|
||||
use futures::channel::mpsc;
|
||||
use futures::stream::{self, FuturesUnordered, StreamExt};
|
||||
@@ -22,6 +21,9 @@ use std::task::Poll;
|
||||
use std::time::Duration;
|
||||
use tokio::time::Instant;
|
||||
|
||||
#[cfg(feature = "coconut")]
|
||||
use coconut_interface::Credential;
|
||||
|
||||
const TIME_CHUNK_SIZE: Duration = Duration::from_millis(50);
|
||||
|
||||
pub(crate) struct GatewayPackets {
|
||||
@@ -71,7 +73,8 @@ struct FreshGatewayClientData {
|
||||
// SECURITY:
|
||||
// since currently we have no double spending protection, just to get things running
|
||||
// we're re-using the same credential for all gateways all the time. THIS IS VERY BAD!!
|
||||
bandwidth_credential: Credential,
|
||||
#[cfg(feature = "coconut")]
|
||||
coconut_bandwidth_credential: Credential,
|
||||
}
|
||||
|
||||
pub(crate) struct PacketSender {
|
||||
@@ -93,11 +96,11 @@ impl PacketSender {
|
||||
pub(crate) fn new(
|
||||
gateways_status_updater: GatewayClientUpdateSender,
|
||||
local_identity: Arc<identity::KeyPair>,
|
||||
bandwidth_credential: Credential,
|
||||
gateway_response_timeout: Duration,
|
||||
gateway_connection_timeout: Duration,
|
||||
max_concurrent_clients: usize,
|
||||
max_sending_rate: usize,
|
||||
#[cfg(feature = "coconut")] coconut_bandwidth_credential: Credential,
|
||||
) -> Self {
|
||||
PacketSender {
|
||||
active_gateway_clients: HashMap::new(),
|
||||
@@ -105,7 +108,8 @@ impl PacketSender {
|
||||
gateways_status_updater,
|
||||
local_identity,
|
||||
gateway_response_timeout,
|
||||
bandwidth_credential,
|
||||
#[cfg(feature = "coconut")]
|
||||
coconut_bandwidth_credential,
|
||||
}),
|
||||
gateway_connection_timeout,
|
||||
max_concurrent_clients,
|
||||
@@ -137,7 +141,6 @@ impl PacketSender {
|
||||
message_sender,
|
||||
ack_sender,
|
||||
fresh_gateway_client_data.gateway_response_timeout,
|
||||
fresh_gateway_client_data.bandwidth_credential.clone(),
|
||||
),
|
||||
(message_receiver, ack_receiver),
|
||||
)
|
||||
@@ -230,7 +233,14 @@ impl PacketSender {
|
||||
// (an actual bug we experienced)
|
||||
match tokio::time::timeout(
|
||||
gateway_connection_timeout,
|
||||
new_client.authenticate_and_start(),
|
||||
new_client.authenticate_and_start(
|
||||
#[cfg(feature = "coconut")]
|
||||
Some(
|
||||
fresh_gateway_client_data
|
||||
.coconut_bandwidth_credential
|
||||
.clone(),
|
||||
),
|
||||
),
|
||||
)
|
||||
.await
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user