Compare commits

..

No commits in common. "10d0b7b06470dae669de51a0cb8f01e2f4f37cae" and "fa700c2315a498c37351d61dd1263b7906c24570" have entirely different histories.

2 changed files with 26 additions and 97 deletions

@ -40,16 +40,13 @@ pub enum Error {
#[error("Could not find contract {0}")]
AppContractNotFound(String),
#[error("Could not find contract {0}")]
ContractNotFound(String),
}
#[derive(Clone, Default, Serialize, Deserialize, Debug)]
pub struct AccountData {
pub balance: u64,
pub tmp_locked: u64,
// holds reasons why Contracts of this account got kicked
// holds reasons why VMs of this account got kicked
pub kicked_for: Vec<String>,
pub last_kick: chrono::DateTime<Utc>,
// holds accounts that banned this account
@ -250,7 +247,7 @@ impl From<AppContract> for AppContractPB {
}
}
#[derive(Eq, PartialEq, Clone, Debug, Default, Serialize, Deserialize)]
#[derive(Eq, Hash, PartialEq, Clone, Debug, Default, Serialize, Deserialize)]
pub struct AppNode {
pub node_pubkey: String,
pub operator_wallet: String,
@ -265,8 +262,7 @@ pub struct AppNode {
pub max_ports_per_app: u32,
// nanotokens per unit per minute
pub price: u64,
// 1st String is user wallet and 2nd String is report message
pub reports: HashMap<String, String>,
pub offline_minutes: u64,
}
@ -280,7 +276,7 @@ impl From<AppNode> for AppNodeListResp {
city: value.city,
ip: value.ip,
price: value.price,
reports: value.reports.into_values().collect(),
reports: Vec::new(),
}
}
}
@ -510,6 +506,7 @@ impl BrainData {
nodes.push(node);
}
// todo: this should also support Apps
/// Receives: operator, contract uuid, reason of kick
pub async fn kick_contract(
&self,
@ -518,48 +515,17 @@ impl BrainData {
reason: &str,
) -> Result<u64, Error> {
log::debug!("Operator {operator} requested a kick of {uuid} for reason: {reason}");
let (admin_pubkey, node_pubkey, updated_at, price_per_mint, is_vm) =
match self.find_any_contract_by_uuid(uuid) {
Ok((Some(vm), _)) => {
let price_per_mint = vm.price_per_minute();
(
vm.admin_pubkey,
vm.node_pubkey,
vm.updated_at,
price_per_mint,
true,
)
}
Ok((_, Some(app))) => {
let price_per_mint = app.price_per_minute();
(
app.admin_pubkey,
app.node_pubkey,
app.updated_at,
price_per_mint,
false,
)
}
_ => {
log::error!("Could not find contract {uuid}");
return Err(Error::ContractNotFound(uuid.to_string()));
}
};
let contract = self.find_contract_by_uuid(uuid)?;
let mut operator_data = self
.operators
.get_mut(operator)
.ok_or(Error::AccessDenied)?;
if !(operator_data.vm_nodes.contains(&node_pubkey)
|| operator_data.app_nodes.contains(&node_pubkey))
{
if !operator_data.vm_nodes.contains(&contract.node_pubkey) {
return Err(Error::AccessDenied);
}
let mut minutes_to_refund = chrono::Utc::now()
.signed_duration_since(updated_at)
.signed_duration_since(contract.updated_at)
.num_minutes()
.abs() as u64;
// cap refund at 1 week
@ -567,10 +533,10 @@ impl BrainData {
minutes_to_refund = 10080;
}
let mut refund_amount = minutes_to_refund * price_per_mint;
let mut refund_amount = minutes_to_refund * contract.price_per_minute();
let mut admin_account = self
.accounts
.get_mut(&admin_pubkey)
.get_mut(&contract.admin_pubkey)
.ok_or(Error::ImpossibleError)?;
// check if he got kicked within the last day
@ -594,22 +560,15 @@ impl BrainData {
admin_account.kicked_for.push(reason.to_string());
operator_data.escrow -= refund_amount;
let admin_pubkey = admin_pubkey.clone();
let admin_pubkey = contract.admin_pubkey.clone();
drop(admin_account);
drop(contract);
if is_vm {
self.delete_vm(grpc::DeleteVmReq {
uuid: uuid.to_string(),
admin_pubkey,
})
.await?;
} else {
self.send_del_container_req(DelAppReq {
uuid: uuid.to_string(),
admin_pubkey,
})
.await?;
}
Ok(refund_amount)
}
@ -635,15 +594,10 @@ impl BrainData {
});
}
pub fn report_any_node(&self, admin_pubkey: String, node: &str, report: String) {
let mut vm_nodes = self.vm_nodes.write().unwrap();
if let Some(vm_node) = vm_nodes.iter_mut().find(|n| n.public_key == node) {
vm_node.reports.insert(admin_pubkey.clone(), report.clone());
}
let mut app_nodes = self.app_nodes.write().unwrap();
if let Some(app_node) = app_nodes.iter_mut().find(|n| n.node_pubkey == node) {
app_node.reports.insert(admin_pubkey, report);
pub fn report_node(&self, admin_pubkey: String, node: &str, report: String) {
let mut nodes = self.vm_nodes.write().unwrap();
if let Some(node) = nodes.iter_mut().find(|n| n.public_key == node) {
node.reports.insert(admin_pubkey, report);
}
}
@ -1285,25 +1239,6 @@ impl BrainData {
}
}
impl BrainData {
pub fn find_any_contract_by_uuid(
&self,
uuid: &str,
) -> Result<(Option<VmContract>, Option<AppContract>), Error> {
let contracts = self.vm_contracts.read().unwrap();
if let Some(vm_contract) = contracts.iter().cloned().find(|c| c.uuid == uuid) {
return Ok((Some(vm_contract), None));
}
let app_contracts = self.app_contracts.read().unwrap();
if let Some(app_contract) = app_contracts.iter().cloned().find(|c| c.uuid == uuid) {
return Ok((None, Some(app_contract)));
}
Err(Error::ContractNotFound(uuid.to_string()))
}
}
impl BrainData {
pub fn add_app_daemon_tx(&self, node_pubkey: &str, tx: Sender<BrainMessageApp>) {
self.app_daemon_tx.insert(node_pubkey.to_string(), tx);

@ -99,23 +99,17 @@ impl BrainGeneralCli for BrainGeneraClilMock {
async fn report_node(&self, req: Request<ReportNodeReq>) -> Result<Response<Empty>, Status> {
let req = check_sig_from_req(req)?;
match self.data.find_any_contract_by_uuid(&req.contract) {
Ok((Some(vm_contract), _))
if vm_contract.admin_pubkey == req.admin_pubkey
&& vm_contract.node_pubkey == req.node_pubkey =>
{
()
}
Ok((_, Some(app_contract)))
if app_contract.admin_pubkey == req.admin_pubkey
&& app_contract.node_pubkey == req.node_pubkey =>
match self.data.find_contract_by_uuid(&req.contract) {
Ok(contract)
if contract.admin_pubkey == req.admin_pubkey
&& contract.node_pubkey == req.node_pubkey =>
{
()
}
_ => return Err(Status::unauthenticated("No contract found by this ID.")),
};
self.data
.report_any_node(req.admin_pubkey, &req.node_pubkey, req.reason);
.report_node(req.admin_pubkey, &req.node_pubkey, req.reason);
Ok(Response::new(Empty {}))
}