Files
nym/mixnode/src/node/mod.rs
T
2020-02-27 12:20:00 +00:00

123 lines
4.2 KiB
Rust

use crate::config::persistance::pathfinder::MixNodePathfinder;
use crate::config::Config;
use crate::node::packet_processing::PacketProcessor;
use crypto::encryption;
use futures::channel::mpsc;
use log::*;
use pemstore::pemstore::PemStore;
use std::net::SocketAddr;
use tokio::runtime::Runtime;
mod listener;
mod metrics;
mod packet_forwarding;
pub(crate) mod packet_processing;
mod presence;
// the MixNode will live for whole duration of this program
pub struct MixNode {
runtime: Runtime,
config: Config,
sphinx_keypair: encryption::KeyPair,
}
impl MixNode {
fn load_sphinx_keys(config_file: &Config) -> encryption::KeyPair {
let sphinx_keypair = PemStore::new(MixNodePathfinder::new_from_config(&config_file))
.read_encryption()
.expect("Failed to read stored sphinx key files");
println!(
"Public encryption key: {}\nFor time being, it is identical to identity keys",
sphinx_keypair.public_key().to_base58_string()
);
sphinx_keypair
}
pub fn new(config: Config) -> Self {
let sphinx_keypair = Self::load_sphinx_keys(&config);
MixNode {
runtime: Runtime::new().unwrap(),
config,
sphinx_keypair,
}
}
pub fn start_presence_notifier(&self) {
info!("Starting presence notifier...");
let notifier_config = presence::NotifierConfig::new(
self.config.get_presence_directory_server(),
self.config.get_announce_address(),
self.sphinx_keypair.public_key().to_base58_string(),
self.config.get_layer(),
self.config.get_presence_sending_delay(),
);
presence::Notifier::new(notifier_config).start(self.runtime.handle());
}
pub fn start_metrics_reporter(&self) -> metrics::MetricsReporter {
info!("Starting metrics reporter...");
metrics::MetricsController::new(
self.config.get_metrics_directory_server(),
self.sphinx_keypair.public_key().to_base58_string(),
self.config.get_metrics_sending_delay(),
)
.start(self.runtime.handle())
}
pub fn start_socket_listener(
&self,
metrics_reporter: metrics::MetricsReporter,
forwarding_channel: mpsc::UnboundedSender<(SocketAddr, Vec<u8>)>,
) {
info!("Starting socket listener...");
// this is the only location where our private key is going to be copied
// it will be held in memory owned by `MixNode` and inside an Arc of `PacketProcessor`
let packet_processor =
PacketProcessor::new(self.sphinx_keypair.private_key().clone(), metrics_reporter);
listener::run_socket_listener(
self.runtime.handle(),
self.config.get_listening_address(),
packet_processor,
forwarding_channel,
);
}
pub fn start_packet_forwarder(&mut self) -> mpsc::UnboundedSender<(SocketAddr, Vec<u8>)> {
info!("Starting packet forwarder...");
// only temporary for test sake, will be replaced with dynamic list extremely soon
let initial_addresses = vec![
"127.0.0.1:4000".parse().unwrap(),
"127.0.0.1:5000".parse().unwrap(),
"127.0.0.1:5001".parse().unwrap(),
"127.0.0.1:5002".parse().unwrap(),
];
self.runtime
.block_on(packet_forwarding::PacketForwarder::new(
initial_addresses,
self.config.get_packet_forwarding_initial_backoff(),
self.config.get_packet_forwarding_maximum_backoff(),
))
.start(self.runtime.handle())
}
pub fn run(&mut self) {
let forwarding_channel = self.start_packet_forwarder();
let metrics_reporter = self.start_metrics_reporter();
self.start_socket_listener(metrics_reporter, forwarding_channel);
self.start_presence_notifier();
if let Err(e) = self.runtime.block_on(tokio::signal::ctrl_c()) {
error!(
"There was an error while capturing SIGINT - {:?}. We will terminate regardless",
e
);
}
println!(
"Received SIGINT - the mixnode will terminate now (threads are not YET nicely stopped)"
);
}
}