Merge branch 'app_payment' into credits_app

This commit is contained in:
Noor 2025-07-01 12:23:05 +05:30
commit 2fe8d38156
Signed by: noormohammedb
GPG Key ID: D83EFB8B3B967146
4 changed files with 54 additions and 7 deletions

@ -30,7 +30,8 @@ pub struct AppNode {
pub avail_ports: u32, pub avail_ports: u32,
pub max_ports_per_app: u32, pub max_ports_per_app: u32,
pub price: u64, pub price: u64,
pub offline_minutes: u64, pub connected_at: Datetime,
pub disconnected_at: Datetime,
} }
impl AppNode { impl AppNode {
@ -40,6 +41,18 @@ impl AppNode {
let app_node: Option<AppNode> = db.upsert(app_node_id.clone()).content(self).await?; let app_node: Option<AppNode> = db.upsert(app_node_id.clone()).content(self).await?;
app_node.ok_or(Error::FailedToCreateDBEntry(format!("{APP_NODE}:{app_node_id}"))) app_node.ok_or(Error::FailedToCreateDBEntry(format!("{APP_NODE}:{app_node_id}")))
} }
pub async fn set_online(db: &Surreal<Client>, app_node_id: &str) -> Result<(), Error> {
db.query(format!("UPDATE {APP_NODE}:{app_node_id} SET connected_at = time::now();"))
.await?;
Ok(())
}
pub async fn set_offline(db: &Surreal<Client>, app_node_id: &str) -> Result<(), Error> {
db.query(format!("UPDATE {APP_NODE}:{app_node_id} SET disconnected_at = time::now();"))
.await?;
Ok(())
}
} }
pub enum AppDaemonMsg { pub enum AppDaemonMsg {
@ -217,7 +230,6 @@ pub struct AppNodeWithReports {
pub avail_ports: u32, pub avail_ports: u32,
pub max_ports_per_app: u32, pub max_ports_per_app: u32,
pub price: u64, pub price: u64,
pub offline_minutes: u64,
pub reports: Vec<Report>, pub reports: Vec<Report>,
} }
@ -255,6 +267,8 @@ impl AppNodeWithReports {
filter_query += &format!("&& ip = '{}' ", filters.ip); filter_query += &format!("&& ip = '{}' ", filters.ip);
} }
filter_query += " && connected_at > disconnected_at ";
if limit_one { if limit_one {
filter_query += "limit 1"; filter_query += "limit 1";
} }
@ -624,7 +638,8 @@ impl From<&old_brain::BrainData> for Vec<AppNode> {
avail_ports: old_node.avail_no_of_port, avail_ports: old_node.avail_no_of_port,
max_ports_per_app: old_node.max_ports_per_app, max_ports_per_app: old_node.max_ports_per_app,
price: old_node.price, price: old_node.price,
offline_minutes: old_node.offline_minutes, disconnected_at: Datetime::default(),
connected_at: Datetime::default(),
}); });
} }
nodes nodes

@ -56,7 +56,8 @@ impl BrainAppDaemon for AppDaemonServer {
avail_storage_mib: 0, avail_storage_mib: 0,
avail_ports: 0, avail_ports: 0,
max_ports_per_app: 0, max_ports_per_app: 0,
offline_minutes: 0, disconnected_at: surrealdb::sql::Datetime::default(),
connected_at: surrealdb::sql::Datetime::default(),
}; };
app_node.register(&self.db).await?; app_node.register(&self.db).await?;
@ -88,6 +89,7 @@ impl BrainAppDaemon for AppDaemonServer {
)?; )?;
info!("App Daemon {} connected to receive brain messages", pubkey); info!("App Daemon {} connected to receive brain messages", pubkey);
let _ = db::AppNode::set_online(&self.db, &pubkey).await;
let (tx, rx) = mpsc::channel(6); let (tx, rx) = mpsc::channel(6);
{ {
@ -161,7 +163,8 @@ impl BrainAppDaemon for AppDaemonServer {
}, },
Err(e) => { Err(e) => {
log::warn!("App Daemon Disconnected: {e:?}") log::warn!("App Daemon Disconnected: {e:?}");
let _ = db::AppNode::set_offline(&self.db, &pubkey).await;
} }
} }
} }

@ -94,7 +94,8 @@ DEFINE FIELD avail_storage_mib ON TABLE app_node TYPE int;
DEFINE FIELD avail_ports ON TABLE app_node TYPE int; DEFINE FIELD avail_ports ON TABLE app_node TYPE int;
DEFINE FIELD max_ports_per_app ON TABLE app_node TYPE int; DEFINE FIELD max_ports_per_app ON TABLE app_node TYPE int;
DEFINE FIELD price ON TABLE app_node TYPE int; DEFINE FIELD price ON TABLE app_node TYPE int;
DEFINE FIELD offline_minutes ON TABLE app_node TYPE int; DEFINE FIELD connected_at ON TABLE app_node TYPE datetime;
DEFINE FIELD disconnected_at ON TABLE app_node TYPE datetime;
DEFINE TABLE new_app_req Type RELATION FROM account to app_node SCHEMAFULL; DEFINE TABLE new_app_req Type RELATION FROM account to app_node SCHEMAFULL;
DEFINE FIELD app_name ON TABLE new_app_req TYPE string; DEFINE FIELD app_name ON TABLE new_app_req TYPE string;

@ -31,4 +31,32 @@ FOR $contract IN (select * from active_vm fetch out) {
}; };
}; };
-- TODO: implement for active_app FOR $app_contract IN (select * from active_app fetch out) {
LET $operator = (select * from $app_contract.out.operator)[0];
LET $node_is_online = $app_contract.out.connected_at > $app_contract.out.disconnected_at;
LET $price_per_minute = fn::app_price_per_minute($app_contract.id);
LET $amount_due = (time::now() - $app_contract.collected_at).mins() * $price_per_minute;
LET $amount_paid = IF $amount_due > $app_contract.locked_nano {
$app_contract.locked_nano
} ELSE {
$amount_due
};
LET $escrow_multiplier = IF $operator.escrow < 5_000_000_000_000 { 1 } ELSE { 5 };
IF $node_is_online {
UPDATE $operator.id SET balance += $amount_paid * $escrow_multiplier;
UPDATE $app_contract.id SET
locked_nano -= $amount_paid,
collected_at = time::now();
} ELSE {
LET $compensation = IF $amount_due > $operator.escrow {
$operator.escrow
} ELSE {
$amount_due
};
UPDATE $operator.id SET escrow -= $compensation;
UPDATE $app_contract.in SET balance += $compensation;
};
IF $amount_paid >= $app_contract.locked_nano {
fn::delete_app($app_contract.id);
}
}