Feature/report node hardware info (#1308)

* Adding simple hardware info reporting to the mixnode HTTP API

* Adding sgx availability as another example field

* Added sysinfo crate for addtitional simple hardware reporting

* Added reporting on number of cpu cores and available ram

* Cleanup of unused struct

* Fixing merge conflict

* Checking for supported system before using sysinfo

* Breaking commit containing additional types

...and a painfully wrong implementation of the SMT processor cores type.

* Handling unavailable brand string

* Fixed getting SMT logical processor count

* Rebase with develop + cleaned up changelog

* unused import

Co-authored-by: Jędrzej Stuczyński <jedrzej.stuczynski@gmail.com>
This commit is contained in:
Dave Hrycyszyn
2022-06-20 09:49:32 +01:00
committed by GitHub
parent b4f3a48550
commit 135c818fee
6 changed files with 129 additions and 3 deletions
+87
View File
@@ -0,0 +1,87 @@
use cupid::TopologyType;
use rocket::serde::{json::Json, Serialize};
use sysinfo::{System, SystemExt};
#[derive(Serialize, Debug)]
#[serde(crate = "rocket::serde")]
pub(crate) struct Hardware {
ram: String,
num_cores: usize,
crypto_hardware: Option<CryptoHardware>,
}
#[derive(Serialize, Debug)]
#[serde(crate = "rocket::serde")]
pub(crate) struct CryptoHardware {
aesni: bool,
avx2: bool,
brand_string: String,
smt_logical_processor_count: Vec<u32>,
osxsave: bool,
sgx: bool,
xsave: bool,
}
/// Provides hardware information which Nym can use to optimize mixnet speed over time (memory, crypto hardware, CPU, cores, etc).
#[get("/hardware")]
pub(crate) fn hardware() -> Json<Option<Hardware>> {
Json(hardware_info())
}
/// Gives back a summary report of whatever system hardware info we can get for this platform.
fn hardware_info() -> Option<Hardware> {
let crypto_hardware = hardware_info_from_cupid();
hardware_from_sysinfo(crypto_hardware)
}
/// Sysinfo gives back basic stuff like number of CPU cores and available memory. If available, this includes the hardware encryption
/// extensions report
fn hardware_from_sysinfo(crypto_hardware: Option<CryptoHardware>) -> Option<Hardware> {
if System::IS_SUPPORTED {
let mut system = System::new_all();
system.refresh_all();
let ram = format!("{}KB", system.total_memory());
let cores = system.cpus();
let num_cores = cores.len();
Some(Hardware {
crypto_hardware,
ram,
num_cores,
})
} else {
None
}
}
/// The `cupid` crate gives back a report on available hardware encryption extensions which may be useful for future mixnet optimizations.
///
/// Note: this information is generally only available on x86 platforms for Linux.
fn hardware_info_from_cupid() -> Option<CryptoHardware> {
cupid::master().map(|info| -> CryptoHardware {
let smt_logical_processor_count =
if let Some(extended_topology) = info.extended_topology_enumeration() {
extended_topology
.clone()
.filter_map(|entry| {
if entry.level_type() == TopologyType::SMT {
Some(entry.logical_processor_count())
} else {
None
}
})
.collect()
} else {
Vec::new()
};
CryptoHardware {
aesni: info.aesni(),
avx2: info.avx2(),
brand_string: info.brand_string().map(String::from).unwrap_or_default(),
smt_logical_processor_count,
osxsave: info.osxsave(),
sgx: info.sgx(),
xsave: info.xsave(),
}
})
}
+1
View File
@@ -1,4 +1,5 @@
pub(crate) mod description;
pub(crate) mod hardware;
pub(crate) mod stats;
pub(crate) mod verloc;
+2 -1
View File
@@ -6,6 +6,7 @@ use crate::config::persistence::pathfinder::MixNodePathfinder;
use crate::config::Config;
use crate::node::http::{
description::description,
hardware::hardware,
not_found,
stats::stats,
verloc::{verloc as verlocRoute, VerlocState},
@@ -140,7 +141,7 @@ impl MixNode {
tokio::spawn(async move {
rocket::build()
.configure(config)
.mount("/", routes![verlocRoute, description, stats])
.mount("/", routes![verlocRoute, description, stats, hardware])
.register("/", catchers![not_found])
.manage(verloc_state)
.manage(descriptor)