write metrics to the /host/logs

Signed-off-by: Valentyn Faychuk <valy@detee.ltd>
This commit is contained in:
Valentyn Faychuk 2024-11-29 16:12:27 +02:00
parent c2e751d893
commit 3c93b258f5
Signed by: valy
GPG Key ID: F1AB995E20FEADC5
9 changed files with 70 additions and 27 deletions

2
.cargo/config Normal file

@ -0,0 +1,2 @@
[net]
git-fetch-with-cli=true

@ -9,9 +9,11 @@ message NodeUpdate {
google.protobuf.Timestamp keepalive = 3;
uint64 mint_requests = 4;
uint64 mints = 5;
uint64 ratls_conns = 6;
uint64 ratls_attacks = 7;
uint64 mratls_conns = 6;
uint64 quote_attacks = 7;
bool public = 8;
uint64 restarts = 9;
uint64 disk_attacks = 10;
}
message Keys {

@ -2,6 +2,7 @@
use crate::solana::Client as SolClient;
use dashmap::{DashMap, DashSet};
use std::time::{Duration, SystemTime};
use crate::persistence::Logfile;
type IP = String;
pub const LOCALHOST: &str = "localhost";
@ -12,9 +13,11 @@ pub struct NodeInfo {
pub keepalive: SystemTime,
pub mint_requests: u64,
pub mints: u64,
pub ratls_conns: u64,
pub ratls_attacks: u64,
pub mratls_conns: u64,
pub quote_attacks: u64,
pub public: bool,
pub restarts: u64,
pub disk_attacks: u64,
}
impl NodeInfo {
@ -25,8 +28,8 @@ impl NodeInfo {
}
}
if self.mint_requests > other_node.mint_requests
|| self.ratls_attacks > other_node.ratls_attacks
|| self.ratls_conns > other_node.ratls_conns
|| self.quote_attacks > other_node.quote_attacks
|| self.mratls_conns > other_node.mratls_conns
|| self.mints > other_node.mints
|| (self.public && !other_node.public)
{
@ -34,6 +37,12 @@ impl NodeInfo {
}
false
}
pub fn log(&self, ip: &IP) {
if let Err(e) = Logfile::append(&format!("{}: {:?}", ip, self)) {
println!("Could not log: {:?}", e);
}
}
}
/// Keypair must already be known when creating a Store
@ -55,9 +64,11 @@ impl Store {
keepalive: SystemTime::now(),
mint_requests: 0,
mints: 0,
ratls_conns: 0,
ratls_attacks: 0,
mratls_conns: 0,
quote_attacks: 0,
public: false,
restarts: 0,
disk_attacks: 0,
},
);
store
@ -86,18 +97,28 @@ impl Store {
pub fn increase_mint_requests(&self) {
if let Some(mut localhost_info) = self.nodes.get_mut(LOCALHOST) {
localhost_info.mint_requests += 1;
localhost_info.log(localhost_info.key());
}
}
pub fn increase_mints(&self) {
if let Some(mut localhost_info) = self.nodes.get_mut(LOCALHOST) {
localhost_info.mints += 1;
localhost_info.log(localhost_info.key());
}
}
pub fn increase_ratls_conns(&self) {
pub fn increase_mratls_conns(&self) {
if let Some(mut localhost_info) = self.nodes.get_mut(LOCALHOST) {
localhost_info.ratls_conns += 1;
localhost_info.mratls_conns += 1;
localhost_info.log(localhost_info.key());
}
}
pub fn increase_disk_attacks(&self) {
if let Some(mut localhost_info) = self.nodes.get_mut(LOCALHOST) {
localhost_info.disk_attacks += 1;
localhost_info.log(localhost_info.key());
}
}
@ -116,10 +137,7 @@ impl Store {
}
/// This returns true if NodeInfo got modified.
///
/// On a side note, there are two types of people in this world:
/// 1. Those that can extrapolate... WAT?
pub async fn process_node_update(&self, (ip, mut node_info): (String, NodeInfo)) -> bool {
pub fn process_node_update(&self, (ip, mut node_info): (String, NodeInfo)) -> bool {
if let Some(old_node) = self.nodes.get(&ip) {
if !node_info.newer_than(&old_node) {
return false;
@ -127,6 +145,7 @@ impl Store {
node_info.public = node_info.public || old_node.public;
}
println!("Inserting: {}, {:?}", ip, node_info);
node_info.log(&ip);
self.nodes.insert(ip, node_info);
true
}
@ -153,6 +172,7 @@ impl Store {
pub fn remove_inactive_nodes(&self) {
self.nodes.retain(|_, v| {
// HACK: Check if it is possible to abuse network by corrupting system time
let age =
SystemTime::now().duration_since(v.keepalive).unwrap_or(Duration::ZERO).as_secs();
age <= 600

@ -108,7 +108,7 @@ impl ConnManager {
}
// update the entire network in case the information is new
if self.ds.process_node_update(update.clone().into()).await
if self.ds.process_node_update(update.clone().into())
&& self.tx.send(update.clone()).is_err()
{
println!("tokio broadcast receivers had an issue consuming the channel");

@ -15,9 +15,11 @@ impl From<(String, NodeInfo)> for NodeUpdate {
keepalive: Some(prost_types::Timestamp::from(info.keepalive)),
mint_requests: info.mint_requests,
mints: info.mints,
ratls_conns: info.ratls_conns,
ratls_attacks: info.ratls_attacks,
mratls_conns: info.mratls_conns,
quote_attacks: info.quote_attacks,
public: info.public,
restarts: info.restarts,
disk_attacks: info.disk_attacks
}
}
}
@ -44,9 +46,11 @@ impl From<NodeUpdate> for (String, NodeInfo) {
keepalive,
mint_requests: val.mint_requests,
mints: val.mints,
ratls_conns: val.ratls_conns,
ratls_attacks: val.ratls_attacks,
mratls_conns: val.mratls_conns,
quote_attacks: val.quote_attacks,
public: val.public,
restarts: val.restarts,
disk_attacks: val.disk_attacks
};
(ip, self_info)
}

@ -113,7 +113,7 @@ impl Update for MyServer {
&self,
req: Request<Streaming<NodeUpdate>>,
) -> Result<Response<Self::GetUpdatesStream>, Status> {
self.ds.increase_ratls_conns();
self.ds.increase_mratls_conns();
let remote_ip = req.remote_addr().unwrap().ip().to_string();
let tx = self.tx.clone();
let mut rx = self.tx.subscribe();
@ -136,7 +136,7 @@ impl Update for MyServer {
// note that we don't set this node online,
// as it can be behind NAT
}
if update.ip != "127.0.0.1" && ds.process_node_update(update.clone().into()).await && tx.send(update.clone()).is_err() {
if update.ip != "127.0.0.1" && ds.process_node_update(update.clone().into()) && tx.send(update.clone()).is_err() {
println!("tokio broadcast receivers had an issue consuming the channel");
};
}

@ -39,8 +39,8 @@ impl From<(String, datastore::NodeInfo)> for NodesResp {
joined_at,
last_keepalive,
mints: node_info.mints,
total_ratls_conns: node_info.ratls_conns,
ratls_attacks: node_info.ratls_attacks,
total_ratls_conns: node_info.mratls_conns,
ratls_attacks: node_info.quote_attacks,
public: node_info.public,
mint_requests: node_info.mint_requests,
}
@ -63,12 +63,12 @@ struct MintReq {
async fn mint(ds: web::Data<Arc<Store>>, req: web::Json<MintReq>) -> impl Responder {
ds.increase_mint_requests();
let result =
actix_web::web::block(move || ds.mint(&req.into_inner().wallet).map_err(|e| e.to_string()))
web::block(move || ds.mint(&req.into_inner().wallet).map_err(|e| e.to_string()))
.await
.unwrap(); // TODO: check if this can get a BlockingError
match result {
Ok(s) => HttpResponse::Ok().body(format!(r#"{{ "signature": "{s}"}}"#)),
Err(e) => HttpResponse::InternalServerError().body(format!(r#"{{ "error": "{e}"}}"#)),
Ok(s) => HttpResponse::Ok().body(format!(r#"{{" signature": "{s} "}}"#)),
Err(e) => HttpResponse::InternalServerError().body(format!(r#"{{ "error": "{e}" }}"#)),
}
}

@ -81,7 +81,7 @@ async fn main() {
let sol_client = get_sol_client().await;
let ds = Arc::new(Store::init(sol_client));
let (tx, mut _rx) = broadcast::channel(500);
let (tx, _) = broadcast::channel(500);
let mut tasks = JoinSet::new();

@ -40,3 +40,18 @@ impl Data {
(keypair, pubkey)
}
}
const LOG_PATH: &str = "/host/logs";
pub struct Logfile {}
impl Logfile {
pub fn append(msg: &str) -> Result<(), Box<dyn std::error::Error>> {
use std::io::Write;
let mut file = std::fs::OpenOptions::new()
.append(true)
.open(LOG_PATH)?;
file.write_all(msg.as_bytes())?;
Ok(())
}
}