Merge branch 'develop' into feature/config_files

This commit is contained in:
Jedrzej Stuczynski
2020-01-30 12:50:35 +00:00
32 changed files with 470 additions and 444 deletions
+1
View File
@@ -6,3 +6,4 @@
target
.env
/.vscode/settings.json
sample-configs/validator-config.toml
Generated
+76 -1
View File
@@ -1,5 +1,22 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "abci"
version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1cfb90d266d6ca61cea4d155dd5033c9516495f4f74f82faf1ca5c4feeb82577"
dependencies = [
"byteorder",
"bytes 0.4.12",
"env_logger 0.7.1",
"futures 0.3.1",
"integer-encoding",
"log",
"protobuf",
"protobuf-codegen-pure",
"tokio 0.1.22",
]
[[package]]
name = "addressing"
version = "0.1.0"
@@ -606,6 +623,19 @@ dependencies = [
"termcolor",
]
[[package]]
name = "env_logger"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36"
dependencies = [
"atty",
"humantime",
"log",
"regex",
"termcolor",
]
[[package]]
name = "error-chain"
version = "0.12.1"
@@ -1043,6 +1073,12 @@ dependencies = [
"bytes 0.4.12",
]
[[package]]
name = "integer-encoding"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1aec89c15e2cfa0f0eae8ca60e03cb10b30d25ea2c0ad7d6be60a95e32729994"
[[package]]
name = "iovec"
version = "0.1.4"
@@ -1449,7 +1485,9 @@ dependencies = [
name = "nym-validator"
version = "0.4.1"
dependencies = [
"abci",
"built",
"byteorder",
"clap",
"crypto",
"directory-client",
@@ -1656,7 +1694,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "717ee476b1690853d222af4634056d830b5197ffd747726a9a1eee6da9f49074"
dependencies = [
"chrono",
"env_logger",
"env_logger 0.6.2",
"log",
]
@@ -1686,6 +1724,31 @@ dependencies = [
"unicode-xid",
]
[[package]]
name = "protobuf"
version = "2.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6563a657a014b771e7f69f06447d88d8fbb5a215ffc4cab724afb3acedcc7701"
[[package]]
name = "protobuf-codegen"
version = "2.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f1bbc6db30d5d3e730b6e2326e9a64a75ca9c80d6427d6f054dc8cacc79d225"
dependencies = [
"protobuf",
]
[[package]]
name = "protobuf-codegen-pure"
version = "2.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db5473ffa23d2ea3b9046764f1a22149791967aad946b6cbd99601e720afc4d0"
dependencies = [
"protobuf",
"protobuf-codegen",
]
[[package]]
name = "provider-client"
version = "0.1.0"
@@ -2314,6 +2377,7 @@ dependencies = [
"futures 0.1.29",
"mio",
"num_cpus",
"tokio-codec",
"tokio-current-thread",
"tokio-executor",
"tokio-io",
@@ -2358,6 +2422,17 @@ dependencies = [
"futures 0.1.29",
]
[[package]]
name = "tokio-codec"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c501eceaf96f0e1793cf26beb63da3d11c738c4a943fdf3746d81d64684c39f"
dependencies = [
"bytes 0.4.12",
"futures 0.1.29",
"tokio-io",
]
[[package]]
name = "tokio-current-thread"
version = "0.1.6"
+82 -29
View File
@@ -1,39 +1,92 @@
use crate::PemStorable;
use curve25519_dalek::montgomery::MontgomeryPoint;
use curve25519_dalek::scalar::Scalar;
pub mod x25519;
// TODO: ensure this is a proper name for this considering we are not implementing entire DH here
pub trait MixnetEncryptionKeyPair<Priv, Pub>
where
Priv: MixnetEncryptionPrivateKey,
Pub: MixnetEncryptionPublicKey,
{
fn new() -> Self;
fn private_key(&self) -> &Priv;
fn public_key(&self) -> &Pub;
fn from_bytes(priv_bytes: &[u8], pub_bytes: &[u8]) -> Self;
const CURVE_GENERATOR: MontgomeryPoint = curve25519_dalek::constants::X25519_BASEPOINT;
// TODO: encryption related methods
pub struct KeyPair {
pub(crate) private_key: PrivateKey,
pub(crate) public_key: PublicKey,
}
pub trait MixnetEncryptionPublicKey:
Sized + PemStorable + for<'a> From<&'a <Self as MixnetEncryptionPublicKey>::PrivateKeyMaterial>
{
// we need to couple public and private keys together
type PrivateKeyMaterial: MixnetEncryptionPrivateKey<PublicKeyMaterial = Self>;
impl KeyPair {
pub fn new() -> Self {
let mut rng = rand_os::OsRng::new().unwrap();
let private_key_value = Scalar::random(&mut rng);
let public_key_value = CURVE_GENERATOR * private_key_value;
fn to_bytes(&self) -> Vec<u8>;
fn from_bytes(b: &[u8]) -> Self;
}
pub trait MixnetEncryptionPrivateKey: Sized + PemStorable {
// we need to couple public and private keys together
type PublicKeyMaterial: MixnetEncryptionPublicKey<PrivateKeyMaterial = Self>;
/// Returns the associated public key
fn public_key(&self) -> Self::PublicKeyMaterial {
self.into()
KeyPair {
private_key: PrivateKey(private_key_value),
public_key: PublicKey(public_key_value),
}
}
fn to_bytes(&self) -> Vec<u8>;
fn from_bytes(b: &[u8]) -> Self;
pub fn private_key(&self) -> &PrivateKey {
&self.private_key
}
pub fn public_key(&self) -> &PublicKey {
&self.public_key
}
pub fn from_bytes(priv_bytes: &[u8], pub_bytes: &[u8]) -> Self {
KeyPair {
private_key: PrivateKey::from_bytes(priv_bytes),
public_key: PublicKey::from_bytes(pub_bytes),
}
}
}
// COPY IS DERIVED ONLY TEMPORARILY UNTIL https://github.com/nymtech/nym/issues/47 is fixed
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub struct PrivateKey(pub Scalar);
impl PrivateKey {
pub fn to_bytes(&self) -> Vec<u8> {
self.0.to_bytes().to_vec()
}
pub fn from_bytes(b: &[u8]) -> Self {
let mut bytes = [0; 32];
bytes.copy_from_slice(&b[..]);
// due to trait restriction we have no choice but to panic if this fails
let key = Scalar::from_canonical_bytes(bytes).unwrap();
Self(key)
}
}
impl PemStorable for PrivateKey {
fn pem_type(&self) -> String {
String::from("X25519 PRIVATE KEY")
}
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct PublicKey(pub MontgomeryPoint);
impl<'a> From<&'a PrivateKey> for PublicKey {
fn from(pk: &'a PrivateKey) -> Self {
PublicKey(CURVE_GENERATOR * pk.0)
}
}
impl PublicKey {
pub fn to_bytes(&self) -> Vec<u8> {
self.0.to_bytes().to_vec()
}
pub fn from_bytes(b: &[u8]) -> Self {
let mut bytes = [0; 32];
bytes.copy_from_slice(&b[..]);
let key = MontgomeryPoint(bytes);
Self(key)
}
}
impl PemStorable for PublicKey {
fn pem_type(&self) -> String {
String::from("X25519 PUBLIC KEY")
}
}
-99
View File
@@ -1,99 +0,0 @@
use crate::encryption::{
MixnetEncryptionKeyPair, MixnetEncryptionPrivateKey, MixnetEncryptionPublicKey,
};
use crate::PemStorable;
use curve25519_dalek::montgomery::MontgomeryPoint;
use curve25519_dalek::scalar::Scalar;
// TODO: ensure this is a proper name for this considering we are not implementing entire DH here
const CURVE_GENERATOR: MontgomeryPoint = curve25519_dalek::constants::X25519_BASEPOINT;
pub struct KeyPair {
pub(crate) private_key: PrivateKey,
pub(crate) public_key: PublicKey,
}
impl MixnetEncryptionKeyPair<PrivateKey, PublicKey> for KeyPair {
fn new() -> Self {
let mut rng = rand_os::OsRng::new().unwrap();
let private_key_value = Scalar::random(&mut rng);
let public_key_value = CURVE_GENERATOR * private_key_value;
KeyPair {
private_key: PrivateKey(private_key_value),
public_key: PublicKey(public_key_value),
}
}
fn private_key(&self) -> &PrivateKey {
&self.private_key
}
fn public_key(&self) -> &PublicKey {
&self.public_key
}
fn from_bytes(priv_bytes: &[u8], pub_bytes: &[u8]) -> Self {
KeyPair {
private_key: PrivateKey::from_bytes(priv_bytes),
public_key: PublicKey::from_bytes(pub_bytes),
}
}
}
// COPY IS DERIVED ONLY TEMPORARILY UNTIL https://github.com/nymtech/nym/issues/47 is fixed
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub struct PrivateKey(pub Scalar);
impl MixnetEncryptionPrivateKey for PrivateKey {
type PublicKeyMaterial = PublicKey;
fn to_bytes(&self) -> Vec<u8> {
self.0.to_bytes().to_vec()
}
fn from_bytes(b: &[u8]) -> Self {
let mut bytes = [0; 32];
bytes.copy_from_slice(&b[..]);
// due to trait restriction we have no choice but to panic if this fails
let key = Scalar::from_canonical_bytes(bytes).unwrap();
Self(key)
}
}
impl PemStorable for PrivateKey {
fn pem_type(&self) -> String {
String::from("X25519 PRIVATE KEY")
}
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct PublicKey(pub MontgomeryPoint);
impl<'a> From<&'a PrivateKey> for PublicKey {
fn from(pk: &'a PrivateKey) -> Self {
PublicKey(CURVE_GENERATOR * pk.0)
}
}
impl MixnetEncryptionPublicKey for PublicKey {
type PrivateKeyMaterial = PrivateKey;
fn to_bytes(&self) -> Vec<u8> {
self.0.to_bytes().to_vec()
}
fn from_bytes(b: &[u8]) -> Self {
let mut bytes = [0; 32];
bytes.copy_from_slice(&b[..]);
let key = MontgomeryPoint(bytes);
Self(key)
}
}
impl PemStorable for PublicKey {
fn pem_type(&self) -> String {
String::from("X25519 PUBLIC KEY")
}
}
+41 -95
View File
@@ -1,95 +1,46 @@
use crate::encryption::{
MixnetEncryptionKeyPair, MixnetEncryptionPrivateKey, MixnetEncryptionPublicKey,
};
use crate::{encryption, PemStorable};
use bs58;
use curve25519_dalek::scalar::Scalar;
use sphinx::route::DestinationAddressBytes;
pub trait MixnetIdentityKeyPair<Priv, Pub>: Clone
where
Priv: MixnetIdentityPrivateKey,
Pub: MixnetIdentityPublicKey,
{
fn new() -> Self;
fn private_key(&self) -> &Priv;
fn public_key(&self) -> &Pub;
fn from_bytes(priv_bytes: &[u8], pub_bytes: &[u8]) -> Self;
// TODO: signing related methods
}
pub trait MixnetIdentityPublicKey:
Sized
+ PemStorable
+ Clone
+ for<'a> From<&'a <Self as MixnetIdentityPublicKey>::PrivateKeyMaterial>
{
// we need to couple public and private keys together
type PrivateKeyMaterial: MixnetIdentityPrivateKey<PublicKeyMaterial = Self>;
fn derive_address(&self) -> DestinationAddressBytes;
fn to_bytes(&self) -> Vec<u8>;
fn from_bytes(b: &[u8]) -> Self;
}
pub trait MixnetIdentityPrivateKey: Sized + PemStorable + Clone {
// we need to couple public and private keys together
type PublicKeyMaterial: MixnetIdentityPublicKey<PrivateKeyMaterial = Self>;
/// Returns the associated public key
fn public_key(&self) -> Self::PublicKeyMaterial {
self.into()
}
fn to_bytes(&self) -> Vec<u8>;
fn from_bytes(b: &[u8]) -> Self;
}
// same for validator
// for time being define a dummy identity using x25519 encryption keys (as we've done so far)
// and replace it with proper keys, like ed25519 later on
#[derive(Clone)]
pub struct DummyMixIdentityKeyPair {
pub private_key: DummyMixIdentityPrivateKey,
pub public_key: DummyMixIdentityPublicKey,
pub struct MixIdentityKeyPair {
pub private_key: MixIdentityPrivateKey,
pub public_key: MixIdentityPublicKey,
}
impl MixnetIdentityKeyPair<DummyMixIdentityPrivateKey, DummyMixIdentityPublicKey>
for DummyMixIdentityKeyPair
{
fn new() -> Self {
let keypair = encryption::x25519::KeyPair::new();
DummyMixIdentityKeyPair {
private_key: DummyMixIdentityPrivateKey(keypair.private_key),
public_key: DummyMixIdentityPublicKey(keypair.public_key),
impl MixIdentityKeyPair {
pub fn new() -> Self {
let keypair = encryption::KeyPair::new();
MixIdentityKeyPair {
private_key: MixIdentityPrivateKey(keypair.private_key),
public_key: MixIdentityPublicKey(keypair.public_key),
}
}
fn private_key(&self) -> &DummyMixIdentityPrivateKey {
pub fn private_key(&self) -> &MixIdentityPrivateKey {
&self.private_key
}
fn public_key(&self) -> &DummyMixIdentityPublicKey {
pub fn public_key(&self) -> &MixIdentityPublicKey {
&self.public_key
}
fn from_bytes(priv_bytes: &[u8], pub_bytes: &[u8]) -> Self {
DummyMixIdentityKeyPair {
private_key: DummyMixIdentityPrivateKey::from_bytes(priv_bytes),
public_key: DummyMixIdentityPublicKey::from_bytes(pub_bytes),
pub fn from_bytes(priv_bytes: &[u8], pub_bytes: &[u8]) -> Self {
MixIdentityKeyPair {
private_key: MixIdentityPrivateKey::from_bytes(priv_bytes),
public_key: MixIdentityPublicKey::from_bytes(pub_bytes),
}
}
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct DummyMixIdentityPublicKey(encryption::x25519::PublicKey);
pub struct MixIdentityPublicKey(encryption::PublicKey);
impl MixnetIdentityPublicKey for DummyMixIdentityPublicKey {
type PrivateKeyMaterial = DummyMixIdentityPrivateKey;
fn derive_address(&self) -> DestinationAddressBytes {
impl MixIdentityPublicKey {
pub fn derive_address(&self) -> DestinationAddressBytes {
let mut temporary_address = [0u8; 32];
let public_key_bytes = self.to_bytes();
temporary_address.copy_from_slice(&public_key_bytes[..]);
@@ -97,65 +48,60 @@ impl MixnetIdentityPublicKey for DummyMixIdentityPublicKey {
temporary_address
}
fn to_bytes(&self) -> Vec<u8> {
pub fn to_bytes(&self) -> Vec<u8> {
self.0.to_bytes()
}
fn from_bytes(b: &[u8]) -> Self {
Self(encryption::x25519::PublicKey::from_bytes(b))
pub fn from_bytes(b: &[u8]) -> Self {
Self(encryption::PublicKey::from_bytes(b))
}
pub fn to_base58_string(&self) -> String {
bs58::encode(&self.to_bytes()).into_string()
}
pub fn from_base58_string(val: String) -> Self {
Self::from_bytes(&bs58::decode(&val).into_vec().unwrap())
}
}
impl PemStorable for DummyMixIdentityPublicKey {
impl PemStorable for MixIdentityPublicKey {
fn pem_type(&self) -> String {
format!("DUMMY KEY BASED ON {}", self.0.pem_type())
}
}
impl DummyMixIdentityPublicKey {
pub fn to_base58_string(&self) -> String {
bs58::encode(&self.to_bytes()).into_string()
}
#[allow(dead_code)]
fn from_base58_string(val: String) -> Self {
Self::from_bytes(&bs58::decode(&val).into_vec().unwrap())
}
}
// COPY IS DERIVED ONLY TEMPORARILY UNTIL https://github.com/nymtech/nym/issues/47 is fixed
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub struct DummyMixIdentityPrivateKey(pub encryption::x25519::PrivateKey);
pub struct MixIdentityPrivateKey(pub encryption::PrivateKey);
impl<'a> From<&'a DummyMixIdentityPrivateKey> for DummyMixIdentityPublicKey {
fn from(pk: &'a DummyMixIdentityPrivateKey) -> Self {
impl<'a> From<&'a MixIdentityPrivateKey> for MixIdentityPublicKey {
fn from(pk: &'a MixIdentityPrivateKey) -> Self {
let private_ref = &pk.0;
let public: encryption::x25519::PublicKey = private_ref.into();
DummyMixIdentityPublicKey(public)
let public: encryption::PublicKey = private_ref.into();
MixIdentityPublicKey(public)
}
}
impl MixnetIdentityPrivateKey for DummyMixIdentityPrivateKey {
type PublicKeyMaterial = DummyMixIdentityPublicKey;
fn to_bytes(&self) -> Vec<u8> {
impl MixIdentityPrivateKey {
pub fn to_bytes(&self) -> Vec<u8> {
self.0.to_bytes()
}
fn from_bytes(b: &[u8]) -> Self {
Self(encryption::x25519::PrivateKey::from_bytes(b))
pub fn from_bytes(b: &[u8]) -> Self {
Self(encryption::PrivateKey::from_bytes(b))
}
}
// TODO: this will be implemented differently by using the proper trait
impl DummyMixIdentityPrivateKey {
impl MixIdentityPrivateKey {
pub fn as_scalar(self) -> Scalar {
let encryption_key = self.0;
encryption_key.0
}
}
impl PemStorable for DummyMixIdentityPrivateKey {
impl PemStorable for MixIdentityPrivateKey {
fn pem_type(&self) -> String {
format!("DUMMY KEY BASED ON {}", self.0.pem_type())
}
+6 -25
View File
@@ -1,10 +1,7 @@
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::MixIdentityKeyPair;
use log::trace;
use std::fmt::{Error, Formatter};
use std::marker::PhantomData;
use std::time::Duration;
use topology::{NymTopology, NymTopologyError};
@@ -36,38 +33,22 @@ impl From<topology::NymTopologyError> for HealthCheckerError {
}
}
pub struct HealthChecker<IDPair, Priv, Pub>
where
IDPair: MixnetIdentityKeyPair<Priv, Pub>,
Priv: MixnetIdentityPrivateKey,
Pub: MixnetIdentityPublicKey,
{
pub struct HealthChecker {
num_test_packets: usize,
resolution_timeout: Duration,
identity_keypair: IDPair,
_phantom_private: PhantomData<Priv>,
_phantom_public: PhantomData<Pub>,
identity_keypair: MixIdentityKeyPair,
}
impl<IDPair, Priv, Pub> HealthChecker<IDPair, Priv, Pub>
where
IDPair: crypto::identity::MixnetIdentityKeyPair<Priv, Pub>,
Priv: crypto::identity::MixnetIdentityPrivateKey,
Pub: crypto::identity::MixnetIdentityPublicKey,
{
impl HealthChecker {
pub fn new(
resolution_timeout_f64: f64,
num_test_packets: usize,
identity_keypair: IDPair,
identity_keypair: MixIdentityKeyPair,
) -> Self {
HealthChecker {
resolution_timeout: Duration::from_secs_f64(resolution_timeout_f64),
num_test_packets,
identity_keypair,
_phantom_private: PhantomData,
_phantom_public: PhantomData,
}
}
+4 -9
View File
@@ -1,4 +1,4 @@
use crypto::identity::{MixnetIdentityKeyPair, MixnetIdentityPrivateKey, MixnetIdentityPublicKey};
use crypto::identity::MixIdentityKeyPair;
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(
providers: Vec<provider::Node>,
identity_keys: &IDPair,
identity_keys: &MixIdentityKeyPair,
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();
+4 -10
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::MixIdentityKeyPair;
use log::{debug, error, info, warn};
use rand_os::rand_core::RngCore;
use sphinx::route::NodeAddressBytes;
@@ -102,18 +102,12 @@ impl HealthCheckResult {
id
}
pub async fn calculate<T, IDPair, Priv, Pub>(
pub async fn calculate<T: NymTopology>(
topology: &T,
iterations: usize,
resolution_timeout: Duration,
identity_keys: &IDPair,
) -> Self
where
T: NymTopology,
IDPair: MixnetIdentityKeyPair<Priv, Pub>,
Priv: MixnetIdentityPrivateKey,
Pub: MixnetIdentityPublicKey,
{
identity_keys: &MixIdentityKeyPair,
) -> Self {
// currently healthchecker supports only up to 255 iterations - if we somehow
// find we need more, it's relatively easy change
assert!(iterations <= 255);
+6 -14
View File
@@ -1,4 +1,6 @@
use crate::pathfinder::PathFinder;
use crypto::identity::MixIdentityKeyPair;
use crypto::PemStorable;
use pem::{encode, parse, Pem};
use std::fs::File;
use std::io;
@@ -6,7 +8,7 @@ use std::io::prelude::*;
use std::path::PathBuf;
#[allow(dead_code)]
pub fn read_mix_encryption_keypair_from_disk(_id: String) -> crypto::encryption::x25519::KeyPair {
pub fn read_mix_encryption_keypair_from_disk(_id: String) -> crypto::encryption::KeyPair {
unimplemented!()
}
@@ -25,16 +27,11 @@ 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(&self) -> io::Result<MixIdentityKeyPair> {
let private_pem = self.read_pem_file(self.private_mix_key.clone())?;
let public_pem = self.read_pem_file(self.public_mix_key.clone())?;
let key_pair = IDPair::from_bytes(&private_pem.contents, &public_pem.contents);
let key_pair = MixIdentityKeyPair::from_bytes(&private_pem.contents, &public_pem.contents);
if key_pair.private_key().pem_type() != private_pem.tag {
return Err(io::Error::new(
@@ -62,12 +59,7 @@ 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(&self, key_pair: MixIdentityKeyPair) -> io::Result<()> {
std::fs::create_dir_all(self.config_dir.clone())?;
let private_key = key_pair.private_key();
+9 -6
View File
@@ -242,17 +242,20 @@ impl MixNode {
}
pub fn start(&self, config: node::Config) -> Result<(), Box<dyn std::error::Error>> {
// Create the runtime, probably later move it to MixNode itself?
let mut rt = Runtime::new()?;
let (received_tx, received_rx) = mpsc::channel(1024);
let (sent_tx, sent_rx) = mpsc::channel(1024);
// Set up config and public key for this node
let directory_cfg = directory_client::Config {
base_url: self.directory_server.clone(),
};
let pub_key_str = bs58::encode(&self.public_key.to_bytes().to_vec()).into_string();
// Set up channels
let (received_tx, received_rx) = mpsc::channel(1024);
let (sent_tx, sent_rx) = mpsc::channel(1024);
// Create the runtime, probably later move it to MixNode itself?
let mut rt = Runtime::new()?;
// Spawn Tokio tasks as necessary for node functionality
rt.spawn({
let presence_notifier = presence::Notifier::new(&config);
presence_notifier.run()
+11 -28
View File
@@ -3,7 +3,7 @@ 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::MixIdentityKeyPair;
use directory_client::presence::Topology;
use futures::channel::mpsc;
use futures::join;
@@ -11,7 +11,6 @@ use log::*;
use serde::{Deserialize, Serialize};
use sfw_provider_requests::AuthToken;
use sphinx::route::Destination;
use std::marker::PhantomData;
use std::net::SocketAddr;
use tokio::runtime::Runtime;
use topology::NymTopology;
@@ -40,13 +39,8 @@ pub enum SocketType {
None,
}
pub struct NymClient<IDPair, Priv, Pub>
where
IDPair: MixnetIdentityKeyPair<Priv, Pub> + Send + Sync,
Priv: MixnetIdentityPrivateKey + Send + Sync,
Pub: MixnetIdentityPublicKey + Send + Sync,
{
keypair: IDPair,
pub struct NymClient {
keypair: MixIdentityKeyPair,
// to be used by "send" function or socket, etc
pub input_tx: mpsc::UnboundedSender<InputMessage>,
@@ -56,22 +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>
where
IDPair: MixnetIdentityKeyPair<Priv, Pub> + Send + Sync,
Priv: MixnetIdentityPrivateKey + Send + Sync,
Pub: MixnetIdentityPublicKey + Send + Sync,
{
impl NymClient {
pub fn new(
keypair: IDPair,
keypair: MixIdentityKeyPair,
socket_listening_address: SocketAddr,
directory: String,
auth_token: Option<AuthToken>,
@@ -87,8 +73,6 @@ where
directory,
auth_token,
socket_type,
_phantom_private: PhantomData,
_phantom_public: PhantomData,
}
}
@@ -128,15 +112,14 @@ where
let self_address = self.keypair.public_key().derive_address();
// generate same type of keys we have as our identity
let healthcheck_keys = IDPair::new();
let healthcheck_keys = MixIdentityKeyPair::new();
// 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(
self.directory.clone(),
TOPOLOGY_REFRESH_RATE,
healthcheck_keys,
));
let topology_controller = rt.block_on(topology_control::TopologyControl::<Topology>::new(
self.directory.clone(),
TOPOLOGY_REFRESH_RATE,
healthcheck_keys,
));
let provider_client_listener_address =
rt.block_on(self.get_provider_socket_address(topology_controller.get_inner_ref()));
+5 -17
View File
@@ -1,5 +1,5 @@
use crate::built_info;
use crypto::identity::{MixnetIdentityKeyPair, MixnetIdentityPrivateKey, MixnetIdentityPublicKey};
use crypto::identity::MixIdentityKeyPair;
use healthcheck::HealthChecker;
use log::{error, info, trace, warn};
use std::sync::Arc;
@@ -12,16 +12,10 @@ 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>
where
T: NymTopology,
IDPair: MixnetIdentityKeyPair<Priv, Pub>,
Priv: MixnetIdentityPrivateKey,
Pub: MixnetIdentityPublicKey,
{
pub(crate) struct TopologyControl<T: NymTopology> {
directory_server: String,
inner: Arc<FRwLock<Inner<T>>>,
health_checker: HealthChecker<IDPair, Priv, Pub>,
health_checker: HealthChecker,
refresh_rate: f64,
}
@@ -31,17 +25,11 @@ enum TopologyError {
NoValidPathsError,
}
impl<T, IDPair, Priv, Pub> TopologyControl<T, IDPair, Priv, Pub>
where
T: NymTopology,
IDPair: MixnetIdentityKeyPair<Priv, Pub>,
Priv: MixnetIdentityPrivateKey,
Pub: MixnetIdentityPublicKey,
{
impl<T: NymTopology> TopologyControl<T> {
pub(crate) async fn new(
directory_server: String,
refresh_rate: f64,
identity_keypair: IDPair,
identity_keypair: MixIdentityKeyPair,
) -> Self {
// this is a temporary solution as the healthcheck will eventually be moved to validators
let health_checker = healthcheck::HealthChecker::new(5.0, 2, identity_keypair);
+2 -2
View File
@@ -1,6 +1,6 @@
use crate::config::persistance::pathfinder::ClientPathfinder;
use clap::ArgMatches;
use crypto::identity::MixnetIdentityKeyPair;
use crypto::identity::MixIdentityKeyPair;
use pemstore::pemstore::PemStore;
pub fn execute(matches: &ArgMatches) {
@@ -10,7 +10,7 @@ pub fn execute(matches: &ArgMatches) {
let pathfinder = ClientPathfinder::new(id);
println!("Writing keypairs to {:?}...", pathfinder.config_dir);
let mix_keys = crypto::identity::DummyMixIdentityKeyPair::new();
let mix_keys = MixIdentityKeyPair::new();
let pem_store = PemStore::new(pathfinder);
pem_store.write_identity(mix_keys).unwrap();
+2 -2
View File
@@ -1,7 +1,7 @@
use crate::client::{NymClient, SocketType};
use crate::config::persistance::pathfinder::ClientPathfinder;
use clap::ArgMatches;
use crypto::identity::DummyMixIdentityKeyPair;
use crypto::identity::MixIdentityKeyPair;
use pemstore::pemstore::PemStore;
use std::net::ToSocketAddrs;
@@ -27,7 +27,7 @@ pub fn execute(matches: &ArgMatches) {
.expect("Failed to extract the socket address from the iterator");
// TODO: currently we know we are reading the 'DummyMixIdentityKeyPair', but how to properly assert the type?
let keypair: DummyMixIdentityKeyPair = PemStore::new(ClientPathfinder::new(id))
let keypair: MixIdentityKeyPair = PemStore::new(ClientPathfinder::new(id))
.read_identity()
.unwrap();
// TODO: reading auth_token from disk (if exists);
+2 -2
View File
@@ -1,7 +1,7 @@
use crate::client::{NymClient, SocketType};
use crate::config::persistance::pathfinder::ClientPathfinder;
use clap::ArgMatches;
use crypto::identity::DummyMixIdentityKeyPair;
use crypto::identity::MixIdentityKeyPair;
use pemstore::pemstore::PemStore;
use std::net::ToSocketAddrs;
@@ -27,7 +27,7 @@ pub fn execute(matches: &ArgMatches) {
.expect("Failed to extract the socket address from the iterator");
// TODO: currently we know we are reading the 'DummyMixIdentityKeyPair', but how to properly assert the type?
let keypair: DummyMixIdentityKeyPair = PemStore::new(ClientPathfinder::new(id))
let keypair: MixIdentityKeyPair = PemStore::new(ClientPathfinder::new(id))
.read_identity()
.unwrap();
+1 -2
View File
@@ -1,6 +1,5 @@
use crate::provider::ServiceProvider;
use clap::{App, Arg, ArgMatches, SubCommand};
use crypto::identity::MixnetIdentityKeyPair;
use log::error;
use std::net::ToSocketAddrs;
use std::path::PathBuf;
@@ -121,7 +120,7 @@ fn new_config(matches: &ArgMatches) -> provider::Config {
print_binding_warning(client_host);
}
let key_pair = crypto::identity::DummyMixIdentityKeyPair::new(); // TODO: persist this so keypairs don't change every restart
let key_pair = crypto::identity::MixIdentityKeyPair::new(); // TODO: persist this so keypairs don't change every restart
let store_dir = PathBuf::from(
matches
.value_of("storeDir")
@@ -1,6 +1,6 @@
use crate::provider::storage::{ClientStorage, StoreError};
use crate::provider::ClientLedger;
use crypto::identity::{DummyMixIdentityPrivateKey, MixnetIdentityPrivateKey};
use crypto::identity::MixIdentityPrivateKey;
use futures::lock::Mutex as FMutex;
use hmac::{Hmac, Mac};
use log::*;
@@ -54,14 +54,14 @@ impl From<io::Error> for ClientProcessingError {
pub(crate) struct ClientProcessingData {
store_dir: PathBuf,
registered_clients_ledger: Arc<FMutex<ClientLedger>>,
secret_key: DummyMixIdentityPrivateKey,
secret_key: MixIdentityPrivateKey,
}
impl ClientProcessingData {
pub(crate) fn new(
store_dir: PathBuf,
registered_clients_ledger: Arc<FMutex<ClientLedger>>,
secret_key: DummyMixIdentityPrivateKey,
secret_key: MixIdentityPrivateKey,
) -> Self {
ClientProcessingData {
store_dir,
@@ -153,7 +153,7 @@ impl ClientRequestProcessor {
std::fs::create_dir_all(full_store_dir)
}
fn generate_new_auth_token(data: Vec<u8>, key: DummyMixIdentityPrivateKey) -> AuthToken {
fn generate_new_auth_token(data: Vec<u8>, key: MixIdentityPrivateKey) -> AuthToken {
// also note that `new_varkey` doesn't even have an execution branch returning an error
let mut auth_token_raw = HmacSha256::new_varkey(&key.to_bytes())
.expect("HMAC should be able take key of any size");
@@ -249,7 +249,7 @@ mod generating_new_auth_token {
fn for_the_same_input_generates_the_same_auth_token() {
let data1 = vec![1u8; 55];
let data2 = vec![1u8; 55];
let key = DummyMixIdentityPrivateKey::from_bytes(&[1u8; 32]);
let key = MixIdentityPrivateKey::from_bytes(&[1u8; 32]);
let token1 = ClientRequestProcessor::generate_new_auth_token(data1, key);
let token2 = ClientRequestProcessor::generate_new_auth_token(data2, key);
assert_eq!(token1, token2);
@@ -259,14 +259,14 @@ mod generating_new_auth_token {
fn for_different_inputs_generates_different_auth_tokens() {
let data1 = vec![1u8; 55];
let data2 = vec![2u8; 55];
let key = DummyMixIdentityPrivateKey::from_bytes(&[1u8; 32]);
let key = MixIdentityPrivateKey::from_bytes(&[1u8; 32]);
let token1 = ClientRequestProcessor::generate_new_auth_token(data1, key);
let token2 = ClientRequestProcessor::generate_new_auth_token(data2, key);
assert_ne!(token1, token2);
let data1 = vec![1u8; 50];
let data2 = vec![2u8; 55];
let key = DummyMixIdentityPrivateKey::from_bytes(&[1u8; 32]);
let key = MixIdentityPrivateKey::from_bytes(&[1u8; 32]);
let token1 = ClientRequestProcessor::generate_new_auth_token(data1, key);
let token2 = ClientRequestProcessor::generate_new_auth_token(data2, key);
assert_ne!(token1, token2);
@@ -1,5 +1,5 @@
use crate::provider::storage::StoreData;
use crypto::identity::DummyMixIdentityPrivateKey;
use crypto::identity::MixIdentityPrivateKey;
use log::{error, warn};
use sphinx::{ProcessedPacket, SphinxPacket};
use std::path::PathBuf;
@@ -37,12 +37,12 @@ impl From<std::io::Error> for MixProcessingError {
// ProcessingData defines all data required to correctly unwrap sphinx packets
#[derive(Debug, Clone)]
pub(crate) struct MixProcessingData {
secret_key: DummyMixIdentityPrivateKey,
secret_key: MixIdentityPrivateKey,
pub(crate) store_dir: PathBuf,
}
impl MixProcessingData {
pub(crate) fn new(secret_key: DummyMixIdentityPrivateKey, store_dir: PathBuf) -> Self {
pub(crate) fn new(secret_key: MixIdentityPrivateKey, store_dir: PathBuf) -> Self {
MixProcessingData {
secret_key,
store_dir,
+7 -7
View File
@@ -1,7 +1,7 @@
use crate::provider::client_handling::{ClientProcessingData, ClientRequestProcessor};
use crate::provider::mix_handling::{MixPacketProcessor, MixProcessingData};
use crate::provider::storage::ClientStorage;
use crypto::identity::{DummyMixIdentityPrivateKey, DummyMixIdentityPublicKey};
use crypto::identity::{MixIdentityPrivateKey, MixIdentityPublicKey};
use directory_client::presence::providers::MixProviderClient;
use futures::io::Error;
use futures::lock::Mutex as FMutex;
@@ -29,8 +29,8 @@ pub struct Config {
pub client_socket_address: SocketAddr,
pub directory_server: String,
pub mix_socket_address: SocketAddr,
pub public_key: DummyMixIdentityPublicKey,
pub secret_key: DummyMixIdentityPrivateKey,
pub public_key: MixIdentityPublicKey,
pub secret_key: MixIdentityPrivateKey,
pub store_dir: PathBuf,
}
@@ -102,8 +102,8 @@ pub struct ServiceProvider {
directory_server: String,
mix_network_address: SocketAddr,
client_network_address: SocketAddr,
public_key: DummyMixIdentityPublicKey,
secret_key: DummyMixIdentityPrivateKey,
public_key: MixIdentityPublicKey,
secret_key: MixIdentityPrivateKey,
store_dir: PathBuf,
registered_clients_ledger: ClientLedger,
}
@@ -236,7 +236,7 @@ impl ServiceProvider {
async fn start_mixnet_listening(
address: SocketAddr,
secret_key: DummyMixIdentityPrivateKey,
secret_key: MixIdentityPrivateKey,
store_dir: PathBuf,
) -> Result<(), ProviderError> {
let mut listener = tokio::net::TcpListener::bind(address).await?;
@@ -258,7 +258,7 @@ impl ServiceProvider {
address: SocketAddr,
store_dir: PathBuf,
client_ledger: Arc<FMutex<ClientLedger>>,
secret_key: DummyMixIdentityPrivateKey,
secret_key: MixIdentityPrivateKey,
) -> Result<(), ProviderError> {
let mut listener = tokio::net::TcpListener::bind(address).await?;
let processing_data =
+2 -2
View File
@@ -1,5 +1,5 @@
use crate::provider::ClientLedger;
use crypto::identity::DummyMixIdentityPublicKey;
use crypto::identity::MixIdentityPublicKey;
use directory_client::presence::providers::MixProviderPresence;
use directory_client::requests::presence_providers_post::PresenceMixProviderPoster;
use directory_client::DirectoryClient;
@@ -22,7 +22,7 @@ impl Notifier {
directory_server_address: String,
client_listener: SocketAddr,
mixnet_listener: SocketAddr,
pub_key: DummyMixIdentityPublicKey,
pub_key: MixIdentityPublicKey,
client_ledger: Arc<FMutex<ClientLedger>>,
) -> Notifier {
let directory_config = directory_client::Config {
+2
View File
@@ -8,6 +8,8 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
abci = "0.6.4"
byteorder = "1.3.2"
clap = "2.33.0"
# Read notes https://crates.io/crates/dotenv - tl;dr: don't use in production, set environmental variables properly.
dotenv = "0.15.0"
+21
View File
@@ -0,0 +1,21 @@
Nym Validator
=============
The Nym Validator has several jobs:
* use Tendermint (v0.33.0) to maintain a total global ordering of incoming transactions
* track quality of service for mixnet nodes (mixmining)
* generate Coconut credentials and ensure they're not double spent
* maintain a decentralized directory of all Nym nodes that have staked into the system
Some of these functions may be moved away to their own node types in the future, for example to increase scalability or performance. At the moment, we'd like to keep deployments simple, so they're all in the validator node.
Running the validator on your local machine
-------------------------------------------
1. Download and install [Tendermint 0.32.7](https://github.com/tendermint/tendermint/releases/tag/v0.32.7)
2. `tendermint init` sets up Tendermint for use
3. `tendermint node` runs Tendermint. You'll get errors until you run the Nym validator, this is normal :).
4. `cp sample-configs/validator-config.toml.sample sample-configs/validator-config.toml`
5. `cargo run -- run --config ../sample-configs/validator-config.toml` builds the Nym Validator and runs it
+4 -2
View File
@@ -1,10 +1,12 @@
use crate::validator::config::Config;
use crate::validator::Config;
use crate::validator::Validator;
use clap::{App, Arg, ArgMatches, SubCommand};
use log::{error, trace};
use log::*;
use std::process;
use toml;
mod network;
mod services;
mod validator;
fn main() {
+1
View File
@@ -0,0 +1 @@
// placeholder for Ethereum / ERC20 bridge integration
+4
View File
@@ -0,0 +1,4 @@
//! The `network` module provides interfaces to external systems via network
//! connectivity.
//!
pub mod tendermint;
+67
View File
@@ -0,0 +1,67 @@
use abci::*;
use byteorder::{BigEndian, ByteOrder};
// Convert incoming tx network data to the proper BigEndian size. txs.len() > 8 will return 0
fn convert_tx(tx: &[u8]) -> u64 {
if tx.len() < 8 {
let pad = 8 - tx.len();
let mut x = vec![0; pad];
x.extend_from_slice(tx);
return BigEndian::read_u64(x.as_slice());
}
BigEndian::read_u64(tx)
}
pub struct Abci {
count: u64,
}
impl Abci {
pub fn new() -> Abci {
Abci { count: 0 }
}
pub async fn run(self) {
abci::run_local(self);
}
}
impl abci::Application for Abci {
// Validate transactions. Rule: Transactions must be incremental: 1,2,3,4...
fn check_tx(&mut self, req: &RequestCheckTx) -> ResponseCheckTx {
// Get the Tx [u8] and convert to u64
let c = convert_tx(req.get_tx());
let mut resp = ResponseCheckTx::new();
// Validation logic
if c != self.count + 1 {
resp.set_code(1);
resp.set_log(String::from("Count must be incremental!"));
return resp;
}
// Update state to keep state correct for next check_tx call
self.count = c;
resp
}
fn deliver_tx(&mut self, req: &RequestDeliverTx) -> ResponseDeliverTx {
// Get the Tx [u8]
let c = convert_tx(req.get_tx());
// Update state
self.count = c;
// Return default code 0 == bueno
ResponseDeliverTx::new()
}
fn commit(&mut self, _req: &RequestCommit) -> ResponseCommit {
// Create the response
let mut resp = ResponseCommit::new();
// Convert count to bits
let mut buf = [0; 8];
BigEndian::write_u64(&mut buf, self.count);
// Set data so last state is included in the block
resp.set_data(buf.to_vec());
resp
}
}
@@ -0,0 +1,47 @@
use healthcheck::HealthChecker;
use log::*;
use std::time::Duration;
use topology::NymTopology;
pub struct HealthCheckRunner {
directory_server: String,
health_checker: HealthChecker,
interval: f64,
}
impl HealthCheckRunner {
pub fn new(
directory_server: String,
interval: f64,
health_checker: HealthChecker,
) -> HealthCheckRunner {
HealthCheckRunner {
directory_server,
health_checker,
interval,
}
}
pub async fn run(self) {
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;
+51
View File
@@ -0,0 +1,51 @@
use crate::network::tendermint;
use crate::services::mixmining::health_check_runner;
use crypto::identity::MixIdentityKeyPair;
use healthcheck::HealthChecker;
use tokio::runtime::Runtime;
use serde_derive::Deserialize;
#[derive(Deserialize, Debug)]
pub struct Config {
#[serde(rename(deserialize = "healthcheck"))]
pub health_check: healthcheck::config::HealthCheck,
}
// allow for a generic validator
pub struct Validator {
#[allow(dead_code)]
identity_keypair: MixIdentityKeyPair,
health_check_runner: health_check_runner::HealthCheckRunner,
tendermint_abci: tendermint::Abci,
}
// but for time being, since it's a dummy one, have it use dummy keys
impl Validator {
pub fn new(config: Config) -> Self {
let dummy_keypair = MixIdentityKeyPair::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 {
identity_keypair: dummy_keypair,
health_check_runner,
tendermint_abci: tendermint::Abci::new(),
}
}
pub fn start(self) {
let mut rt = Runtime::new().unwrap();
rt.spawn(self.health_check_runner.run());
rt.block_on(self.tendermint_abci.run());
}
}
-7
View File
@@ -1,7 +0,0 @@
use serde::Deserialize;
#[derive(Deserialize, Debug)]
pub struct Config {
#[serde(rename(deserialize = "healthcheck"))]
pub health_check: healthcheck::config::HealthCheck,
}
-75
View File
@@ -1,75 +0,0 @@
use crate::validator::config::Config;
use crypto::identity::{
DummyMixIdentityKeyPair, DummyMixIdentityPrivateKey, DummyMixIdentityPublicKey,
MixnetIdentityKeyPair, MixnetIdentityPrivateKey, MixnetIdentityPublicKey,
};
use directory_client::presence::Topology;
use healthcheck::HealthChecker;
use log::{debug, error, info};
use std::time::Duration;
use tokio::runtime::Runtime;
use topology::NymTopology;
pub mod config;
// allow for a generic validator
pub struct Validator<IDPair, Priv, Pub>
where
IDPair: MixnetIdentityKeyPair<Priv, Pub>,
Priv: MixnetIdentityPrivateKey,
Pub: MixnetIdentityPublicKey,
{
config: Config,
#[allow(dead_code)]
identity_keypair: IDPair,
heath_check: HealthChecker<IDPair, Priv, Pub>,
}
// but for time being, since it's a dummy one, have it use dummy keys
impl Validator<DummyMixIdentityKeyPair, DummyMixIdentityPrivateKey, DummyMixIdentityPublicKey> {
pub fn new(config: Config) -> Self {
debug!("validator new");
let dummy_keypair = DummyMixIdentityKeyPair::new();
Validator {
identity_keypair: dummy_keypair.clone(),
heath_check: HealthChecker::new(
config.health_check.resolution_timeout,
config.health_check.num_test_packets,
dummy_keypair,
),
config,
}
}
async fn healthcheck_runner<T: NymTopology>(&self) {
let healthcheck_interval = Duration::from_secs_f64(self.config.health_check.interval);
debug!("healthcheck will run every {:?}", healthcheck_interval);
loop {
let full_topology = T::new(self.config.health_check.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.heath_check.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;
}
}
pub fn start(self) {
debug!("validator run");
let mut rt = Runtime::new().unwrap();
let health_check_future = self.healthcheck_runner::<Topology>();
rt.block_on(health_check_future);
}
}