Compare commits

...

3 Commits

Author SHA1 Message Date
46929fa84c
switch to new staging brain 2025-06-18 17:47:09 +03:00
8d07122df2
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-16 13:50:24 +05:30
79968b2d1e
new brain proto and new staging address 2025-06-05 16:33:18 +03:00
5 changed files with 55 additions and 48 deletions

2
Cargo.lock generated

@ -395,7 +395,7 @@ dependencies = [
[[package]] [[package]]
name = "detee-shared" name = "detee-shared"
version = "0.1.0" version = "0.1.0"
source = "git+ssh://git@gitea.detee.cloud/testnet/proto?branch=main#b5289f1f5ba3ddae2ee066d6deb073ce92436b71" source = "git+ssh://git@gitea.detee.cloud/testnet/proto?branch=surreal_brain#d6ca058d2de78b5257517034bca2b2c7d5929db8"
dependencies = [ dependencies = [
"bincode", "bincode",
"prost", "prost",

@ -24,7 +24,8 @@ serde_json = "1.0.135"
bs58 = "0.5.1" bs58 = "0.5.1"
chrono = "0.4.39" chrono = "0.4.39"
detee-shared = { git = "ssh://git@gitea.detee.cloud/testnet/proto", branch = "main" } # TODO: switch this back to main after the upgrade
detee-shared = { git = "ssh://git@gitea.detee.cloud/testnet/proto", branch = "surreal_brain" }
# detee-shared = { path = "../detee-shared" } # detee-shared = { path = "../detee-shared" }
[build-dependencies] [build-dependencies]

@ -2,12 +2,19 @@ use anyhow::Result;
use ed25519_dalek::SigningKey; use ed25519_dalek::SigningKey;
use lazy_static::lazy_static; use lazy_static::lazy_static;
use log::{info, warn}; use log::{info, warn};
use rand::Rng;
use sha2::{Digest, Sha256}; use sha2::{Digest, Sha256};
use std::{fs::File, io::Read, io::Write}; use std::{
fs::File,
io::{Read, Write},
sync::LazyLock,
};
pub(crate) const DETEE_ROOT_CA: &str = "/etc/detee/root_ca.pem"; pub(crate) const DETEE_ROOT_CA: &str = "/etc/detee/root_ca.pem";
pub(crate) const BRAIN_STAGING: (&str, &str) = ("https://159.65.58.38:31337", "staging-brain"); pub(crate) const BRAIN_STAGING_URLS: [&str; 3] =
pub(crate) const BRAIN_TESTING: (&str, &str) = ("https://164.92.249.180:31337", "testnet-brain"); ["https://156.146.63.216:31337", "https://156.146.63.216:31337", "https://156.146.63.216:31337"];
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 VM_BOOT_DIR: &str = "/var/lib/detee/boot/";
pub(crate) const USED_RESOURCES: &str = "/etc/detee/daemon/used_resources.yaml"; 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 VM_CONFIG_DIR: &str = "/etc/detee/daemon/vms/";
@ -22,6 +29,14 @@ pub(crate) const OVMF_HASH: &str =
pub(crate) const OVMF_URL: &str = pub(crate) const OVMF_URL: &str =
"https://drive.google.com/uc?export=download&id=1V-vLkaiLaGmFSjrN84Z6nELQOxKNAoSJ"; "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! { lazy_static! {
pub static ref PUBLIC_KEY: String = get_public_key(); pub static ref PUBLIC_KEY: String = get_public_key();
pub static ref IP_INFO: IPInfo = get_ip_info().unwrap(); pub static ref IP_INFO: IPInfo = get_ip_info().unwrap();

@ -1,10 +1,8 @@
use crate::global::*; use crate::{global::*, snp_proto::VmDaemonMessage};
use crate::snp_proto::VmDaemonMessage;
use anyhow::Result; use anyhow::Result;
use detee_shared::vm_proto::DeleteVmReq;
use log::{debug, info, warn}; use log::{debug, info, warn};
use snp_proto::{ use snp_proto::{brain_vm_daemon_client::BrainVmDaemonClient, BrainVmMessage, RegisterVmNodeReq};
brain_vm_daemon_client::BrainVmDaemonClient, BrainVmMessage, RegisterVmNodeReq, VmContract,
};
use tokio::{ use tokio::{
sync::mpsc::{Receiver, Sender}, sync::mpsc::{Receiver, Sender},
task::JoinSet, task::JoinSet,
@ -18,14 +16,16 @@ pub mod snp_proto {
async fn client(network: &str) -> Result<BrainVmDaemonClient<Channel>> { async fn client(network: &str) -> Result<BrainVmDaemonClient<Channel>> {
let (brain_url, brain_san) = match network { let (brain_url, brain_san) = match network {
"staging" => BRAIN_STAGING, "staging" => *BRAIN_STAGING,
"testnet" => BRAIN_TESTING, "testnet" => *BRAIN_TESTING,
_ => { _ => {
return Err(anyhow::anyhow!( return Err(anyhow::anyhow!(
"The only networks currently supported are staging and testnet." "The only networks currently supported are staging and testnet."
)) ))
} }
}; };
info!("brain_url: {brain_url}, brain_san: {brain_san}");
let pem = std::fs::read_to_string(DETEE_ROOT_CA)?; let pem = std::fs::read_to_string(DETEE_ROOT_CA)?;
let ca = Certificate::from_pem(pem); let ca = Certificate::from_pem(pem);
@ -36,9 +36,8 @@ async fn client(network: &str) -> Result<BrainVmDaemonClient<Channel>> {
Ok(BrainVmDaemonClient::new(channel)) Ok(BrainVmDaemonClient::new(channel))
} }
pub async fn register_node(config: &crate::config::Config) -> Result<Vec<VmContract>> { pub async fn register_node(config: &crate::config::Config) -> Result<Vec<DeleteVmReq>> {
use tonic::metadata::AsciiMetadataValue; use tonic::{metadata::AsciiMetadataValue, Request};
use tonic::Request;
let mut client = client(&config.network).await?; let mut client = client(&config.network).await?;
debug!("Starting node registration..."); debug!("Starting node registration...");
let ip_info = IP_INFO.clone(); let ip_info = IP_INFO.clone();
@ -68,7 +67,7 @@ pub async fn register_node(config: &crate::config::Config) -> Result<Vec<VmContr
while let Some(stream_update) = grpc_stream.next().await { while let Some(stream_update) = grpc_stream.next().await {
match stream_update { match stream_update {
Ok(node) => { Ok(node) => {
debug!("Received contract from brain: {node:?}"); debug!("Received deleted VM from brain: {node:?}");
contracts.push(node); contracts.push(node);
} }
Err(e) => { Err(e) => {

@ -3,8 +3,7 @@ mod global;
mod grpc; mod grpc;
mod state; mod state;
use crate::global::*; use crate::{config::Config, global::*, grpc::snp_proto};
use crate::{config::Config, grpc::snp_proto};
use anyhow::{anyhow, Result}; use anyhow::{anyhow, Result};
use log::{debug, info, warn}; use log::{debug, info, warn};
use std::{fs::File, path::Path}; use std::{fs::File, path::Path};
@ -205,31 +204,27 @@ impl VMHandler {
} }
} }
fn clear_deleted_contracts(&mut self, contracts: Vec<snp_proto::VmContract>) { fn clear_deleted_contracts(&mut self, deleted_vms: Vec<snp_proto::DeleteVmReq>) {
for uuid in self.res.existing_vms.clone() { for deleted_vm in deleted_vms {
if contracts.iter().find(|c| c.uuid == uuid).is_none() { let uuid = deleted_vm.uuid;
info!("VM {uuid} exists locally but not found in brain. Deleting..."); let content = match std::fs::read_to_string(VM_CONFIG_DIR.to_string() + &uuid + ".yaml")
let content = {
match std::fs::read_to_string(VM_CONFIG_DIR.to_string() + &uuid + ".yaml") { Ok(content) => content,
Ok(content) => content, Err(e) => {
Err(e) => { log::debug!("Could not find VM config for {uuid}. Maybe it already got deleted? Error: {e:?}");
log::error!( continue;
"Could not find VM config for {uuid}. Cannot delete VM: {e:?}"
);
continue;
}
};
let vm: crate::state::VM = match serde_yaml::from_str(&content) {
Ok(vm) => vm,
Err(e) => {
log::error!("VM config corrupted for {uuid}. Cannot delete VM: {e:?}");
continue;
}
};
match vm.delete(&mut self.res) {
Ok(()) => info!("Successfully deleted VM {uuid}"),
Err(e) => log::error!("Deletion failed for VM {uuid}: {e:?}"),
} }
};
let vm: crate::state::VM = match serde_yaml::from_str(&content) {
Ok(vm) => vm,
Err(e) => {
log::error!("VM config corrupted for {uuid}. Cannot delete VM: {e:?}");
continue;
}
};
match vm.delete(&mut self.res) {
Ok(()) => info!("Successfully deleted VM {uuid}"),
Err(e) => log::error!("Deletion failed for VM {uuid}: {e:?}"),
} }
} }
} }
@ -252,14 +247,11 @@ async fn main() {
let mut vm_handler = VMHandler::new(brain_msg_rx, daemon_msg_tx.clone()); let mut vm_handler = VMHandler::new(brain_msg_rx, daemon_msg_tx.clone());
let network = vm_handler.config.network.clone(); let network = vm_handler.config.network.clone();
let contracts: Vec<String> = vm_handler.res.existing_vms.clone().into_iter().collect();
info!("Registering with the brain and getting back VM Contracts (if they exist)."); info!("Registering with the brain and getting back deleted VMs.");
let mut contracts: Vec<String> = Vec::new();
match grpc::register_node(&vm_handler.config).await { match grpc::register_node(&vm_handler.config).await {
Ok(c) => { Ok(deleted_vms) => vm_handler.clear_deleted_contracts(deleted_vms),
contracts.append(&mut c.iter().map(|c| c.uuid.clone()).collect());
vm_handler.clear_deleted_contracts(c)
}
Err(e) => log::error!("Could not get contracts from brain: {e:?}"), Err(e) => log::error!("Could not get contracts from brain: {e:?}"),
}; };