From a1664d61e4f7885cd2e878eda20334f2d83ba45b Mon Sep 17 00:00:00 2001 From: Noor Date: Mon, 5 May 2025 13:30:16 +0530 Subject: [PATCH] feat: report app node include contract id in report schema validated app contract also while reporting --- interim_tables.surql | 1 + src/constants.rs | 2 ++ src/db.rs | 46 ++++++++++++++++++++++++++++++++++++++++---- src/grpc.rs | 21 +++++++++++++------- 4 files changed, 59 insertions(+), 11 deletions(-) diff --git a/interim_tables.surql b/interim_tables.surql index 54a302e..8911c34 100644 --- a/interim_tables.surql +++ b/interim_tables.surql @@ -131,3 +131,4 @@ DEFINE FIELD contract ON TABLE kick TYPE record; DEFINE TABLE report TYPE RELATION FROM account TO vm_node|app_node; DEFINE FIELD created_at ON TABLE report TYPE datetime; DEFINE FIELD reason ON TABLE report TYPE string; +DEFINE FIELD contract_id ON TABLE report TYPE string; diff --git a/src/constants.rs b/src/constants.rs index 5e1f03a..c505d60 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -20,6 +20,8 @@ pub const UPDATE_VM_REQ: &str = "update_vm_req"; pub const DELETED_VM: &str = "deleted_vm"; pub const VM_CONTRACT: &str = "vm_contract"; +pub const ACTIVE_APP: &str = "active_app"; + pub const ID_ALPHABET: [char; 62] = [ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', diff --git a/src/db.rs b/src/db.rs index e59cf6b..995ded9 100644 --- a/src/db.rs +++ b/src/db.rs @@ -1,8 +1,8 @@ use std::str::FromStr; pub use crate::constants::{ - ACCOUNT, ACTIVE_VM, DB_SCHEMA_FILE, DELETED_VM, ID_ALPHABET, NEW_VM_REQ, UPDATE_VM_REQ, - VM_CONTRACT, VM_NODE, + ACCOUNT, ACTIVE_APP, ACTIVE_VM, DB_SCHEMA_FILE, DELETED_VM, ID_ALPHABET, NEW_VM_REQ, + UPDATE_VM_REQ, VM_CONTRACT, VM_NODE, }; use crate::old_brain; @@ -720,7 +720,7 @@ pub struct AppNodeWithReports { } #[derive(Debug, Serialize, Deserialize)] -pub struct AppContract { +pub struct ActiveApp { id: RecordId, #[serde(rename = "in")] admin: RecordId, @@ -741,6 +741,36 @@ pub struct AppContract { hratls_pubkey: String, } +#[derive(Debug, Serialize, Deserialize)] +pub struct ActiveAppWithNode { + pub id: RecordId, + #[serde(rename = "in")] + pub admin: RecordId, + #[serde(rename = "out")] + pub app_node: AppNode, + pub app_name: String, + pub mapped_ports: Vec<(u64, u64)>, + pub host_ipv4: String, + pub vcpus: u64, + pub memory_mb: u64, + pub disk_size_gb: u64, + pub created_at: Datetime, + pub price_per_unit: u64, + pub locked_nano: u64, + pub collected_at: Datetime, + pub mr_enclave: String, + pub package_url: String, + pub hratls_pubkey: String, +} + +impl ActiveAppWithNode { + pub async fn get_by_uuid(db: &Surreal, uuid: &str) -> Result, Error> { + let contract: Option = + db.query(format!("select * from {ACTIVE_APP}:{uuid} fetch out;")).await?.take(0)?; + Ok(contract) + } +} + #[derive(Debug, Serialize, Deserialize)] pub struct Ban { id: RecordId, @@ -771,6 +801,7 @@ pub struct Report { to_node: RecordId, created_at: Datetime, pub reason: String, + pub contract_id: String, } impl Report { @@ -780,10 +811,17 @@ impl Report { from_account: RecordId, to_node: RecordId, reason: String, + contract_id: String, ) -> Result<(), Error> { let _: Vec = db .insert("report") - .relation(Report { from_account, to_node, created_at: Datetime::default(), reason }) + .relation(Report { + from_account, + to_node, + created_at: Datetime::default(), + reason, + contract_id, + }) .await?; Ok(()) } diff --git a/src/grpc.rs b/src/grpc.rs index 7209182..0877ea8 100644 --- a/src/grpc.rs +++ b/src/grpc.rs @@ -436,20 +436,27 @@ impl BrainGeneralCli for BrainGeneralCliForReal { async fn report_node(&self, req: Request) -> Result, Status> { let req = check_sig_from_req(req)?; - let (account, node) = + let (account, node, contract_id) = match db::ActiveVmWithNode::get_by_uuid(&self.db, &req.contract).await? { Some(vm_contract) if vm_contract.admin.key().to_string() == req.admin_pubkey && vm_contract.vm_node.id.key().to_string() == req.node_pubkey => { - (vm_contract.admin, vm_contract.vm_node.id) - } - _ => { - // TODO: Hey, Noor! Please add app contract here. - return Err(Status::unauthenticated("No contract found by this ID.")); + (vm_contract.admin, vm_contract.vm_node.id, vm_contract.id.to_string()) } + _ => match db::ActiveAppWithNode::get_by_uuid(&self.db, &req.contract).await? { + Some(app_contract) + if app_contract.admin.key().to_string() == req.admin_pubkey + && app_contract.app_node.id.key().to_string() == req.node_pubkey => + { + (app_contract.admin, app_contract.app_node.id, app_contract.id.to_string()) + } + _ => { + return Err(Status::unauthenticated("No contract found by this ID.")); + } + }, }; - db::Report::create(&self.db, account, node, req.reason).await?; + db::Report::create(&self.db, account, node, req.reason, contract_id).await?; Ok(Response::new(Empty {})) }