From 4d17ba666726e2e75674f7860c2652b2d4885639 Mon Sep 17 00:00:00 2001 From: Noor Date: Thu, 20 Mar 2025 16:51:38 +0530 Subject: [PATCH] feat: move sgx utility functions to sgx/utils module for better organization --- src/sgx/cli_handler.rs | 3 +- src/sgx/grpc_brain.rs | 3 +- src/sgx/grpc_dtpm.rs | 3 +- src/sgx/mod.rs | 1 + src/sgx/utils.rs | 129 +++++++++++++++++++++++++++++++++++++++++ src/utils.rs | 125 --------------------------------------- 6 files changed, 136 insertions(+), 128 deletions(-) create mode 100644 src/sgx/utils.rs diff --git a/src/sgx/cli_handler.rs b/src/sgx/cli_handler.rs index a7cccdf..3018ebf 100644 --- a/src/sgx/cli_handler.rs +++ b/src/sgx/cli_handler.rs @@ -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; diff --git a/src/sgx/grpc_brain.rs b/src/sgx/grpc_brain.rs index 3b6674b..5e681a5 100644 --- a/src/sgx/grpc_brain.rs +++ b/src/sgx/grpc_brain.rs @@ -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 { diff --git a/src/sgx/grpc_dtpm.rs b/src/sgx/grpc_dtpm.rs index 10e70a0..6dda8ed 100644 --- a/src/sgx/grpc_dtpm.rs +++ b/src/sgx/grpc_dtpm.rs @@ -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 { diff --git a/src/sgx/mod.rs b/src/sgx/mod.rs index a6cf8f4..127bcaf 100644 --- a/src/sgx/mod.rs +++ b/src/sgx/mod.rs @@ -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 { diff --git a/src/sgx/utils.rs b/src/sgx/utils.rs new file mode 100644 index 0000000..dc400c3 --- /dev/null +++ b/src/sgx/utils.rs @@ -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, +} +#[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::(&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::(&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, + args: Vec, +) { + 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); + } +} diff --git a/src/utils.rs b/src/utils.rs index 935d516..2ebc32d 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -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(future: F) -> F::Output @@ -42,117 +31,3 @@ pub fn sign_request(req: T) -> Result, 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, -} -#[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::(&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::(&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, - args: Vec, -) { - 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); - } -}