added report and airdrop
This commit is contained in:
parent
71cc0a8d82
commit
a8cf515061
64
src/db.rs
64
src/db.rs
@ -51,36 +51,6 @@ pub async fn migration0(old_data: &old_brain::BrainData) -> surrealdb::Result<()
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn account(address: &str) -> Result<Account, Error> {
|
|
||||||
let id = (ACCOUNT, address);
|
|
||||||
let account: Option<Account> = DB.select(id).await?;
|
|
||||||
let account = match account {
|
|
||||||
Some(account) => account,
|
|
||||||
None => {
|
|
||||||
Account { id: id.into(), balance: 0, tmp_locked: 0, escrow: 0, email: String::new() }
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Ok(account)
|
|
||||||
}
|
|
||||||
|
|
||||||
// I am not deleting this example cause I might need it later.
|
|
||||||
//
|
|
||||||
// async fn get_wallet_contracts() -> surrealdb::Result<Vec<Wallet>> {
|
|
||||||
// let mut result = DB
|
|
||||||
// .query("select *, ->contract.* from wallet:address1;")
|
|
||||||
// .await?;
|
|
||||||
// let wallets: Vec<Wallet> = result.take(0)?;
|
|
||||||
// Ok(wallets)
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// #[derive(Debug, Serialize, Deserialize)]
|
|
||||||
// pub struct Wallet {
|
|
||||||
// balance: u64,
|
|
||||||
// id: RecordId,
|
|
||||||
// #[serde(rename = "->contract", default)]
|
|
||||||
// contracts: Vec<Contract>,
|
|
||||||
// }
|
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub struct Account {
|
pub struct Account {
|
||||||
pub id: RecordId,
|
pub id: RecordId,
|
||||||
@ -90,6 +60,28 @@ pub struct Account {
|
|||||||
pub email: String,
|
pub email: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Account {
|
||||||
|
pub async fn get(address: &str) -> Result<Self, Error> {
|
||||||
|
let id = (ACCOUNT, address);
|
||||||
|
let account: Option<Self> = DB.select(id).await?;
|
||||||
|
let account = match account {
|
||||||
|
Some(account) => account,
|
||||||
|
None => {
|
||||||
|
Self { id: id.into(), balance: 0, tmp_locked: 0, escrow: 0, email: String::new() }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Ok(account)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn airdrop(account: &str, tokens: u64) -> Result<(), Error> {
|
||||||
|
let tokens = tokens.saturating_mul(1_000_000_000);
|
||||||
|
let _ = DB
|
||||||
|
.query(format!("upsert account:{account} SET balance = (balance || 0) + {tokens};"))
|
||||||
|
.await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub struct VmNode {
|
pub struct VmNode {
|
||||||
pub id: RecordId,
|
pub id: RecordId,
|
||||||
@ -291,7 +283,6 @@ pub struct Kick {
|
|||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub struct Report {
|
pub struct Report {
|
||||||
id: RecordId,
|
|
||||||
#[serde(rename = "in")]
|
#[serde(rename = "in")]
|
||||||
from_account: RecordId,
|
from_account: RecordId,
|
||||||
#[serde(rename = "out")]
|
#[serde(rename = "out")]
|
||||||
@ -300,6 +291,17 @@ pub struct Report {
|
|||||||
reason: String,
|
reason: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Report {
|
||||||
|
// TODO: test this functionality and remove this comment
|
||||||
|
pub async fn create(from_account: RecordId, to_node: RecordId, reason: String) -> Result<(), Error> {
|
||||||
|
let _: Vec<Self> = DB
|
||||||
|
.insert("report")
|
||||||
|
.relation(Report { from_account, to_node, created_at: Datetime::default(), reason })
|
||||||
|
.await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub struct OperatorRelation {
|
pub struct OperatorRelation {
|
||||||
#[serde(rename = "in")]
|
#[serde(rename = "in")]
|
||||||
|
84
src/grpc.rs
84
src/grpc.rs
@ -95,29 +95,25 @@ impl BrainGeneralCli for BrainGeneralCliMock {
|
|||||||
|
|
||||||
async fn get_balance(&self, req: Request<Pubkey>) -> Result<Response<AccountBalance>, Status> {
|
async fn get_balance(&self, req: Request<Pubkey>) -> Result<Response<AccountBalance>, Status> {
|
||||||
let req = check_sig_from_req(req)?;
|
let req = check_sig_from_req(req)?;
|
||||||
Ok(Response::new(db::account(&req.pubkey).await?.into()))
|
Ok(Response::new(db::Account::get(&req.pubkey).await?.into()))
|
||||||
}
|
}
|
||||||
|
|
||||||
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)?;
|
||||||
todo!();
|
let (account, node) = match db::VmContractWithNode::get_by_uuid(&req.contract).await? {
|
||||||
// match self.data.find_any_contract_by_uuid(&req.contract) {
|
Some(vm_contract)
|
||||||
// Ok((Some(vm_contract), _))
|
if vm_contract.admin.key().to_string() == req.admin_pubkey
|
||||||
// if vm_contract.admin_pubkey == req.admin_pubkey
|
&& vm_contract.vm_node.id.key().to_string() == req.node_pubkey =>
|
||||||
// && vm_contract.node_pubkey == req.node_pubkey =>
|
{
|
||||||
// {
|
(vm_contract.admin, vm_contract.vm_node.id)
|
||||||
// ()
|
}
|
||||||
// }
|
_ => {
|
||||||
// Ok((_, Some(app_contract)))
|
// TODO: Hey, Noor! Please add app contract here.
|
||||||
// if app_contract.admin_pubkey == req.admin_pubkey
|
return Err(Status::unauthenticated("No contract found by this ID."));
|
||||||
// && app_contract.node_pubkey == req.node_pubkey =>
|
}
|
||||||
// {
|
};
|
||||||
// ()
|
db::Report::create(account, node, req.reason).await?;
|
||||||
// }
|
Ok(Response::new(Empty {}))
|
||||||
// _ => return Err(Status::unauthenticated("No contract found by this ID.")),
|
|
||||||
// };
|
|
||||||
// self.data.report_any_node(req.admin_pubkey, &req.node_pubkey, req.reason);
|
|
||||||
// Ok(Response::new(Empty {}))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn list_operators(
|
async fn list_operators(
|
||||||
@ -178,12 +174,11 @@ impl BrainGeneralCli for BrainGeneralCliMock {
|
|||||||
|
|
||||||
// admin commands
|
// admin commands
|
||||||
|
|
||||||
async fn airdrop(&self, _req: Request<AirdropReq>) -> Result<Response<Empty>, Status> {
|
async fn airdrop(&self, req: Request<AirdropReq>) -> Result<Response<Empty>, Status> {
|
||||||
todo!();
|
check_admin_key(&req)?;
|
||||||
// check_admin_key(&req)?;
|
let req = check_sig_from_req(req)?;
|
||||||
// let req = check_sig_from_req(req)?;
|
db::Account::airdrop(&req.pubkey, req.tokens).await?;
|
||||||
// self.data.give_airdrop(&req.pubkey, req.tokens);
|
Ok(Response::new(Empty {}))
|
||||||
// Ok(Response::new(Empty {}))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn slash(&self, _req: Request<SlashReq>) -> Result<Response<Empty>, Status> {
|
async fn slash(&self, _req: Request<SlashReq>) -> Result<Response<Empty>, Status> {
|
||||||
@ -420,13 +415,26 @@ macro_rules! impl_pubkey_getter {
|
|||||||
impl_pubkey_getter!(Pubkey, pubkey);
|
impl_pubkey_getter!(Pubkey, pubkey);
|
||||||
impl_pubkey_getter!(NewVmReq, admin_pubkey);
|
impl_pubkey_getter!(NewVmReq, admin_pubkey);
|
||||||
impl_pubkey_getter!(DeleteVmReq, admin_pubkey);
|
impl_pubkey_getter!(DeleteVmReq, admin_pubkey);
|
||||||
impl_pubkey_getter!(ReportNodeReq, admin_pubkey);
|
|
||||||
impl_pubkey_getter!(UpdateVmReq, admin_pubkey);
|
impl_pubkey_getter!(UpdateVmReq, admin_pubkey);
|
||||||
impl_pubkey_getter!(ExtendVmReq, admin_pubkey);
|
impl_pubkey_getter!(ExtendVmReq, admin_pubkey);
|
||||||
|
impl_pubkey_getter!(ReportNodeReq, admin_pubkey);
|
||||||
impl_pubkey_getter!(ListVmContractsReq, wallet);
|
impl_pubkey_getter!(ListVmContractsReq, wallet);
|
||||||
impl_pubkey_getter!(RegisterVmNodeReq, node_pubkey);
|
impl_pubkey_getter!(RegisterVmNodeReq, node_pubkey);
|
||||||
|
impl_pubkey_getter!(RegOperatorReq, pubkey);
|
||||||
|
impl_pubkey_getter!(KickReq, operator_wallet);
|
||||||
|
impl_pubkey_getter!(BanUserReq, operator_wallet);
|
||||||
|
|
||||||
impl_pubkey_getter!(VmNodeFilters);
|
impl_pubkey_getter!(VmNodeFilters);
|
||||||
impl_pubkey_getter!(Empty);
|
impl_pubkey_getter!(Empty);
|
||||||
|
impl_pubkey_getter!(AirdropReq);
|
||||||
|
impl_pubkey_getter!(SlashReq);
|
||||||
|
|
||||||
|
// impl_pubkey_getter!(NewAppReq, admin_pubkey);
|
||||||
|
// impl_pubkey_getter!(DelAppReq, admin_pubkey);
|
||||||
|
// impl_pubkey_getter!(ListAppContractsReq, admin_pubkey);
|
||||||
|
//
|
||||||
|
// impl_pubkey_getter!(RegisterAppNodeReq);
|
||||||
|
// impl_pubkey_getter!(AppNodeFilters);
|
||||||
|
|
||||||
fn check_sig_from_req<T: std::fmt::Debug + PubkeyGetter>(req: Request<T>) -> Result<T, Status> {
|
fn check_sig_from_req<T: std::fmt::Debug + PubkeyGetter>(req: Request<T>) -> Result<T, Status> {
|
||||||
let time = match req.metadata().get("timestamp") {
|
let time = match req.metadata().get("timestamp") {
|
||||||
@ -490,3 +498,25 @@ fn check_sig_from_req<T: std::fmt::Debug + PubkeyGetter>(req: Request<T>) -> Res
|
|||||||
}
|
}
|
||||||
Ok(req)
|
Ok(req)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ADMIN_ACCOUNTS: &[&str] = &[
|
||||||
|
"x52w7jARC5erhWWK65VZmjdGXzBK6ZDgfv1A283d8XK",
|
||||||
|
"FHuecMbeC1PfjkW2JKyoicJAuiU7khgQT16QUB3Q1XdL",
|
||||||
|
"H21Shi4iE7vgfjWEQNvzmpmBMJSaiZ17PYUcdNoAoKNc",
|
||||||
|
];
|
||||||
|
|
||||||
|
fn check_admin_key<T>(req: &Request<T>) -> Result<(), Status> {
|
||||||
|
let pubkey = match req.metadata().get("pubkey") {
|
||||||
|
Some(p) => p.clone(),
|
||||||
|
None => return Err(Status::unauthenticated("pubkey not found in metadata.")),
|
||||||
|
};
|
||||||
|
let pubkey = pubkey
|
||||||
|
.to_str()
|
||||||
|
.map_err(|_| Status::unauthenticated("could not parse pubkey metadata to str"))?;
|
||||||
|
|
||||||
|
if !ADMIN_ACCOUNTS.contains(&pubkey) {
|
||||||
|
return Err(Status::unauthenticated("This operation is reserved to admin accounts"));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user