snp-daemon/src/global.rs
Noor d6a8f14124
Improves brain connection reliability
Updates the brain connection logic to randomly select from a list of available URLs for staging and testnet environments.
2025-06-20 02:29:05 +03:00

113 lines
4.0 KiB
Rust

// SPDX-License-Identifier: Apache-2.0
use anyhow::Result;
use ed25519_dalek::SigningKey;
use lazy_static::lazy_static;
use log::{info, warn};
use rand::Rng;
use sha2::{Digest, Sha256};
use std::{
fs::File,
io::{Read, Write},
sync::LazyLock,
};
pub(crate) const DETEE_ROOT_CA: &str = "/etc/detee/root_ca.pem";
pub(crate) const BRAIN_STAGING_URLS: [&str; 3] =
["https://184.107.169.199:49092", "https://149.22.95.1:47855", "https://149.36.48.99:48843"];
pub(crate) const BRAIN_TESTING_URLS: [&str; 3] =
["https://184.107.169.199:45223", "https://149.22.95.1:44522", "https://149.36.48.99:48638"];
pub(crate) const VM_BOOT_DIR: &str = "/var/lib/detee/boot/";
pub(crate) const USED_RESOURCES: &str = "/etc/detee/daemon/used_resources.yaml";
pub(crate) const VM_CONFIG_DIR: &str = "/etc/detee/daemon/vms/";
pub(crate) const SECRET_KEY_PATH: &str = "/etc/detee/daemon/node_secret_key.pem";
pub(crate) const DAEMON_CONFIG_PATH: &str = "/etc/detee/daemon/config.yaml";
pub(crate) const START_VM_SCRIPT: &str = "/usr/local/bin/detee/start_qemu_vm.sh";
// TODO: research if other CPU types provide better performance
pub(crate) const QEMU_VM_CPU_TYPE: &str = "EPYC-v4";
// If you modify this, also modify scripts/start_qemu_vm.sh
pub(crate) const OVMF_HASH: &str =
"0346619257269b9a61ee003e197d521b8e2283483070d163a34940d6a1d40d76";
pub(crate) const OVMF_URL: &str =
"https://drive.google.com/uc?export=download&id=1V-vLkaiLaGmFSjrN84Z6nELQOxKNAoSJ";
pub static BRAIN_STAGING: LazyLock<(&str, &str)> = LazyLock::new(|| {
(BRAIN_STAGING_URLS[rand::thread_rng().gen_range(0..BRAIN_STAGING_URLS.len())], "staging-brain")
});
pub static BRAIN_TESTING: LazyLock<(&str, &str)> = LazyLock::new(|| {
(BRAIN_TESTING_URLS[rand::thread_rng().gen_range(0..BRAIN_TESTING_URLS.len())], "testnet-brain")
});
lazy_static! {
pub static ref PUBLIC_KEY: String = get_public_key();
pub static ref IP_INFO: IPInfo = get_ip_info().unwrap();
}
fn create_secret_key() -> Result<ed25519_dalek::SigningKey> {
let key_path = SECRET_KEY_PATH;
info!("Creating new secret key at {}", key_path);
let sk = ed25519_dalek::SigningKey::generate(&mut rand_core::OsRng);
let private_key_string = bs58::encode(sk.to_bytes()).into_string();
let mut file = File::create(key_path)?;
file.write_all(private_key_string.as_bytes())?;
Ok(sk)
}
fn load_secret_key() -> Result<ed25519_dalek::SigningKey> {
let secret_key_string = match std::fs::read_to_string(SECRET_KEY_PATH) {
Ok(secret_key_pem) => secret_key_pem,
Err(e) => {
warn!("Could not load secret key due to error: {e:?}");
return Ok(create_secret_key()?);
}
};
Ok(SigningKey::from_bytes(
&bs58::decode(secret_key_string)
.into_vec()?
.try_into()
.map_err(|_| bs58::decode::Error::BufferTooSmall)?,
))
}
pub fn sign_message(msg: &str) -> Result<String> {
use ed25519_dalek::Signer;
let key = load_secret_key()?;
Ok(bs58::encode(key.sign(msg.as_bytes()).to_bytes()).into_string())
}
pub fn get_public_key() -> String {
let pubkey = bs58::encode(load_secret_key().unwrap().verifying_key().to_bytes()).into_string();
log::info!("Loaded the following public key: {pubkey}");
pubkey
}
#[derive(serde::Deserialize, Clone)]
pub struct IPInfo {
pub country: String,
pub region: String,
pub city: String,
pub ip: String,
}
fn get_ip_info() -> anyhow::Result<IPInfo> {
let body = reqwest::blocking::get("https://ipinfo.io/".to_string())?.text()?;
info!("Got the following data from ipinfo.io: {body}");
Ok(serde_json::de::from_str(&body)?)
}
pub fn compute_sha256<P: AsRef<std::path::Path>>(path: P) -> Result<String> {
let mut file = File::open(path)?;
let mut hasher = Sha256::new();
let mut buffer = [0u8; 8192];
loop {
let bytes_read = file.read(&mut buffer)?;
if bytes_read == 0 {
break;
}
hasher.update(&buffer[..bytes_read]);
}
let result = hasher.finalize();
Ok(format!("{:x}", result))
}