validator: WIP on merge conflicts

This commit is contained in:
Dave Hrycyszyn
2020-01-30 11:25:00 +00:00
21 changed files with 206 additions and 192 deletions
+38 -7
View File
@@ -1,8 +1,38 @@
# Changelog
## [Unreleased](https://github.com/nymtech/nym/tree/HEAD)
## [v0.4.1](https://github.com/nymtech/nym/tree/v0.4.1) (2020-01-29)
[Full Changelog](https://github.com/nymtech/nym/compare/v0.3.3...HEAD)
[Full Changelog](https://github.com/nymtech/nym/compare/v0.4.0...v0.4.1)
**Closed issues:**
- Change healthcheck to run on provided topology rather than pull one itself [\#95](https://github.com/nymtech/nym/issues/95)
**Merged pull requests:**
- Bugfix/healthcheck on provided topology [\#108](https://github.com/nymtech/nym/pull/108) ([jstuczyn](https://github.com/jstuczyn))
## [v0.4.0](https://github.com/nymtech/nym/tree/v0.4.0) (2020-01-28)
[Full Changelog](https://github.com/nymtech/nym/compare/v0.4.0-rc.2...v0.4.0)
Nym 0.4.0 Platform
In this release, we're taking a lot more care with version numbers, so that we can ensure upgrade compatibility for mixnodes, providers, clients, and validators more easily.
This release also integrates a health-checker and network topology refresh into the Nym client, so that the client can intelligently choose paths which route around any non-functional or incompatible nodes.
## [v0.4.0-rc.2](https://github.com/nymtech/nym/tree/v0.4.0-rc.2) (2020-01-28)
[Full Changelog](https://github.com/nymtech/nym/compare/v0.4.0-rc.1...v0.4.0-rc.2)
**Merged pull requests:**
- Hotfix/semver compatibility [\#106](https://github.com/nymtech/nym/pull/106) ([jstuczyn](https://github.com/jstuczyn))
## [v0.4.0-rc.1](https://github.com/nymtech/nym/tree/v0.4.0-rc.1) (2020-01-28)
[Full Changelog](https://github.com/nymtech/nym/compare/v0.3.3...v0.4.0-rc.1)
**Closed issues:**
@@ -64,10 +94,6 @@
[Full Changelog](https://github.com/nymtech/nym/compare/v0.3.1...v0.3.2)
**Merged pull requests:**
- Feature/separate presence address [\#59](https://github.com/nymtech/nym/pull/59) ([jstuczyn](https://github.com/jstuczyn))
## [v0.3.1](https://github.com/nymtech/nym/tree/v0.3.1) (2020-01-16)
[Full Changelog](https://github.com/nymtech/nym/compare/v0.3.0...v0.3.1)
@@ -94,6 +120,7 @@
**Merged pull requests:**
- Feature/separate presence address [\#59](https://github.com/nymtech/nym/pull/59) ([jstuczyn](https://github.com/jstuczyn))
- Feature/client topology filtering [\#54](https://github.com/nymtech/nym/pull/54) ([jstuczyn](https://github.com/jstuczyn))
- print public key for nym client tools [\#53](https://github.com/nymtech/nym/pull/53) ([mileschet](https://github.com/mileschet))
- Showing binding warning on binding to localhost, 0.0.0.0 or 127.0.0.1 [\#52](https://github.com/nymtech/nym/pull/52) ([jstuczyn](https://github.com/jstuczyn))
@@ -114,7 +141,11 @@
## [v0.2.0](https://github.com/nymtech/nym/tree/v0.2.0) (2020-01-07)
[Full Changelog](https://github.com/nymtech/nym/compare/3c64a2facd753f4f2f431e7f888e54842e2bc64e...v0.2.0)
[Full Changelog](https://github.com/nymtech/nym/compare/0.2.0...v0.2.0)
## [0.2.0](https://github.com/nymtech/nym/tree/0.2.0) (2020-01-06)
[Full Changelog](https://github.com/nymtech/nym/compare/0.1.0...0.2.0)
Generated
+6 -4
View File
@@ -1379,7 +1379,7 @@ dependencies = [
[[package]]
name = "nym-client"
version = "0.4.0-rc.1"
version = "0.4.1"
dependencies = [
"addressing",
"bs58",
@@ -1411,7 +1411,7 @@ dependencies = [
[[package]]
name = "nym-mixnode"
version = "0.4.0-rc.1"
version = "0.4.1"
dependencies = [
"addressing",
"bs58",
@@ -1429,7 +1429,7 @@ dependencies = [
[[package]]
name = "nym-sfw-provider"
version = "0.4.0-rc.1"
version = "0.4.1"
dependencies = [
"bs58",
"built",
@@ -1453,13 +1453,14 @@ dependencies = [
[[package]]
name = "nym-validator"
version = "0.4.0-rc.1"
version = "0.4.1"
dependencies = [
"abci",
"built",
"byteorder",
"clap",
"crypto",
"directory-client",
"dotenv",
"futures 0.3.1",
"healthcheck",
@@ -1469,6 +1470,7 @@ dependencies = [
"serde_derive",
"tokio 0.2.10",
"toml",
"topology",
]
[[package]]
+10 -10
View File
@@ -6,14 +6,13 @@ use bs58;
use curve25519_dalek::scalar::Scalar;
use sphinx::route::DestinationAddressBytes;
pub trait MixnetIdentityKeyPair<Priv, Pub>: Clone
where
Priv: MixnetIdentityPrivateKey,
Pub: MixnetIdentityPublicKey,
{
pub trait MixnetIdentityKeyPair: Clone {
type PublicKeyMaterial: MixnetIdentityPublicKey;
type PrivateKeyMaterial: MixnetIdentityPrivateKey;
fn new() -> Self;
fn private_key(&self) -> &Priv;
fn public_key(&self) -> &Pub;
fn private_key(&self) -> &Self::PrivateKeyMaterial;
fn public_key(&self) -> &Self::PublicKeyMaterial;
fn from_bytes(priv_bytes: &[u8], pub_bytes: &[u8]) -> Self;
// TODO: signing related methods
@@ -56,9 +55,10 @@ pub struct DummyMixIdentityKeyPair {
pub public_key: DummyMixIdentityPublicKey,
}
impl MixnetIdentityKeyPair<DummyMixIdentityPrivateKey, DummyMixIdentityPublicKey>
for DummyMixIdentityKeyPair
{
impl MixnetIdentityKeyPair for DummyMixIdentityKeyPair {
type PublicKeyMaterial = DummyMixIdentityPublicKey;
type PrivateKeyMaterial = DummyMixIdentityPrivateKey;
fn new() -> Self {
let keypair = encryption::x25519::KeyPair::new();
DummyMixIdentityKeyPair {
+16 -62
View File
@@ -1,12 +1,9 @@
use crate::result::HealthCheckResult;
use crypto::identity::{MixnetIdentityKeyPair, MixnetIdentityPrivateKey, MixnetIdentityPublicKey};
use directory_client::requests::presence_topology_get::PresenceTopologyGetRequester;
use directory_client::DirectoryClient;
use log::{debug, error, info, trace};
use crypto::identity::MixnetIdentityKeyPair;
use log::trace;
use std::fmt::{Error, Formatter};
use std::marker::PhantomData;
use std::time::Duration;
use topology::NymTopologyError;
use topology::{NymTopology, NymTopologyError};
pub mod config;
mod path_check;
@@ -36,58 +33,31 @@ impl From<topology::NymTopologyError> for HealthCheckerError {
}
}
pub struct HealthChecker<IDPair, Priv, Pub>
where
IDPair: MixnetIdentityKeyPair<Priv, Pub>,
Priv: MixnetIdentityPrivateKey,
Pub: MixnetIdentityPublicKey,
{
directory_client: directory_client::Client,
interval: Duration,
pub struct HealthChecker<IDPair: MixnetIdentityKeyPair> {
num_test_packets: usize,
resolution_timeout: Duration,
identity_keypair: IDPair,
_phantom_private: PhantomData<Priv>,
_phantom_public: PhantomData<Pub>,
}
impl<IDPair, Priv, Pub> HealthChecker<IDPair, Priv, Pub>
where
IDPair: crypto::identity::MixnetIdentityKeyPair<Priv, Pub>,
Priv: crypto::identity::MixnetIdentityPrivateKey,
Pub: crypto::identity::MixnetIdentityPublicKey,
{
pub fn new(config: config::HealthCheck, identity_keypair: IDPair) -> Self {
debug!(
"healthcheck will be using the following directory server: {:?}",
config.directory_server
);
let directory_client_config = directory_client::Config::new(config.directory_server);
impl<IDPair: MixnetIdentityKeyPair> HealthChecker<IDPair> {
pub fn new(
resolution_timeout_f64: f64,
num_test_packets: usize,
identity_keypair: IDPair,
) -> Self {
HealthChecker {
directory_client: directory_client::Client::new(directory_client_config),
interval: Duration::from_secs_f64(config.interval),
resolution_timeout: Duration::from_secs_f64(config.resolution_timeout),
num_test_packets: config.num_test_packets,
resolution_timeout: Duration::from_secs_f64(resolution_timeout_f64),
num_test_packets,
identity_keypair,
_phantom_private: PhantomData,
_phantom_public: PhantomData,
}
}
pub async fn do_check(&self) -> Result<HealthCheckResult, HealthCheckerError> {
pub async fn do_check<T: NymTopology>(
&self,
current_topology: &T,
) -> Result<HealthCheckResult, HealthCheckerError> {
trace!("going to perform a healthcheck!");
let current_topology = match self.directory_client.presence_topology.get() {
Ok(topology) => topology,
Err(err) => {
error!("failed to obtain topology - {:?}", err);
return Err(HealthCheckerError::FailedToObtainTopologyError);
}
};
trace!("current topology: {:?}", current_topology);
let mut healthcheck_result = HealthCheckResult::calculate(
current_topology,
self.num_test_packets,
@@ -98,20 +68,4 @@ where
healthcheck_result.sort_scores();
Ok(healthcheck_result)
}
pub async fn run(self) -> Result<(), HealthCheckerError> {
debug!(
"healthcheck will run every {:?} and will send {} packets to each node",
self.interval, self.num_test_packets
);
loop {
match self.do_check().await {
Ok(health) => info!("current network health: \n{}", health),
Err(err) => error!("failed to perform healthcheck - {:?}", err),
};
tokio::time::delay_for(self.interval).await;
}
}
}
+3 -8
View File
@@ -1,4 +1,4 @@
use crypto::identity::{MixnetIdentityKeyPair, MixnetIdentityPrivateKey, MixnetIdentityPublicKey};
use crypto::identity::{MixnetIdentityKeyPair, MixnetIdentityPublicKey};
use itertools::Itertools;
use log::{debug, error, info, trace, warn};
use mix_client::MixClient;
@@ -27,16 +27,11 @@ pub(crate) struct PathChecker {
}
impl PathChecker {
pub(crate) async fn new<IDPair, Priv, Pub>(
pub(crate) async fn new<IDPair: MixnetIdentityKeyPair>(
providers: Vec<provider::Node>,
identity_keys: &IDPair,
check_id: [u8; 16],
) -> Self
where
IDPair: MixnetIdentityKeyPair<Priv, Pub>,
Priv: MixnetIdentityPrivateKey,
Pub: MixnetIdentityPublicKey,
{
) -> Self {
let mut provider_clients = HashMap::new();
let address = identity_keys.public_key().derive_address();
+5 -7
View File
@@ -1,6 +1,6 @@
use crate::path_check::{PathChecker, PathStatus};
use crate::score::NodeScore;
use crypto::identity::{MixnetIdentityKeyPair, MixnetIdentityPrivateKey, MixnetIdentityPublicKey};
use crypto::identity::MixnetIdentityKeyPair;
use log::{debug, error, info, warn};
use rand_os::rand_core::RngCore;
use sphinx::route::NodeAddressBytes;
@@ -27,7 +27,7 @@ impl HealthCheckResult {
self.0.sort();
}
fn zero_score<T: NymTopology>(topology: T) -> Self {
fn zero_score<T: NymTopology>(topology: &T) -> Self {
warn!("The network is unhealthy, could not send any packets - returning zero score!");
let mixes = topology.mix_nodes();
let providers = topology.providers();
@@ -102,17 +102,15 @@ impl HealthCheckResult {
id
}
pub async fn calculate<T, IDPair, Priv, Pub>(
topology: T,
pub async fn calculate<T, IDPair>(
topology: &T,
iterations: usize,
resolution_timeout: Duration,
identity_keys: &IDPair,
) -> Self
where
T: NymTopology,
IDPair: MixnetIdentityKeyPair<Priv, Pub>,
Priv: MixnetIdentityPrivateKey,
Pub: MixnetIdentityPublicKey,
IDPair: MixnetIdentityKeyPair,
{
// currently healthchecker supports only up to 255 iterations - if we somehow
// find we need more, it's relatively easy change
+7 -12
View File
@@ -1,4 +1,6 @@
use crate::pathfinder::PathFinder;
use crypto::identity::{MixnetIdentityKeyPair, MixnetIdentityPrivateKey, MixnetIdentityPublicKey};
use crypto::PemStorable;
use pem::{encode, parse, Pem};
use std::fs::File;
use std::io;
@@ -25,12 +27,7 @@ impl PemStore {
}
}
pub fn read_identity<IDPair, Priv, Pub>(&self) -> io::Result<IDPair>
where
IDPair: crypto::identity::MixnetIdentityKeyPair<Priv, Pub>,
Priv: crypto::identity::MixnetIdentityPrivateKey,
Pub: crypto::identity::MixnetIdentityPublicKey,
{
pub fn read_identity<IDPair: MixnetIdentityKeyPair>(&self) -> io::Result<IDPair> {
let private_pem = self.read_pem_file(self.private_mix_key.clone())?;
let public_pem = self.read_pem_file(self.public_mix_key.clone())?;
@@ -62,12 +59,10 @@ impl PemStore {
// This should be refactored and made more generic for when we have other kinds of
// KeyPairs that we want to persist (e.g. validator keypairs, or keys for
// signing vs encryption). However, for the moment, it does the job.
pub fn write_identity<IDPair, Priv, Pub>(&self, key_pair: IDPair) -> io::Result<()>
where
IDPair: crypto::identity::MixnetIdentityKeyPair<Priv, Pub>,
Priv: crypto::identity::MixnetIdentityPrivateKey,
Pub: crypto::identity::MixnetIdentityPublicKey,
{
pub fn write_identity<IDPair: MixnetIdentityKeyPair>(
&self,
key_pair: IDPair,
) -> io::Result<()> {
std::fs::create_dir_all(self.config_dir.clone())?;
let private_key = key_pair.private_key();
+8 -6
View File
@@ -1,5 +1,4 @@
use semver::Version;
use semver::VersionReq;
/// Checks whether given `version` is compatible with a given semantic version requirement `req`
/// according to major-minor semver rules. The semantic version requirement can be passed as a full,
@@ -7,18 +6,16 @@ use semver::VersionReq;
/// The patch number in the requirement gets dropped and replaced with a wildcard (0.3.*) as all
/// minor versions should be compatible with each other.
pub fn is_minor_version_compatible(version: &str, req: &str) -> bool {
let version = match Version::parse(version) {
let expected_version = match Version::parse(version) {
Ok(v) => v,
Err(_) => return false,
};
let tmp = match Version::parse(req) {
let req_version = match Version::parse(req) {
Ok(v) => v,
Err(_) => return false,
};
let wildcard = format!("{}.{}.*", tmp.major, tmp.minor).to_string();
let semver_requirement = VersionReq::parse(&wildcard).expect("panicked on semver requirement parsing. This should never happen as inputs should already have been sanitized.");
semver_requirement.matches(&version)
expected_version.major == req_version.major && expected_version.minor == req_version.minor
}
#[cfg(test)]
@@ -55,6 +52,11 @@ mod tests {
assert!(!is_minor_version_compatible("1.3.2", "0.3.2"));
}
#[test]
fn version_0_4_0_rc_1_is_compatible_with_version_0_4_0_rc_1() {
assert!(is_minor_version_compatible("0.4.0-rc.1", "0.4.0-rc.1"));
}
#[test]
fn returns_false_on_foo_version() {
assert!(!is_minor_version_compatible("foo", "0.3.2"));
+1 -1
View File
@@ -1,7 +1,7 @@
[package]
build = "build.rs"
name = "nym-mixnode"
version = "0.4.0-rc.1"
version = "0.4.1"
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>", "Jędrzej Stuczyński <andrew@nymtech.net>"]
edition = "2018"
+1 -1
View File
@@ -1,7 +1,7 @@
[package]
build = "build.rs"
name = "nym-client"
version = "0.4.0-rc.1"
version = "0.4.1"
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>", "Jędrzej Stuczyński <andrew@nymtech.net>"]
edition = "2018"
+6 -16
View File
@@ -3,14 +3,13 @@ use crate::client::received_buffer::ReceivedMessagesBuffer;
use crate::client::topology_control::TopologyInnerRef;
use crate::sockets::tcp;
use crate::sockets::ws;
use crypto::identity::{MixnetIdentityKeyPair, MixnetIdentityPrivateKey, MixnetIdentityPublicKey};
use crypto::identity::{MixnetIdentityKeyPair, MixnetIdentityPublicKey};
use directory_client::presence::Topology;
use futures::channel::mpsc;
use futures::join;
use log::*;
use sfw_provider_requests::AuthToken;
use sphinx::route::Destination;
use std::marker::PhantomData;
use std::net::SocketAddr;
use tokio::runtime::Runtime;
use topology::NymTopology;
@@ -37,11 +36,9 @@ pub enum SocketType {
None,
}
pub struct NymClient<IDPair, Priv, Pub>
pub struct NymClient<IDPair>
where
IDPair: MixnetIdentityKeyPair<Priv, Pub> + Send + Sync,
Priv: MixnetIdentityPrivateKey + Send + Sync,
Pub: MixnetIdentityPublicKey + Send + Sync,
IDPair: MixnetIdentityKeyPair + Send + Sync,
{
keypair: IDPair,
@@ -53,19 +50,14 @@ where
directory: String,
auth_token: Option<AuthToken>,
socket_type: SocketType,
_phantom_private: PhantomData<Priv>,
_phantom_public: PhantomData<Pub>,
}
#[derive(Debug)]
pub struct InputMessage(pub Destination, pub Vec<u8>);
impl<IDPair: 'static, Priv: 'static, Pub: 'static> NymClient<IDPair, Priv, Pub>
impl<IDPair> NymClient<IDPair>
where
IDPair: MixnetIdentityKeyPair<Priv, Pub> + Send + Sync,
Priv: MixnetIdentityPrivateKey + Send + Sync,
Pub: MixnetIdentityPublicKey + Send + Sync,
IDPair: 'static + MixnetIdentityKeyPair + Send + Sync,
{
pub fn new(
keypair: IDPair,
@@ -84,8 +76,6 @@ where
directory,
auth_token,
socket_type,
_phantom_private: PhantomData,
_phantom_public: PhantomData,
}
}
@@ -129,7 +119,7 @@ where
// TODO: when we switch to our graph topology, we need to remember to change 'Topology' type
let topology_controller =
rt.block_on(topology_control::TopologyControl::<Topology, _, _, _>::new(
rt.block_on(topology_control::TopologyControl::<Topology, _>::new(
self.directory.clone(),
TOPOLOGY_REFRESH_RATE,
healthcheck_keys,
+20 -31
View File
@@ -1,5 +1,5 @@
use crate::built_info;
use crypto::identity::{MixnetIdentityKeyPair, MixnetIdentityPrivateKey, MixnetIdentityPublicKey};
use crypto::identity::MixnetIdentityKeyPair;
use healthcheck::HealthChecker;
use log::{error, info, trace, warn};
use std::sync::Arc;
@@ -12,16 +12,14 @@ const NODE_HEALTH_THRESHOLD: f64 = 0.0;
// auxiliary type for ease of use
pub type TopologyInnerRef<T> = Arc<FRwLock<Inner<T>>>;
pub(crate) struct TopologyControl<T, IDPair, Priv, Pub>
pub(crate) struct TopologyControl<T, IDPair>
where
T: NymTopology,
IDPair: MixnetIdentityKeyPair<Priv, Pub>,
Priv: MixnetIdentityPrivateKey,
Pub: MixnetIdentityPublicKey,
IDPair: MixnetIdentityKeyPair,
{
directory_server: String,
inner: Arc<FRwLock<Inner<T>>>,
health_checker: HealthChecker<IDPair, Priv, Pub>,
health_checker: HealthChecker<IDPair>,
refresh_rate: f64,
}
@@ -31,29 +29,18 @@ enum TopologyError {
NoValidPathsError,
}
impl<T, IDPair, Priv, Pub> TopologyControl<T, IDPair, Priv, Pub>
impl<T, IDPair> TopologyControl<T, IDPair>
where
T: NymTopology,
IDPair: MixnetIdentityKeyPair<Priv, Pub>,
Priv: MixnetIdentityPrivateKey,
Pub: MixnetIdentityPublicKey,
IDPair: MixnetIdentityKeyPair,
{
pub(crate) async fn new(
directory_server: String,
refresh_rate: f64,
identity_keypair: IDPair,
) -> Self {
// topology control run a healthcheck to determine healthy-ish nodes:
// this is a temporary solution as the healthcheck will eventually be moved to validators
let healthcheck_config = healthcheck::config::HealthCheck {
directory_server: directory_server.clone(),
// those are literally irrelevant when running single check
interval: 100000.0,
resolution_timeout: 5.0,
num_test_packets: 2,
};
let health_checker = healthcheck::HealthChecker::new(healthcheck_config, identity_keypair);
let health_checker = healthcheck::HealthChecker::new(5.0, 2, identity_keypair);
let mut topology_control = TopologyControl {
directory_server,
@@ -79,8 +66,16 @@ where
async fn get_current_compatible_topology(&self) -> Result<T, TopologyError> {
let full_topology = T::new(self.directory_server.clone());
let version_filtered_topology = full_topology.filter_node_versions(
built_info::PKG_VERSION,
built_info::PKG_VERSION,
built_info::PKG_VERSION,
);
let healthcheck_result = self.health_checker.do_check().await;
let healthcheck_result = self
.health_checker
.do_check(&version_filtered_topology)
.await;
let healthcheck_scores = match healthcheck_result {
Err(err) => {
error!("Error while performing the healthcheck: {:?}", err);
@@ -89,21 +84,15 @@ where
Ok(scores) => scores,
};
let healthy_topology =
healthcheck_scores.filter_topology_by_score(&full_topology, NODE_HEALTH_THRESHOLD);
let versioned_healthy_topology = healthy_topology.filter_node_versions(
built_info::PKG_VERSION,
built_info::PKG_VERSION,
built_info::PKG_VERSION,
);
let healthy_topology = healthcheck_scores
.filter_topology_by_score(&version_filtered_topology, NODE_HEALTH_THRESHOLD);
// make sure you can still send a packet through the network:
if !versioned_healthy_topology.can_construct_path_through() {
if !healthy_topology.can_construct_path_through() {
return Err(TopologyError::NoValidPathsError);
}
Ok(versioned_healthy_topology)
Ok(healthy_topology)
}
pub(crate) fn get_inner_ref(&self) -> Arc<FRwLock<Inner<T>>> {
+3
View File
@@ -0,0 +1,3 @@
#!/bin/bash
# set CHANGELOG_GITHUB_TOKEN in your .bashrc file
github_changelog_generator -u nymtech -p nym --exclude-tags 0.1.0 --token "$CHANGELOG_GITHUB_TOKEN"
+1 -1
View File
@@ -1,7 +1,7 @@
[package]
build = "build.rs"
name = "nym-sfw-provider"
version = "0.4.0-rc.1"
version = "0.4.1"
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>", "Jędrzej Stuczyński <andrew@nymtech.net>"]
edition = "2018"
+3 -1
View File
@@ -1,7 +1,7 @@
[package]
build = "build.rs"
name = "nym-validator"
version = "0.4.0-rc.1"
version = "0.4.1"
authors = ["Jedrzej Stuczynski <andrew@nymtech.net>"]
edition = "2018"
@@ -23,7 +23,9 @@ toml = "0.5.5"
## internal
crypto = {path = "../common/crypto"}
directory-client = { path = "../common/clients/directory-client" }
healthcheck = {path = "../common/healthcheck" }
topology = {path = "../common/topology"}
[build-dependencies]
built = "0.3.2"
+1
View File
@@ -6,6 +6,7 @@ use std::process;
use toml;
mod network;
mod services;
mod validator;
fn main() {
+2 -2
View File
@@ -21,8 +21,8 @@ impl Abci {
Abci { count: 0 }
}
pub async fn run(self) {
abci::run_local(self);
pub fn run(self) {
tokio::spawn(async { abci::run_local(self) })
}
}
@@ -0,0 +1,50 @@
use crypto::identity::MixnetIdentityKeyPair;
use healthcheck::HealthChecker;
use log::*;
use std::time::Duration;
use topology::NymTopology;
pub struct HealthCheckRunner<T: MixnetIdentityKeyPair> {
directory_server: String,
health_checker: HealthChecker<T>,
interval: f64,
}
impl<T: MixnetIdentityKeyPair + Send + Sync + 'static> HealthCheckRunner<T> {
pub fn new(
directory_server: String,
interval: f64,
health_checker: HealthChecker<T>,
) -> HealthCheckRunner<T> {
HealthCheckRunner {
directory_server,
health_checker,
interval,
}
}
pub async fn run(self) {
tokio::spawn(async move {
let healthcheck_interval = Duration::from_secs_f64(self.interval);
debug!("healthcheck will run every {:?}", healthcheck_interval);
loop {
let full_topology =
directory_client::presence::Topology::new(self.directory_server.clone());
let version_filtered_topology = full_topology.filter_node_versions(
crate::built_info::PKG_VERSION,
crate::built_info::PKG_VERSION,
crate::built_info::PKG_VERSION,
);
match self
.health_checker
.do_check(&version_filtered_topology)
.await
{
Ok(health) => info!("current network health: \n{}", health),
Err(err) => error!("failed to perform healthcheck - {:?}", err),
};
tokio::time::delay_for(healthcheck_interval).await;
}
});
}
}
+1
View File
@@ -0,0 +1 @@
pub mod health_check_runner;
+1
View File
@@ -0,0 +1 @@
pub mod mixmining;
+23 -23
View File
@@ -1,8 +1,6 @@
use crate::network::tendermint;
use crypto::identity::{
DummyMixIdentityKeyPair, DummyMixIdentityPrivateKey, DummyMixIdentityPublicKey,
MixnetIdentityKeyPair, MixnetIdentityPrivateKey, MixnetIdentityPublicKey,
};
use crate::services::mixmining::health_check_runner;
use crypto::identity::{DummyMixIdentityKeyPair, MixnetIdentityKeyPair};
use healthcheck::HealthChecker;
use tokio::runtime::Runtime;
@@ -15,39 +13,41 @@ pub struct Config {
}
// allow for a generic validator
pub struct Validator<IDPair, Priv, Pub>
where
IDPair: MixnetIdentityKeyPair<Priv, Pub>,
Priv: MixnetIdentityPrivateKey,
Pub: MixnetIdentityPublicKey,
{
tendermint_abci: tendermint::Abci,
health_check: HealthChecker<IDPair, Priv, Pub>,
pub struct Validator<IDPair: MixnetIdentityKeyPair> {
config: Config,
#[allow(dead_code)]
identity_keypair: IDPair,
health_check_runner: health_check_runner::HealthCheckRunner<IDPair>,
tendermint_abci: tendermint::Abci,
}
// but for time being, since it's a dummy one, have it use dummy keys
impl Validator<DummyMixIdentityKeyPair, DummyMixIdentityPrivateKey, DummyMixIdentityPublicKey> {
impl Validator<DummyMixIdentityKeyPair> {
pub fn new(config: Config) -> Self {
let dummy_keypair = DummyMixIdentityKeyPair::new();
let hc = HealthChecker::new(
config.health_check.resolution_timeout,
config.health_check.num_test_packets,
dummy_keypair.clone(),
);
let health_check_runner = health_check_runner::HealthCheckRunner::new(
config.health_check.directory_server.clone(),
config.health_check.interval,
hc,
);
Validator {
tendermint_abci: tendermint::Abci::new(),
health_check: HealthChecker::new(config.health_check, dummy_keypair.clone()),
identity_keypair: dummy_keypair,
health_check_runner,
config,
tendermint_abci: tendermint::Abci::new(),
}
}
pub fn start(self) {
let mut rt = Runtime::new().unwrap();
let abci_future = self.tendermint_abci.run();
let health_check_future = self.health_check.run();
rt.spawn(abci_future);
let health_check_res = rt.block_on(health_check_future);
assert!(health_check_res.is_ok()); // panic if health checker failed
rt.spawn(self.health_check_runner.run());
rt.block_on(self.tendermint_abci.run());
}
}