Compare commits
1 Commits
37d45f5b74
...
6ca02e91b9
Author | SHA1 | Date | |
---|---|---|---|
6ca02e91b9 |
6
Cargo.lock
generated
6
Cargo.lock
generated
@ -246,7 +246,7 @@ dependencies = [
|
||||
"prost-types",
|
||||
"reqwest",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_yaml",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"tokio-stream",
|
||||
@ -307,6 +307,7 @@ dependencies = [
|
||||
"iana-time-zone",
|
||||
"js-sys",
|
||||
"num-traits",
|
||||
"serde",
|
||||
"wasm-bindgen",
|
||||
"windows-targets",
|
||||
]
|
||||
@ -403,6 +404,7 @@ dependencies = [
|
||||
"lock_api",
|
||||
"once_cell",
|
||||
"parking_lot_core",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -418,7 +420,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "detee-shared"
|
||||
version = "0.1.0"
|
||||
source = "git+ssh://git@gitea.detee.cloud/noormohammedb/detee-shared?branch=stable_01#b8f37dec1845d29ea0b69035712e6ebb214376f4"
|
||||
source = "git+ssh://git@gitea.detee.cloud/noormohammedb/detee-shared?branch=stable_01#099f0a0488bce8e59c9c9e9a5e9b1f24998f1633"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"prost",
|
||||
|
@ -5,16 +5,16 @@ edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
bs58 = "0.5.1"
|
||||
chrono = "0.4.39"
|
||||
dashmap = "6.1.0"
|
||||
chrono = { version = "0.4.39", features = ["serde"] }
|
||||
dashmap = { version = "6.1.0", features = ["serde"] }
|
||||
ed25519-dalek = "2.1.1"
|
||||
env_logger = "0.11.6"
|
||||
log = "0.4.22"
|
||||
prost = "0.13.4"
|
||||
prost-types = "0.13.4"
|
||||
reqwest = "0.12.10"
|
||||
serde = { version = "1.0.216", features = ["derive"] }
|
||||
serde_json = "1.0.134"
|
||||
serde = { version = "1.0.217", features = ["derive"] }
|
||||
serde_yaml = "0.9.34"
|
||||
thiserror = "2.0.11"
|
||||
tokio = { version = "1.42.0", features = ["macros", "rt-multi-thread"] }
|
||||
tokio-stream = "0.1.17"
|
||||
|
768
src/data.rs
768
src/data.rs
File diff suppressed because it is too large
Load Diff
336
src/grpc.rs
336
src/grpc.rs
@ -1,5 +1,3 @@
|
||||
#![allow(dead_code)]
|
||||
|
||||
pub mod snp_proto {
|
||||
tonic::include_proto!("vm_proto");
|
||||
}
|
||||
@ -19,12 +17,13 @@ use tonic::{Request, Response, Status, Streaming};
|
||||
use detee_shared::sgx::pb::brain::brain_app_cli_server::BrainAppCli;
|
||||
use detee_shared::sgx::pb::brain::brain_app_daemon_server::BrainAppDaemon;
|
||||
use detee_shared::sgx::pb::brain::{
|
||||
AppContract, BrainMessageApp, DaemonMessageApp, DelAppReq, ListAppContractsReq, NewAppReq,
|
||||
NewAppRes, RegisterAppNodeReq,
|
||||
AppContract, AppNodeFilters, AppNodeListResp, BrainMessageApp, DaemonMessageApp, DelAppReq,
|
||||
ListAppContractsReq, NewAppReq, NewAppRes, RegisterAppNodeReq,
|
||||
};
|
||||
const ADMIN_ACCOUNTS: &[&str] = &[
|
||||
"x52w7jARC5erhWWK65VZmjdGXzBK6ZDgfv1A283d8XK",
|
||||
"FHuecMbeC1PfjkW2JKyoicJAuiU7khgQT16QUB3Q1XdL",
|
||||
"H21Shi4iE7vgfjWEQNvzmpmBMJSaiZ17PYUcdNoAoKNc",
|
||||
];
|
||||
|
||||
pub struct BrainDaemonMock {
|
||||
@ -78,7 +77,7 @@ impl BrainVmDaemon for BrainDaemonMock {
|
||||
info!("Starting registration process for {:?}", req);
|
||||
let node = crate::data::VmNode {
|
||||
public_key: req.node_pubkey.clone(),
|
||||
owner_key: req.owner_pubkey,
|
||||
operator_wallet: req.operator_wallet,
|
||||
country: req.country,
|
||||
region: req.region,
|
||||
city: req.city,
|
||||
@ -86,10 +85,10 @@ impl BrainVmDaemon for BrainDaemonMock {
|
||||
price: req.price,
|
||||
..Default::default()
|
||||
};
|
||||
self.data.insert_node(node);
|
||||
self.data.register_node(node);
|
||||
|
||||
info!("Sending existing contracts to {}", req.node_pubkey);
|
||||
let contracts = self.data.find_contracts_by_node_pubkey(&req.node_pubkey);
|
||||
let contracts = self.data.find_vm_contracts_by_node(&req.node_pubkey);
|
||||
let (tx, rx) = mpsc::channel(6);
|
||||
tokio::spawn(async move {
|
||||
for contract in contracts {
|
||||
@ -187,6 +186,14 @@ impl BrainCli for BrainCliMock {
|
||||
async fn new_vm(&self, req: Request<NewVmReq>) -> Result<Response<NewVmResp>, Status> {
|
||||
let req = check_sig_from_req(req)?;
|
||||
info!("New VM requested via CLI: {req:?}");
|
||||
if self
|
||||
.data
|
||||
.is_user_banned_by_node(&req.admin_pubkey, &req.node_pubkey)
|
||||
{
|
||||
return Err(Status::permission_denied(
|
||||
"This operator banned you. What did you do?",
|
||||
));
|
||||
}
|
||||
let admin_pubkey = req.admin_pubkey.clone();
|
||||
let (oneshot_tx, oneshot_rx) = tokio::sync::oneshot::channel();
|
||||
self.data.submit_newvm_req(req, oneshot_tx).await;
|
||||
@ -214,9 +221,9 @@ impl BrainCli for BrainCliMock {
|
||||
info!("Sending UpdateVMResp: {response:?}");
|
||||
Ok(Response::new(response))
|
||||
}
|
||||
Err(_) => Err(Status::unknown(
|
||||
"Update VM request failed due to error: {e}",
|
||||
)),
|
||||
Err(e) => Err(Status::unknown(format!(
|
||||
"Update VM request failed due to error: {e}"
|
||||
))),
|
||||
}
|
||||
}
|
||||
|
||||
@ -231,20 +238,55 @@ impl BrainCli for BrainCliMock {
|
||||
}
|
||||
}
|
||||
|
||||
async fn delete_vm(&self, req: Request<DeleteVmReq>) -> Result<Response<Empty>, Status> {
|
||||
let req = check_sig_from_req(req)?;
|
||||
match self.data.delete_vm(req).await {
|
||||
Ok(()) => Ok(Response::new(Empty {})),
|
||||
Err(e) => Err(Status::not_found(e.to_string())),
|
||||
}
|
||||
}
|
||||
|
||||
async fn report_node(&self, req: Request<ReportNodeReq>) -> Result<Response<Empty>, Status> {
|
||||
let req = check_sig_from_req(req)?;
|
||||
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_node(req.admin_pubkey, &req.node_pubkey, req.reason);
|
||||
Ok(Response::new(Empty {}))
|
||||
}
|
||||
|
||||
type ListVmContractsStream = Pin<Box<dyn Stream<Item = Result<VmContract, Status>> + Send>>;
|
||||
async fn list_vm_contracts(
|
||||
&self,
|
||||
req: Request<ListVmContractsReq>,
|
||||
) -> Result<Response<Self::ListVmContractsStream>, Status> {
|
||||
let req = check_sig_from_req(req)?;
|
||||
info!("CLI {} requested ListVMVmContractsStream", req.admin_pubkey);
|
||||
let contracts = match req.uuid.is_empty() {
|
||||
false => match self.data.find_contract_by_uuid(&req.uuid) {
|
||||
Some(contract) => vec![contract],
|
||||
None => Vec::new(),
|
||||
},
|
||||
true => self.data.find_contracts_by_admin_pubkey(&req.admin_pubkey),
|
||||
};
|
||||
info!(
|
||||
"CLI {} requested ListVMVmContractsStream. As operator: {}",
|
||||
req.wallet, req.as_operator
|
||||
);
|
||||
let mut contracts = Vec::new();
|
||||
if !req.uuid.is_empty() {
|
||||
if let Ok(specific_contract) = self.data.find_contract_by_uuid(&req.uuid) {
|
||||
if specific_contract.admin_pubkey == req.wallet {
|
||||
contracts.push(specific_contract);
|
||||
}
|
||||
// TODO: allow operator to inspect contracts
|
||||
}
|
||||
} else {
|
||||
if req.as_operator {
|
||||
contracts.append(&mut self.data.find_vm_contracts_by_operator(&req.wallet));
|
||||
} else {
|
||||
contracts.append(&mut self.data.find_vm_contracts_by_admin(&req.wallet));
|
||||
}
|
||||
}
|
||||
let (tx, rx) = mpsc::channel(6);
|
||||
tokio::spawn(async move {
|
||||
for contract in contracts {
|
||||
@ -264,7 +306,7 @@ impl BrainCli for BrainCliMock {
|
||||
) -> Result<Response<Self::ListVmNodesStream>, tonic::Status> {
|
||||
let req = check_sig_from_req(req)?;
|
||||
info!("CLI requested ListVmNodesStream: {req:?}");
|
||||
let nodes = self.data.find_nodes_by_filters(&req);
|
||||
let nodes = self.data.find_vm_nodes_by_filters(&req);
|
||||
let (tx, rx) = mpsc::channel(6);
|
||||
tokio::spawn(async move {
|
||||
for node in nodes {
|
||||
@ -291,12 +333,65 @@ impl BrainCli for BrainCliMock {
|
||||
}
|
||||
}
|
||||
|
||||
async fn delete_vm(&self, req: Request<DeleteVmReq>) -> Result<Response<Empty>, Status> {
|
||||
async fn register_operator(
|
||||
&self,
|
||||
req: Request<RegOperatorReq>,
|
||||
) -> Result<Response<Empty>, Status> {
|
||||
let req = check_sig_from_req(req)?;
|
||||
info!("Unknown CLI requested to delete vm {}", req.uuid);
|
||||
match self.data.delete_vm(req).await {
|
||||
info!("Regitering new operator: {req:?}");
|
||||
match self.data.register_operator(req) {
|
||||
Ok(()) => Ok(Response::new(Empty {})),
|
||||
Err(e) => Err(Status::not_found(e.to_string())),
|
||||
Err(e) => Err(Status::failed_precondition(e.to_string())),
|
||||
}
|
||||
}
|
||||
|
||||
async fn kick_contract(&self, req: Request<KickReq>) -> Result<Response<KickResp>, Status> {
|
||||
let req = check_sig_from_req(req)?;
|
||||
match self
|
||||
.data
|
||||
.kick_contract(&req.operator_wallet, &req.contract_uuid, &req.reason)
|
||||
.await
|
||||
{
|
||||
Ok(nano_lp) => Ok(Response::new(KickResp { nano_lp })),
|
||||
Err(e) => Err(Status::permission_denied(e.to_string())),
|
||||
}
|
||||
}
|
||||
|
||||
async fn ban_user(&self, req: Request<BanUserReq>) -> Result<Response<Empty>, Status> {
|
||||
let req = check_sig_from_req(req)?;
|
||||
self.data.ban_user(&req.operator_wallet, &req.user_wallet);
|
||||
Ok(Response::new(Empty {}))
|
||||
}
|
||||
|
||||
type ListOperatorsStream =
|
||||
Pin<Box<dyn Stream<Item = Result<ListOperatorsResp, Status>> + Send>>;
|
||||
async fn list_operators(
|
||||
&self,
|
||||
req: Request<Empty>,
|
||||
) -> Result<Response<Self::ListOperatorsStream>, Status> {
|
||||
let _ = check_sig_from_req(req)?;
|
||||
let operators = self.data.list_operators();
|
||||
let (tx, rx) = mpsc::channel(6);
|
||||
tokio::spawn(async move {
|
||||
for op in operators {
|
||||
let _ = tx.send(Ok(op.into())).await;
|
||||
}
|
||||
});
|
||||
let output_stream = ReceiverStream::new(rx);
|
||||
Ok(Response::new(
|
||||
Box::pin(output_stream) as Self::ListOperatorsStream
|
||||
))
|
||||
}
|
||||
|
||||
async fn inspect_operator(
|
||||
&self,
|
||||
req: Request<Pubkey>,
|
||||
) -> Result<Response<InspectOperatorResp>, Status> {
|
||||
match self.data.inspect_operator(&req.into_inner().pubkey) {
|
||||
Some(op) => Ok(Response::new(op.into())),
|
||||
None => Err(Status::not_found(
|
||||
"The wallet you specified is not an operator",
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
@ -307,6 +402,13 @@ impl BrainCli for BrainCliMock {
|
||||
Ok(Response::new(Empty {}))
|
||||
}
|
||||
|
||||
async fn slash(&self, req: Request<SlashReq>) -> Result<Response<Empty>, Status> {
|
||||
check_admin_key(&req)?;
|
||||
let req = check_sig_from_req(req)?;
|
||||
self.data.slash_account(&req.pubkey, req.tokens);
|
||||
Ok(Response::new(Empty {}))
|
||||
}
|
||||
|
||||
type ListAllVmContractsStream = Pin<Box<dyn Stream<Item = Result<VmContract, Status>> + Send>>;
|
||||
async fn list_all_vm_contracts(
|
||||
&self,
|
||||
@ -352,17 +454,14 @@ trait PubkeyGetter {
|
||||
fn get_pubkey(&self) -> Option<String>;
|
||||
}
|
||||
|
||||
impl PubkeyGetter for Pubkey {
|
||||
fn get_pubkey(&self) -> Option<String> {
|
||||
Some(self.pubkey.clone())
|
||||
}
|
||||
}
|
||||
|
||||
#[tonic::async_trait]
|
||||
impl BrainAppCli for BrainAppCliMock {
|
||||
type ListAppContractsStream = Pin<Box<dyn Stream<Item = Result<AppContract, Status>> + Send>>;
|
||||
type ListAppNodesStream = Pin<Box<dyn Stream<Item = Result<AppNodeListResp, Status>> + Send>>;
|
||||
type ListAllAppContractsStream =
|
||||
Pin<Box<dyn Stream<Item = Result<AppContract, Status>> + Send>>;
|
||||
|
||||
async fn create_app(
|
||||
async fn deploy_app(
|
||||
&self,
|
||||
req: tonic::Request<NewAppReq>,
|
||||
) -> Result<tonic::Response<NewAppRes>, Status> {
|
||||
@ -420,6 +519,54 @@ impl BrainAppCli for BrainAppCliMock {
|
||||
Box::pin(output_stream) as Self::ListAppContractsStream
|
||||
))
|
||||
}
|
||||
|
||||
async fn list_app_nodes(
|
||||
&self,
|
||||
req: tonic::Request<AppNodeFilters>,
|
||||
) -> Result<tonic::Response<Self::ListAppNodesStream>, Status> {
|
||||
let req = check_sig_from_req(req)?;
|
||||
info!("CLI requested ListAppNodes: {req:?}");
|
||||
let nodes = self.data.find_app_nodes_by_filters(&req);
|
||||
let (tx, rx) = mpsc::channel(6);
|
||||
tokio::spawn(async move {
|
||||
for node in nodes {
|
||||
let _ = tx.send(Ok(node.into())).await;
|
||||
}
|
||||
});
|
||||
let output_stream = ReceiverStream::new(rx);
|
||||
Ok(Response::new(Box::pin(output_stream)))
|
||||
}
|
||||
|
||||
async fn get_one_app_node(
|
||||
&self,
|
||||
req: tonic::Request<AppNodeFilters>,
|
||||
) -> Result<tonic::Response<AppNodeListResp>, Status> {
|
||||
let req = check_sig_from_req(req)?;
|
||||
info!("CLI requested GetOneAppNode: {req:?}");
|
||||
match self.data.get_one_app_node_by_filters(&req) {
|
||||
Some(node) => Ok(Response::new(node.into())),
|
||||
None => Err(Status::not_found(
|
||||
"Could not find any node based on your search criteria",
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
async fn list_all_app_contracts(
|
||||
&self,
|
||||
req: tonic::Request<detee_shared::sgx::pb::brain::Empty>,
|
||||
) -> Result<tonic::Response<Self::ListAllAppContractsStream>, Status> {
|
||||
check_admin_key(&req)?;
|
||||
let _ = check_sig_from_req(req)?;
|
||||
let contracts = self.data.list_all_app_contracts();
|
||||
let (tx, rx) = mpsc::channel(6);
|
||||
tokio::spawn(async move {
|
||||
for contract in contracts {
|
||||
let _ = tx.send(Ok(contract.into())).await;
|
||||
}
|
||||
});
|
||||
let output_stream = ReceiverStream::new(rx);
|
||||
Ok(Response::new(Box::pin(output_stream)))
|
||||
}
|
||||
}
|
||||
|
||||
#[tonic::async_trait]
|
||||
@ -435,26 +582,22 @@ impl BrainAppDaemon for BrainAppDaemonMock {
|
||||
log::info!(
|
||||
"registering app node_key : {}, operator_key: {}",
|
||||
&req_data.node_pubkey,
|
||||
&req_data.operator_pubkey
|
||||
&req_data.operator_wallet
|
||||
);
|
||||
|
||||
let app_node = crate::data::AppNode {
|
||||
node_pubkey: req_data.node_pubkey.clone(),
|
||||
operator_pubkey: req_data.operator_pubkey,
|
||||
operator_wallet: req_data.operator_wallet,
|
||||
ip: req_data.main_ip,
|
||||
city: req_data.city,
|
||||
region: req_data.region,
|
||||
country: req_data.country,
|
||||
..Default::default()
|
||||
};
|
||||
self.data.register_app_node(app_node);
|
||||
|
||||
self.data.insert_app_node(app_node);
|
||||
log::info!("Sending existing contracts to {}", &req_data.node_pubkey);
|
||||
|
||||
let app_contracts = self
|
||||
.data
|
||||
.find_app_contracts_by_node_pubkey(&req_data.node_pubkey);
|
||||
|
||||
let app_contracts = self.data.find_app_contracts_by_node(&req_data.node_pubkey);
|
||||
let (tx, rx) = mpsc::channel(6);
|
||||
tokio::spawn(async move {
|
||||
for contract in app_contracts {
|
||||
@ -549,83 +692,48 @@ impl BrainAppDaemon for BrainAppDaemonMock {
|
||||
Ok(Response::new(detee_shared::sgx::pb::brain::Empty {}))
|
||||
}
|
||||
}
|
||||
impl PubkeyGetter for NewVmReq {
|
||||
fn get_pubkey(&self) -> Option<String> {
|
||||
Some(self.admin_pubkey.clone())
|
||||
}
|
||||
|
||||
macro_rules! impl_pubkey_getter {
|
||||
($t:ty, $field:ident) => {
|
||||
impl PubkeyGetter for $t {
|
||||
fn get_pubkey(&self) -> Option<String> {
|
||||
Some(self.$field.clone())
|
||||
}
|
||||
}
|
||||
};
|
||||
($t:ty) => {
|
||||
impl PubkeyGetter for $t {
|
||||
fn get_pubkey(&self) -> Option<String> {
|
||||
None
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl PubkeyGetter for DeleteVmReq {
|
||||
fn get_pubkey(&self) -> Option<String> {
|
||||
Some(self.admin_pubkey.clone())
|
||||
}
|
||||
}
|
||||
impl_pubkey_getter!(Pubkey, pubkey);
|
||||
impl_pubkey_getter!(NewVmReq, admin_pubkey);
|
||||
impl_pubkey_getter!(DeleteVmReq, admin_pubkey);
|
||||
impl_pubkey_getter!(UpdateVmReq, admin_pubkey);
|
||||
impl_pubkey_getter!(ExtendVmReq, admin_pubkey);
|
||||
impl_pubkey_getter!(ReportNodeReq, admin_pubkey);
|
||||
impl_pubkey_getter!(ListVmContractsReq, wallet);
|
||||
impl_pubkey_getter!(RegisterVmNodeReq, node_pubkey);
|
||||
impl_pubkey_getter!(RegOperatorReq, pubkey);
|
||||
impl_pubkey_getter!(KickReq, operator_wallet);
|
||||
impl_pubkey_getter!(BanUserReq, operator_wallet);
|
||||
|
||||
impl PubkeyGetter for UpdateVmReq {
|
||||
fn get_pubkey(&self) -> Option<String> {
|
||||
Some(self.admin_pubkey.clone())
|
||||
}
|
||||
}
|
||||
impl_pubkey_getter!(VmNodeFilters);
|
||||
impl_pubkey_getter!(Empty);
|
||||
impl_pubkey_getter!(AirdropReq);
|
||||
impl_pubkey_getter!(SlashReq);
|
||||
|
||||
impl PubkeyGetter for ExtendVmReq {
|
||||
fn get_pubkey(&self) -> Option<String> {
|
||||
Some(self.admin_pubkey.clone())
|
||||
}
|
||||
}
|
||||
impl_pubkey_getter!(NewAppReq, admin_pubkey);
|
||||
impl_pubkey_getter!(DelAppReq, admin_pubkey);
|
||||
impl_pubkey_getter!(ListAppContractsReq, admin_pubkey);
|
||||
|
||||
impl PubkeyGetter for ListVmContractsReq {
|
||||
fn get_pubkey(&self) -> Option<String> {
|
||||
Some(self.admin_pubkey.clone())
|
||||
}
|
||||
}
|
||||
|
||||
impl PubkeyGetter for VmNodeFilters {
|
||||
fn get_pubkey(&self) -> Option<String> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl PubkeyGetter for RegisterVmNodeReq {
|
||||
fn get_pubkey(&self) -> Option<String> {
|
||||
Some(self.node_pubkey.clone())
|
||||
}
|
||||
}
|
||||
|
||||
impl PubkeyGetter for Empty {
|
||||
fn get_pubkey(&self) -> Option<String> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl PubkeyGetter for AirdropReq {
|
||||
fn get_pubkey(&self) -> Option<String> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl PubkeyGetter for RegisterAppNodeReq {
|
||||
fn get_pubkey(&self) -> Option<String> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl PubkeyGetter for NewAppReq {
|
||||
fn get_pubkey(&self) -> Option<String> {
|
||||
Some(self.admin_pubkey.clone())
|
||||
}
|
||||
}
|
||||
|
||||
impl PubkeyGetter for DelAppReq {
|
||||
fn get_pubkey(&self) -> Option<String> {
|
||||
Some(self.admin_pubkey.clone())
|
||||
}
|
||||
}
|
||||
|
||||
impl PubkeyGetter for ListAppContractsReq {
|
||||
fn get_pubkey(&self) -> Option<String> {
|
||||
Some(self.admin_pubkey.clone())
|
||||
}
|
||||
}
|
||||
impl_pubkey_getter!(RegisterAppNodeReq);
|
||||
impl_pubkey_getter!(detee_shared::sgx::pb::brain::Empty);
|
||||
impl_pubkey_getter!(AppNodeFilters);
|
||||
|
||||
fn check_sig_from_req<T: std::fmt::Debug + PubkeyGetter>(req: Request<T>) -> Result<T, Status> {
|
||||
let time = match req.metadata().get("timestamp") {
|
||||
@ -640,9 +748,9 @@ fn check_sig_from_req<T: std::fmt::Debug + PubkeyGetter>(req: Request<T>) -> Res
|
||||
let parsed_time = chrono::DateTime::parse_from_rfc3339(time)
|
||||
.map_err(|_| Status::unauthenticated("Coult not parse timestamp"))?;
|
||||
let seconds_elapsed = now.signed_duration_since(parsed_time).num_seconds();
|
||||
if seconds_elapsed > 1 || seconds_elapsed < -1 {
|
||||
if seconds_elapsed > 4 || seconds_elapsed < -4 {
|
||||
return Err(Status::unauthenticated(format!(
|
||||
"Date is not within 1 sec of the time of the server: CLI {} vs Server {}",
|
||||
"Date is not within 4 sec of the time of the server: CLI {} vs Server {}",
|
||||
parsed_time, now
|
||||
)));
|
||||
}
|
||||
@ -695,9 +803,9 @@ fn check_sig_from_parts(pubkey: &str, time: &str, msg: &str, sig: &str) -> Resul
|
||||
let parsed_time = chrono::DateTime::parse_from_rfc3339(time)
|
||||
.map_err(|_| Status::unauthenticated("Coult not parse timestamp"))?;
|
||||
let seconds_elapsed = now.signed_duration_since(parsed_time).num_seconds();
|
||||
if seconds_elapsed > 1 || seconds_elapsed < -1 {
|
||||
if seconds_elapsed > 4 || seconds_elapsed < -4 {
|
||||
return Err(Status::unauthenticated(format!(
|
||||
"Date is not within 1 sec of the time of the server: CLI {} vs Server {}",
|
||||
"Date is not within 4 sec of the time of the server: CLI {} vs Server {}",
|
||||
parsed_time, now
|
||||
)));
|
||||
}
|
||||
|
@ -23,7 +23,12 @@ async fn main() {
|
||||
tokio::spawn(async move {
|
||||
loop {
|
||||
tokio::time::sleep(tokio::time::Duration::from_secs(60)).await;
|
||||
data_clone.vm_nodes_cron().await;
|
||||
data_clone.vm_contracts_cron().await;
|
||||
data_clone.app_contracts_cron().await;
|
||||
if let Err(e) = data_clone.save_to_disk() {
|
||||
log::error!("Could not save data to disk due to error: {e}")
|
||||
}
|
||||
}
|
||||
});
|
||||
let addr = "0.0.0.0:31337".parse().unwrap();
|
||||
|
77
vm.proto
77
vm.proto
@ -55,7 +55,7 @@ message MeasurementIP {
|
||||
// This should also include a block hash or similar, for auth
|
||||
message RegisterVmNodeReq {
|
||||
string node_pubkey = 1;
|
||||
string owner_pubkey = 2;
|
||||
string operator_wallet = 2;
|
||||
string main_ip = 3;
|
||||
string country = 4;
|
||||
string region = 5;
|
||||
@ -154,8 +154,8 @@ service BrainVmDaemon {
|
||||
}
|
||||
|
||||
message ListVmContractsReq {
|
||||
string admin_pubkey = 1;
|
||||
string node_pubkey = 2;
|
||||
string wallet = 1;
|
||||
bool as_operator = 2;
|
||||
string uuid = 3;
|
||||
}
|
||||
|
||||
@ -174,15 +174,14 @@ message VmNodeFilters {
|
||||
}
|
||||
|
||||
message VmNodeListResp {
|
||||
string node_pubkey = 1;
|
||||
string country = 2;
|
||||
string region = 3;
|
||||
string city = 4;
|
||||
string ip = 5; // required for latency test
|
||||
uint32 server_rating = 6;
|
||||
uint32 provider_rating = 7;
|
||||
// nanoLP per unit per minute
|
||||
uint64 price = 8;
|
||||
string operator = 1;
|
||||
string node_pubkey = 2;
|
||||
string country = 3;
|
||||
string region = 4;
|
||||
string city = 5;
|
||||
string ip = 6; // required for latency test
|
||||
repeated string reports = 7; // TODO: this will become an enum
|
||||
uint64 price = 8; // nanoLP per unit per minute
|
||||
}
|
||||
|
||||
message ExtendVmReq {
|
||||
@ -196,12 +195,59 @@ message AirdropReq {
|
||||
uint64 tokens = 2;
|
||||
}
|
||||
|
||||
message SlashReq {
|
||||
string pubkey = 1;
|
||||
uint64 tokens = 2;
|
||||
}
|
||||
|
||||
message Account {
|
||||
string pubkey = 1;
|
||||
uint64 balance = 2;
|
||||
uint64 tmp_locked = 3;
|
||||
}
|
||||
|
||||
message RegOperatorReq {
|
||||
string pubkey = 1;
|
||||
uint64 escrow = 2;
|
||||
string email = 3;
|
||||
}
|
||||
|
||||
message ListOperatorsResp {
|
||||
string pubkey = 1;
|
||||
uint64 escrow = 2;
|
||||
string email = 3;
|
||||
uint64 app_nodes = 4;
|
||||
uint64 vm_nodes = 5;
|
||||
uint64 reports = 6;
|
||||
}
|
||||
|
||||
message InspectOperatorResp {
|
||||
ListOperatorsResp operator = 1;
|
||||
repeated VmNodeListResp nodes = 2;
|
||||
}
|
||||
|
||||
message ReportNodeReq {
|
||||
string admin_pubkey = 1;
|
||||
string node_pubkey = 2;
|
||||
string contract = 3;
|
||||
string reason = 4;
|
||||
}
|
||||
|
||||
message KickReq {
|
||||
string operator_wallet = 1;
|
||||
string contract_uuid = 2;
|
||||
string reason = 3;
|
||||
}
|
||||
|
||||
message BanUserReq {
|
||||
string operator_wallet = 1;
|
||||
string user_wallet = 2;
|
||||
}
|
||||
|
||||
message KickResp {
|
||||
uint64 nano_lp = 1;
|
||||
}
|
||||
|
||||
service BrainCli {
|
||||
rpc GetBalance (Pubkey) returns (AccountBalance);
|
||||
rpc NewVm (NewVmReq) returns (NewVmResp);
|
||||
@ -211,8 +257,15 @@ service BrainCli {
|
||||
rpc DeleteVm (DeleteVmReq) returns (Empty);
|
||||
rpc UpdateVm (UpdateVmReq) returns (UpdateVmResp);
|
||||
rpc ExtendVm (ExtendVmReq) returns (Empty);
|
||||
rpc ReportNode (ReportNodeReq) returns (Empty);
|
||||
rpc ListOperators (Empty) returns (stream ListOperatorsResp);
|
||||
rpc InspectOperator (Pubkey) returns (InspectOperatorResp);
|
||||
rpc RegisterOperator (RegOperatorReq) returns (Empty);
|
||||
rpc KickContract (KickReq) returns (KickResp);
|
||||
rpc BanUser (BanUserReq) returns (Empty);
|
||||
// admin commands
|
||||
rpc Airdrop (AirdropReq) returns (Empty);
|
||||
rpc Slash (SlashReq) returns (Empty);
|
||||
rpc ListAllVmContracts (Empty) returns (stream VmContract);
|
||||
rpc ListAccounts (Empty) returns (stream Account);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user