From daff2fd533f6ab6cd8207f6005a22ae2e5931c8c Mon Sep 17 00:00:00 2001 From: Noor Date: Thu, 20 Mar 2025 21:33:01 +0530 Subject: [PATCH] fix: tokio block on error replace retry crate with tokio-retry for asynchronous app deployment and config updates change hratls and sign key data to Config refactor mr_signer format to save in config modularized deploy and config update functionality for better code arrangements --- Cargo.lock | 22 ++++++++++++---------- Cargo.toml | 2 +- src/config.rs | 26 ++++++++++++-------------- src/sgx/cli_handler.rs | 22 +++++++--------------- src/sgx/grpc_brain.rs | 2 +- src/sgx/grpc_dtpm.rs | 6 ++++-- src/sgx/packaging.rs | 4 ++-- src/sgx/utils.rs | 31 +++++++++++++++++++++++++++++++ 8 files changed, 70 insertions(+), 45 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1093932..2625a75 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1058,7 +1058,6 @@ dependencies = [ "rand", "rand_core", "reqwest", - "retry", "rustls", "serde", "serde_json", @@ -1066,6 +1065,7 @@ dependencies = [ "tabled", "thiserror 2.0.11", "tokio", + "tokio-retry", "tokio-stream", "tonic", "tonic-build", @@ -2756,15 +2756,6 @@ dependencies = [ "windows-registry", ] -[[package]] -name = "retry" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9166d72162de3575f950507683fac47e30f6f2c3836b71b7fbc61aa517c9c5f4" -dependencies = [ - "rand", -] - [[package]] name = "rfc6979" version = "0.4.0" @@ -3511,6 +3502,17 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-retry" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f57eb36ecbe0fc510036adff84824dd3c24bb781e21bfa67b69d556aa85214f" +dependencies = [ + "pin-project", + "rand", + "tokio", +] + [[package]] name = "tokio-rustls" version = "0.26.1" diff --git a/Cargo.toml b/Cargo.toml index 74c3b8e..e418d84 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,7 +31,7 @@ rustls = "0.23.23" tower = "0.5.2" hyper-rustls = { version = "0.27.5", features = ["http2"] } openssl = { version = "0.10.71", features = ["vendored"] } -retry = "2.0.0" +tokio-retry = "0.3.0" detee-sgx = { git = "ssh://git@gitea.detee.cloud/testnet/detee-sgx.git", branch = "hratls", features=["hratls", "qvl"] } detee-shared = { git = "ssh://git@gitea.detee.cloud/testnet/proto.git", branch = "main" } diff --git a/src/config.rs b/src/config.rs index b5d8a14..7b1d68b 100644 --- a/src/config.rs +++ b/src/config.rs @@ -16,10 +16,6 @@ pub struct AccountData { locked_funds: f64, wallet_address: String, wallet_path: String, - pub hratls_pubkey: String, - pub hratls_path: String, - pub mrsigner: [u8; 32], - pub signing_key_path: String, } impl super::HumanOutput for AccountData { @@ -52,6 +48,10 @@ pub struct Config { default_dtrfs: String, default_kernel: String, brain_url: String, + pub hratls_pubkey: String, + pub hratls_path: String, + pub mrsigner: String, + pub signing_key_path: String, } #[derive(thiserror::Error, Debug)] @@ -191,7 +191,11 @@ impl Config { Err(e) => { debug!("Could not load config due to error: {e}"); eprintln!("Config file not found. Creating new config file!"); - let config = Self::default(); + let mut config = Self::default(); + config.hratls_pubkey = Self::get_hratls_pubkey_hex(); + config.hratls_path = Self::hratls_private_key_path(); + config.mrsigner = Self::get_mr_signer(); + config.signing_key_path = Self::signing_key_path(); if let Err(e) = config.save_to_disk() { log::error!("Could not save config to disk: {e}"); panic!("Could not initialize config."); @@ -336,11 +340,6 @@ impl Config { Err(_) => log::error!("This error should never happen. Please report this bug."), } - account_data.hratls_pubkey = Self::get_hratls_pubkey_hex(); - account_data.hratls_path = Self::hratls_private_key_path(); - account_data.mrsigner = Self::get_mr_signer(); - account_data.signing_key_path = Self::signing_key_path(); - account_data } } @@ -377,7 +376,7 @@ impl Config { } impl Config { - fn get_mr_signer() -> [u8; 32] { + pub fn get_mr_signer() -> String { let mut signing_key_mod = Self::get_signing_key().n().to_vec(); signing_key_mod.reverse(); // make it little endian @@ -389,7 +388,7 @@ impl Config { let mut mr_signer = [0u8; 32]; mr_signer.copy_from_slice(&mr_signer_raw[..32]); - mr_signer + mr_signer.iter().fold(String::new(), |acc, x| acc + &format!("{:02X?}", x)) } fn get_signing_key() -> Rsa { @@ -441,8 +440,7 @@ mod tests { #[test] fn test_mr_signer() { - let mr_signer = - Config::get_mr_signer().iter().fold(String::new(), |acc, x| acc + &format!("{:X?}", x)); + let mr_signer = Config::get_mr_signer(); println!("mr_signer: {mr_signer}",); } } diff --git a/src/sgx/cli_handler.rs b/src/sgx/cli_handler.rs index 3018ebf..9fa0de7 100644 --- a/src/sgx/cli_handler.rs +++ b/src/sgx/cli_handler.rs @@ -1,6 +1,10 @@ +use super::grpc_brain::list_apps; +use super::utils::deploy_new_app_and_update_config; +use super::{get_app_node, AppContract, AppDeployResponse}; + use crate::name_generator::random_app_name; use crate::sgx::config::{validate_yaml, DeteeCliExt}; -use crate::sgx::grpc_brain::{delete_app, new_app}; +use crate::sgx::grpc_brain::delete_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}; @@ -10,11 +14,6 @@ use crate::{cli_print, SimpleOutput}; use clap::ArgMatches; use detee_shared::sgx::types::brain::AppDeployConfig; use detee_shared::sgx::types::brain::Resource; -use retry::delay::Fixed; -use retry::retry; - -use super::grpc_brain::list_apps; -use super::{get_app_node, AppContract, AppDeployResponse}; pub fn handle_app(app_matche: &ArgMatches) { match app_matche.subcommand() { @@ -104,15 +103,8 @@ fn handle_deploy( override_envs_and_args_launch_config(&mut launch_config, envs, args); - match block_on(new_app(app_deploy_config)) { - Ok(new_app_res) if new_app_res.error == "" => { - println!("Deploying..."); - std::thread::sleep(std::time::Duration::from_millis(3100)); - retry(Fixed::from_millis(500).take(4), || { - block_on(attest_and_send_config(launch_config.clone(), &new_app_res.uuid)) - })?; - Ok(new_app_res.into()) - } + match block_on(deploy_new_app_and_update_config(app_deploy_config, launch_config)) { + Ok(new_app_res) if new_app_res.error == "" => Ok(new_app_res.into()), Ok(new_app_res) => Err(Box::new(std::io::Error::other(new_app_res.error))), Err(e) => Err(Box::new(e)), } diff --git a/src/sgx/grpc_brain.rs b/src/sgx/grpc_brain.rs index 5e681a5..d26a3bd 100644 --- a/src/sgx/grpc_brain.rs +++ b/src/sgx/grpc_brain.rs @@ -39,7 +39,7 @@ pub async fn new_app(app_deploy_config: AppDeployConfig) -> Result { req.uuid = "".to_string(); req.locked_nano = locked_nano; req.admin_pubkey = Config::get_detee_wallet().expect("No wallet found"); - req.hratls_pubkey = Config::get_hratls_pubkey_hex(); + req.hratls_pubkey = Config::init_config().hratls_pubkey; let mut daemon_serivce = BrainAppCliClient::connect(Config::get_brain_url()).await?; let res = daemon_serivce.deploy_app(sign_request(req)?).await?; diff --git a/src/sgx/grpc_dtpm.rs b/src/sgx/grpc_dtpm.rs index 6dda8ed..eae3d56 100644 --- a/src/sgx/grpc_dtpm.rs +++ b/src/sgx/grpc_dtpm.rs @@ -38,13 +38,15 @@ pub async fn connect_dtpm_grpc_client( package_mr_enclave: Option<[u8; 32]>, ) -> Result> { let private_key_pem = Config::get_hratls_private_key(); - let mr_signer = vec![Config::get_account_data().mrsigner]; + let mut mr_signer = [0u8; 32]; + hex::decode_to_slice(Config::init_config().mrsigner, &mut mr_signer)?; + let mr_signers = vec![mr_signer]; let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); let hratls_config = Arc::new(RwLock::new( HRaTlsConfig::new() - .allow_instance_measurement(InstanceMeasurement::new().with_mrsigners(mr_signer)) + .allow_instance_measurement(InstanceMeasurement::new().with_mrsigners(mr_signers)) .with_hratls_private_key_pem(private_key_pem), )); diff --git a/src/sgx/packaging.rs b/src/sgx/packaging.rs index 611e85f..c0011d2 100644 --- a/src/sgx/packaging.rs +++ b/src/sgx/packaging.rs @@ -11,8 +11,8 @@ pub fn package_enclave( .collect::>() .join(" "); - let signing_key_path = Config::get_account_data().signing_key_path; - let hratls_key_path = Config::get_account_data().hratls_path; + let signing_key_path = Config::init_config().signing_key_path; + let hratls_key_path = Config::init_config().hratls_path; let docker_package_str = if package_type == "public" { format!( diff --git a/src/sgx/utils.rs b/src/sgx/utils.rs index dc400c3..75a901e 100644 --- a/src/sgx/utils.rs +++ b/src/sgx/utils.rs @@ -1,8 +1,14 @@ +use super::grpc_brain::new_app; use crate::constants::HRATLS_APP_PORT; use crate::sgx::grpc_brain::list_apps; +use crate::sgx::grpc_dtpm::attest_and_send_config; +use detee_shared::app_proto::NewAppRes; +use detee_shared::sgx::types::brain::AppDeployConfig; use detee_shared::sgx::types::dtpm::DtpmConfig; use detee_shared::sgx::types::dtpm::EnvironmentEntry; use serde::{Deserialize, Serialize}; +use tokio_retry::strategy::FixedInterval; +use tokio_retry::Retry; #[derive(thiserror::Error, Debug)] pub enum Error { @@ -12,6 +18,12 @@ pub enum Error { Serde(#[from] serde_yaml::Error), #[error("{0}")] PublicPackage(std::string::String), + #[error("{0}")] + Brain(#[from] crate::sgx::grpc_brain::Error), + #[error("{0}")] + Dtpm(#[from] crate::sgx::grpc_dtpm::Error), + #[error("{0}")] + Deployment(String), } pub async fn hratls_url_and_mr_enclave_from_app_id(app_id: &str) -> (String, Option<[u8; 32]>) { @@ -127,3 +139,22 @@ pub fn override_envs_and_args_launch_config( launch_config.child_processes.first_mut().unwrap().arguments.push(arg); } } + +pub async fn deploy_new_app_and_update_config( + app_deploy_config: AppDeployConfig, + launch_config: DtpmConfig, +) -> Result { + let new_app_res = new_app(app_deploy_config).await?; + if new_app_res.error == "" { + println!("Deploying..."); + tokio::time::sleep(tokio::time::Duration::from_millis(3100)).await; + Retry::spawn(FixedInterval::from_millis(500).take(5), || { + log::debug!("retrying attestation and launch config update"); + attest_and_send_config(launch_config.clone(), &new_app_res.uuid) + }) + .await?; + Ok(new_app_res.into()) + } else { + Err(Error::Deployment(new_app_res.error)) + } +}