feat: move sgx utility functions to sgx/utils module for better organization

This commit is contained in:
Noor 2025-03-20 16:51:38 +05:30
parent bb861fe817
commit 4d17ba6667
Signed by: noormohammedb
GPG Key ID: D83EFB8B3B967146
6 changed files with 136 additions and 128 deletions

@ -3,8 +3,9 @@ use crate::sgx::config::{validate_yaml, DeteeCliExt};
use crate::sgx::grpc_brain::{delete_app, new_app};
use crate::sgx::grpc_dtpm::{attest_and_send_config, get_config_from_enclave};
use crate::sgx::packaging::package_enclave;
use crate::sgx::utils::{fetch_config_and_mr_enclave, override_envs_and_args_launch_config};
use crate::sgx::AppDeleteResponse;
use crate::utils::{block_on, fetch_config_and_mr_enclave, override_envs_and_args_launch_config};
use crate::utils::block_on;
use crate::{cli_print, SimpleOutput};
use clap::ArgMatches;
use detee_shared::sgx::types::brain::AppDeployConfig;

@ -7,7 +7,8 @@ use detee_shared::sgx::types::brain::AppDeployConfig;
use tokio_stream::StreamExt;
use crate::config::Config;
use crate::utils::{self, calculate_nanolp_for_app, sign_request};
use crate::sgx::utils::calculate_nanolp_for_app;
use crate::utils::{self, sign_request};
#[derive(thiserror::Error, Debug)]
pub enum Error {

@ -12,7 +12,8 @@ use detee_shared::sgx::{
types::dtpm::DtpmConfig,
};
use crate::{config::Config, utils::hratls_url_and_mr_enclave_from_app_id};
use crate::config::Config;
use crate::sgx::utils::hratls_url_and_mr_enclave_from_app_id;
#[derive(thiserror::Error, Debug)]
pub enum Error {

@ -16,6 +16,7 @@ pub mod config;
pub mod grpc_brain;
pub mod grpc_dtpm;
pub mod packaging;
pub mod utils;
#[derive(Tabled, Debug, Serialize, Deserialize)]
pub struct AppContract {

129
src/sgx/utils.rs Normal file

@ -0,0 +1,129 @@
use crate::constants::HRATLS_APP_PORT;
use crate::sgx::grpc_brain::list_apps;
use detee_shared::sgx::types::dtpm::DtpmConfig;
use detee_shared::sgx::types::dtpm::EnvironmentEntry;
use serde::{Deserialize, Serialize};
#[derive(thiserror::Error, Debug)]
pub enum Error {
#[error(transparent)]
Reqwest(#[from] reqwest::Error),
#[error(transparent)]
Serde(#[from] serde_yaml::Error),
#[error("{0}")]
PublicPackage(std::string::String),
}
pub async fn hratls_url_and_mr_enclave_from_app_id(app_id: &str) -> (String, Option<[u8; 32]>) {
let app_contracts = list_apps().await.expect("Could not get App contracts");
let app_contract = app_contracts.iter().find(|contract| contract.uuid == app_id);
if app_contract.is_none() {
eprintln!("Could not find App contract with ID: {}", app_id);
std::process::exit(1);
}
let app_contract = app_contract.unwrap();
let mr_enclave = app_contract
.public_package_mr_enclave
.clone()
.filter(|vec| vec.len() == 32)
.and_then(|vec| vec.try_into().ok());
let public_ip = app_contract.public_ipv4.clone();
let dtpm_port = app_contract
.mapped_ports
.iter()
.find(|port| port.app_port == HRATLS_APP_PORT)
.unwrap()
.host_port;
(format!("https://{public_ip}:{dtpm_port}"), mr_enclave)
}
#[derive(Serialize, Deserialize, Debug)]
struct PublicIndex {
packages: Vec<PackageElement>,
}
#[derive(Serialize, Deserialize, Debug)]
struct PackageElement {
package_url: String,
launch_config_url: String,
mr_enclave: [u8; 32],
}
pub async fn fetch_config_and_mr_enclave(
package_url: &str,
) -> Result<([u8; 32], DtpmConfig), Error> {
let public_packages_index =
reqwest::get("https://registry.detee.ltd/sgx/public_packages_index.yaml")
.await?
.text()
.await?;
let index = serde_yaml::from_str::<PublicIndex>(&public_packages_index)?;
let index_package_entry =
index.packages.iter().find(|package| package.package_url == package_url).ok_or(
Error::PublicPackage("mr_enclave not found for this public package".to_string()),
)?;
let PackageElement { launch_config_url, mr_enclave, .. } = index_package_entry;
let launch_config_str = reqwest::get(launch_config_url).await?.text().await?;
let launch_config = serde_yaml::from_str::<DtpmConfig>(&launch_config_str)?;
Ok((*mr_enclave, launch_config))
}
pub fn calculate_nanolp_for_app(
vcpus: u32,
memory_mb: u32,
disk_size_mb: u32,
hours: u64,
node_price: u64,
) -> u64 {
// this calculation needs to match the calculation of the network
let total_units =
(vcpus as f64 * 5f64) + (memory_mb as f64 / 200f64) + (disk_size_mb as f64 / 10000f64);
let locked_nano = (hours as f64 * 60f64 * total_units * node_price as f64) as u64;
println!(
"Node price: {}/unit/minute. Total Units for hardware requested: {:.4}. Locking {} LP (offering the App for {} hours).",
node_price as f64 / 1_000_000_000.0,
total_units,
locked_nano as f64 / 1_000_000_000.0,
hours
);
locked_nano
}
pub fn override_envs_and_args_launch_config(
launch_config: &mut DtpmConfig,
envs: Vec<String>,
args: Vec<String>,
) {
for env in envs {
let mut env = env.split("=");
let key = env.next().expect("environment variable must be in the format 'key=value'");
let value =
env.next().expect("environment variable pair must be in the format 'key=value'");
if launch_config.environments.iter().find(|env| env.name == key).is_some() {
let existing_env =
launch_config.environments.iter_mut().find(|env| env.name == key).unwrap();
existing_env.name = key.to_string();
existing_env.value = value.to_string();
} else {
let mut new_env = EnvironmentEntry::default();
new_env.name = key.to_string();
new_env.value = value.to_string();
launch_config.environments.push(new_env);
}
}
for arg in args {
launch_config.child_processes.first_mut().unwrap().arguments.push(arg);
}
}

@ -1,9 +1,4 @@
use crate::config::Config;
use crate::constants::HRATLS_APP_PORT;
use crate::sgx::grpc_brain::list_apps;
use detee_shared::sgx::types::dtpm::DtpmConfig;
use detee_shared::sgx::types::dtpm::EnvironmentEntry;
use serde::{Deserialize, Serialize};
use tonic::metadata::errors::InvalidMetadataValue;
use tonic::metadata::AsciiMetadataValue;
use tonic::Request;
@ -14,12 +9,6 @@ pub enum Error {
ConfigError(#[from] crate::config::Error),
#[error(transparent)]
InternalError(#[from] InvalidMetadataValue),
#[error(transparent)]
Reqwest(#[from] reqwest::Error),
#[error(transparent)]
Serde(#[from] serde_yaml::Error),
#[error("{0}")]
PublicPackage(std::string::String),
}
pub fn block_on<F>(future: F) -> F::Output
@ -42,117 +31,3 @@ pub fn sign_request<T: std::fmt::Debug>(req: T) -> Result<Request<T>, Error> {
req.metadata_mut().insert("request-signature", signature);
Ok(req)
}
pub async fn hratls_url_and_mr_enclave_from_app_id(app_id: &str) -> (String, Option<[u8; 32]>) {
let app_contracts = list_apps().await.expect("Could not get App contracts");
let app_contract = app_contracts.iter().find(|contract| contract.uuid == app_id);
if app_contract.is_none() {
eprintln!("Could not find App contract with ID: {}", app_id);
std::process::exit(1);
}
let app_contract = app_contract.unwrap();
let mr_enclave = app_contract
.public_package_mr_enclave
.clone()
.filter(|vec| vec.len() == 32)
.and_then(|vec| vec.try_into().ok());
let public_ip = app_contract.public_ipv4.clone();
let dtpm_port = app_contract
.mapped_ports
.iter()
.find(|port| port.app_port == HRATLS_APP_PORT)
.unwrap()
.host_port;
(format!("https://{public_ip}:{dtpm_port}"), mr_enclave)
}
#[derive(Serialize, Deserialize, Debug)]
struct PublicIndex {
packages: Vec<PackageElement>,
}
#[derive(Serialize, Deserialize, Debug)]
struct PackageElement {
package_url: String,
launch_config_url: String,
mr_enclave: [u8; 32],
}
pub async fn fetch_config_and_mr_enclave(
package_url: &str,
) -> Result<([u8; 32], DtpmConfig), Error> {
let public_packages_index =
reqwest::get("https://registry.detee.ltd/sgx/public_packages_index.yaml")
.await?
.text()
.await?;
let index = serde_yaml::from_str::<PublicIndex>(&public_packages_index)?;
let index_package_entry =
index.packages.iter().find(|package| package.package_url == package_url).ok_or(
Error::PublicPackage("mr_enclave not found for this public package".to_string()),
)?;
let PackageElement { launch_config_url, mr_enclave, .. } = index_package_entry;
let launch_config_str = reqwest::get(launch_config_url).await?.text().await?;
let launch_config = serde_yaml::from_str::<DtpmConfig>(&launch_config_str)?;
Ok((*mr_enclave, launch_config))
}
pub fn calculate_nanolp_for_app(
vcpus: u32,
memory_mb: u32,
disk_size_mb: u32,
hours: u64,
node_price: u64,
) -> u64 {
// this calculation needs to match the calculation of the network
let total_units =
(vcpus as f64 * 5f64) + (memory_mb as f64 / 200f64) + (disk_size_mb as f64 / 10000f64);
let locked_nano = (hours as f64 * 60f64 * total_units * node_price as f64) as u64;
println!(
"Node price: {}/unit/minute. Total Units for hardware requested: {:.4}. Locking {} LP (offering the App for {} hours).",
node_price as f64 / 1_000_000_000.0,
total_units,
locked_nano as f64 / 1_000_000_000.0,
hours
);
locked_nano
}
pub fn override_envs_and_args_launch_config(
launch_config: &mut DtpmConfig,
envs: Vec<String>,
args: Vec<String>,
) {
for env in envs {
let mut env = env.split("=");
let key = env.next().expect("environment variable must be in the format 'key=value'");
let value =
env.next().expect("environment variable pair must be in the format 'key=value'");
if launch_config.environments.iter().find(|env| env.name == key).is_some() {
let existing_env =
launch_config.environments.iter_mut().find(|env| env.name == key).unwrap();
existing_env.name = key.to_string();
existing_env.value = value.to_string();
} else {
let mut new_env = EnvironmentEntry::default();
new_env.name = key.to_string();
new_env.value = value.to_string();
launch_config.environments.push(new_env);
}
}
for arg in args {
launch_config.child_processes.first_mut().unwrap().arguments.push(arg);
}
}