diff --git a/src/data.rs b/src/data.rs index 5010a29..c6e76b4 100644 --- a/src/data.rs +++ b/src/data.rs @@ -38,6 +38,9 @@ pub enum Error { ImpossibleError, #[error("You don't have the required permissions for this operation.")] AccessDenied, + + #[error("Could not find contract {0}")] + AppContractNotFound(String), } #[derive(Clone, Default, Serialize, Deserialize, Debug)] @@ -1196,9 +1199,13 @@ impl BrainData { }); } - pub fn find_app_contract_by_uuid(&self, uuid: &str) -> Option { + pub fn find_app_contract_by_uuid(&self, uuid: &str) -> Result { let contracts = self.app_contracts.read().unwrap(); - contracts.iter().find(|c| c.uuid == uuid).cloned() + contracts + .iter() + .find(|c| c.uuid == uuid) + .cloned() + .ok_or(Error::AppContractNotFound(uuid.to_string())) } pub fn find_app_node_by_pubkey(&self, public_key: &str) -> Option { @@ -1349,46 +1356,50 @@ impl BrainData { }) .await; } + } else { + self.send_new_container_resp(NewAppRes { + status: "failed".to_string(), + error: "Daemon is offline.".to_string(), + uuid: req.uuid, + ..Default::default() + }) + .await; } - // TODO: implement daemon offline handling } - pub async fn send_del_container_req( - &self, - req: DelAppReq, - ) -> Result<(), Box> { - if let Some(app_contract) = self.find_app_contract_by_uuid(&req.uuid) { - info!("Found app contract {}. Deleting...", &req.uuid); - if let Some(app_daemon_tx) = self.app_daemon_tx.get(&app_contract.node_pubkey) { - debug!( - "TX for daemon {} found. Informing daemon about deletion of {}.", - app_contract.node_pubkey, &req.uuid - ); - let msg = BrainMessageApp { - msg: Some( - detee_shared::sgx::pb::brain::brain_message_app::Msg::DeleteAppReq( - req.clone(), - ), - ), - }; + pub async fn send_del_container_req(&self, req: DelAppReq) -> Result<(), Error> { + log::debug!("Starting deletion of app {}", req.uuid); + let app_contract = self.find_app_contract_by_uuid(&req.uuid)?; - if let Err(e) = app_daemon_tx.send(msg).await { - warn!( - "Failed to send deletion request to {} due to error: {e:?}", - app_contract.node_pubkey - ); - info!("Deleting daemon TX for {}", app_contract.node_pubkey); - self.del_app_daemon_tx(&app_contract.node_pubkey); - } - } - - let mut app_contracts = self.app_contracts.write().unwrap(); - app_contracts.retain(|c| c.uuid != req.uuid); - - Ok(()) - } else { - Err("Contract not found".into()) + if app_contract.admin_pubkey != req.admin_pubkey { + return Err(Error::AccessDenied); } + + info!("Found app contract {}. Deleting...", &req.uuid); + if let Some(app_daemon_tx) = self.app_daemon_tx.get(&app_contract.node_pubkey) { + debug!( + "TX for daemon {} found. Informing daemon about deletion of {}.", + app_contract.node_pubkey, &req.uuid + ); + let msg = BrainMessageApp { + msg: Some(brain_message_app::Msg::DeleteAppReq(req.clone())), + }; + + if let Err(e) = app_daemon_tx.send(msg).await { + warn!( + "Failed to send deletion request to {} due to error: {e:?}", + app_contract.node_pubkey + ); + info!("Deleting daemon TX for {}", app_contract.node_pubkey); + self.del_app_daemon_tx(&app_contract.node_pubkey); + } + } + + self.add_nano_to_wallet(&app_contract.admin_pubkey, app_contract.locked_nano); + let mut app_contracts = self.app_contracts.write().unwrap(); + app_contracts.retain(|c| c.uuid != req.uuid); + + Ok(()) } pub async fn send_new_container_resp(&self, new_container_resp: NewAppRes) { @@ -1412,9 +1423,18 @@ impl BrainData { } if new_container_resp.error != "" { + if let Some(mut admin_wallet) = self.accounts.get_mut(&new_container_req.0.admin_pubkey) + { + admin_wallet.balance += new_container_req.0.locked_nano; + admin_wallet.tmp_locked -= new_container_req.0.locked_nano; + } return; } + if let Some(mut admin_wallet) = self.accounts.get_mut(&new_container_req.0.admin_pubkey) { + admin_wallet.tmp_locked -= new_container_req.0.locked_nano; + } + let requested_resource = new_container_req.0.resource.clone().unwrap_or_default(); let app_contracts = AppContract {