Merge branch 'develop' into feature/config_files
This commit is contained in:
@@ -6,3 +6,4 @@
|
||||
target
|
||||
.env
|
||||
/.vscode/settings.json
|
||||
sample-configs/validator-config.toml
|
||||
Generated
+76
-1
@@ -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"
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
}
|
||||
@@ -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())
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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()));
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,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,
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
// placeholder for Ethereum / ERC20 bridge integration
|
||||
@@ -0,0 +1,4 @@
|
||||
//! The `network` module provides interfaces to external systems via network
|
||||
//! connectivity.
|
||||
//!
|
||||
pub mod tendermint;
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
pub mod health_check_runner;
|
||||
@@ -0,0 +1 @@
|
||||
pub mod mixmining;
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
use serde::Deserialize;
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
pub struct Config {
|
||||
#[serde(rename(deserialize = "healthcheck"))]
|
||||
pub health_check: healthcheck::config::HealthCheck,
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user