feat: report app node

include contract id in report schema
validated app contract also while reporting
This commit is contained in:
Noor 2025-05-05 13:30:16 +05:30
parent 28ff8dcd81
commit a1664d61e4
Signed by: noormohammedb
GPG Key ID: D83EFB8B3B967146
4 changed files with 59 additions and 11 deletions

@ -131,3 +131,4 @@ DEFINE FIELD contract ON TABLE kick TYPE record<deleted_vm|deleted_app>;
DEFINE TABLE report TYPE RELATION FROM account TO vm_node|app_node; DEFINE TABLE report TYPE RELATION FROM account TO vm_node|app_node;
DEFINE FIELD created_at ON TABLE report TYPE datetime; DEFINE FIELD created_at ON TABLE report TYPE datetime;
DEFINE FIELD reason ON TABLE report TYPE string; DEFINE FIELD reason ON TABLE report TYPE string;
DEFINE FIELD contract_id ON TABLE report TYPE string;

@ -20,6 +20,8 @@ pub const UPDATE_VM_REQ: &str = "update_vm_req";
pub const DELETED_VM: &str = "deleted_vm"; pub const DELETED_VM: &str = "deleted_vm";
pub const VM_CONTRACT: &str = "vm_contract"; pub const VM_CONTRACT: &str = "vm_contract";
pub const ACTIVE_APP: &str = "active_app";
pub const ID_ALPHABET: [char; 62] = [ 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', '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', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B',

@ -1,8 +1,8 @@
use std::str::FromStr; use std::str::FromStr;
pub use crate::constants::{ pub use crate::constants::{
ACCOUNT, ACTIVE_VM, DB_SCHEMA_FILE, DELETED_VM, ID_ALPHABET, NEW_VM_REQ, UPDATE_VM_REQ, ACCOUNT, ACTIVE_APP, ACTIVE_VM, DB_SCHEMA_FILE, DELETED_VM, ID_ALPHABET, NEW_VM_REQ,
VM_CONTRACT, VM_NODE, UPDATE_VM_REQ, VM_CONTRACT, VM_NODE,
}; };
use crate::old_brain; use crate::old_brain;
@ -720,7 +720,7 @@ pub struct AppNodeWithReports {
} }
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
pub struct AppContract { pub struct ActiveApp {
id: RecordId, id: RecordId,
#[serde(rename = "in")] #[serde(rename = "in")]
admin: RecordId, admin: RecordId,
@ -741,6 +741,36 @@ pub struct AppContract {
hratls_pubkey: String, 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<Client>, uuid: &str) -> Result<Option<Self>, Error> {
let contract: Option<Self> =
db.query(format!("select * from {ACTIVE_APP}:{uuid} fetch out;")).await?.take(0)?;
Ok(contract)
}
}
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
pub struct Ban { pub struct Ban {
id: RecordId, id: RecordId,
@ -771,6 +801,7 @@ pub struct Report {
to_node: RecordId, to_node: RecordId,
created_at: Datetime, created_at: Datetime,
pub reason: String, pub reason: String,
pub contract_id: String,
} }
impl Report { impl Report {
@ -780,10 +811,17 @@ impl Report {
from_account: RecordId, from_account: RecordId,
to_node: RecordId, to_node: RecordId,
reason: String, reason: String,
contract_id: String,
) -> Result<(), Error> { ) -> Result<(), Error> {
let _: Vec<Self> = db let _: Vec<Self> = db
.insert("report") .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?; .await?;
Ok(()) Ok(())
} }

@ -436,20 +436,27 @@ impl BrainGeneralCli for BrainGeneralCliForReal {
async fn report_node(&self, req: Request<ReportNodeReq>) -> Result<Response<Empty>, Status> { async fn report_node(&self, req: Request<ReportNodeReq>) -> Result<Response<Empty>, Status> {
let req = check_sig_from_req(req)?; 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? { match db::ActiveVmWithNode::get_by_uuid(&self.db, &req.contract).await? {
Some(vm_contract) Some(vm_contract)
if vm_contract.admin.key().to_string() == req.admin_pubkey if vm_contract.admin.key().to_string() == req.admin_pubkey
&& vm_contract.vm_node.id.key().to_string() == req.node_pubkey => && vm_contract.vm_node.id.key().to_string() == req.node_pubkey =>
{ {
(vm_contract.admin, vm_contract.vm_node.id) (vm_contract.admin, vm_contract.vm_node.id, vm_contract.id.to_string())
}
_ => {
// TODO: Hey, Noor! Please add app contract here.
return Err(Status::unauthenticated("No contract found by this ID."));
} }
_ => 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 {})) Ok(Response::new(Empty {}))
} }