Compare commits
	
		
			No commits in common. "cd5c83d3c3ed95bd74417d66bc7344cc413cb911" and "0ec1b61d8bd71e002fab738002b76370d80c2bb7" have entirely different histories.
		
	
	
		
			cd5c83d3c3
			...
			0ec1b61d8b
		
	
		
| @ -46,5 +46,5 @@ pub const ID_ALPHABET: [char; 62] = [ | |||||||
|     'V', 'W', 'X', 'Y', 'Z', |     'V', 'W', 'X', 'Y', 'Z', | ||||||
| ]; | ]; | ||||||
| 
 | 
 | ||||||
|  | pub const MIN_ESCROW: u64 = 5000; | ||||||
| pub const TOKEN_DECIMAL: u64 = 1_000_000_000; | pub const TOKEN_DECIMAL: u64 = 1_000_000_000; | ||||||
| pub const MIN_ESCROW: u64 = 5000 * TOKEN_DECIMAL; |  | ||||||
|  | |||||||
| @ -1,5 +1,5 @@ | |||||||
| use super::Error; | use super::Error; | ||||||
| use crate::constants::{ACCOUNT, BAN, KICK, MIN_ESCROW, VM_NODE}; | use crate::constants::{ACCOUNT, BAN, KICK, MIN_ESCROW, TOKEN_DECIMAL, VM_NODE}; | ||||||
| use crate::db::prelude::*; | use crate::db::prelude::*; | ||||||
| use crate::old_brain; | use crate::old_brain; | ||||||
| use serde::{Deserialize, Serialize}; | use serde::{Deserialize, Serialize}; | ||||||
| @ -42,6 +42,7 @@ impl Account { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     pub async fn airdrop(db: &Surreal<Client>, account: &str, tokens: u64) -> Result<(), Error> { |     pub async fn airdrop(db: &Surreal<Client>, account: &str, tokens: u64) -> Result<(), Error> { | ||||||
|  |         let tokens = tokens.saturating_mul(1_000_000_000); | ||||||
|         let _ = db |         let _ = db | ||||||
|             .query(format!("upsert account:{account} SET balance = (balance || 0) + {tokens};")) |             .query(format!("upsert account:{account} SET balance = (balance || 0) + {tokens};")) | ||||||
|             .await?; |             .await?; | ||||||
| @ -63,6 +64,7 @@ impl Account { | |||||||
|             return Err(Error::MinimalEscrow); |             return Err(Error::MinimalEscrow); | ||||||
|         } |         } | ||||||
|         let mut op_account = Self::get(db, wallet).await?; |         let mut op_account = Self::get(db, wallet).await?; | ||||||
|  |         let escrow = escrow.saturating_mul(TOKEN_DECIMAL); | ||||||
|         let op_total_balance = op_account.balance.saturating_add(op_account.escrow); |         let op_total_balance = op_account.balance.saturating_add(op_account.escrow); | ||||||
|         if op_total_balance < escrow { |         if op_total_balance < escrow { | ||||||
|             return Err(Error::InsufficientFunds); |             return Err(Error::InsufficientFunds); | ||||||
| @ -93,7 +95,7 @@ impl Account { | |||||||
|         let mut query_resp = db |         let mut query_resp = db | ||||||
|             .query(tx_query) |             .query(tx_query) | ||||||
|             .bind(("account_input", RecordId::from((ACCOUNT, account)))) |             .bind(("account_input", RecordId::from((ACCOUNT, account)))) | ||||||
|             .bind(("slash_amount", slash_amount)) |             .bind(("slash_amount", slash_amount.saturating_mul(TOKEN_DECIMAL))) | ||||||
|             .await?; |             .await?; | ||||||
| 
 | 
 | ||||||
|         log::trace!("query_resp: {query_resp:?}"); |         log::trace!("query_resp: {query_resp:?}"); | ||||||
| @ -257,6 +259,7 @@ pub struct Report { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl Report { | impl Report { | ||||||
|  |     // TODO: test this functionality and remove this comment
 | ||||||
|     pub async fn create( |     pub async fn create( | ||||||
|         db: &Surreal<Client>, |         db: &Surreal<Client>, | ||||||
|         from_account: RecordId, |         from_account: RecordId, | ||||||
|  | |||||||
| @ -49,10 +49,6 @@ pub enum Error { | |||||||
|     AlreadyBanned(String), |     AlreadyBanned(String), | ||||||
|     #[error("Failed to slash operator {0}")] |     #[error("Failed to slash operator {0}")] | ||||||
|     FailedToSlashOperator(String), |     FailedToSlashOperator(String), | ||||||
|     #[error("Transation Too Big {0}")] |  | ||||||
|     TooBigTransaction(String), |  | ||||||
|     #[error("Unknown: {0}")] |  | ||||||
|     Unknown(String), |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub mod prelude { | pub mod prelude { | ||||||
|  | |||||||
							
								
								
									
										224
									
								
								src/db/vm.rs
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										224
									
								
								src/db/vm.rs
									
									
									
									
									
								
							| @ -191,120 +191,62 @@ impl NewVmReq { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     pub async fn submit_error(db: &Surreal<Client>, id: &str, error: String) -> Result<(), Error> { |     pub async fn submit_error(db: &Surreal<Client>, id: &str, error: String) -> Result<(), Error> { | ||||||
|         let tx_query = String::from( |         #[derive(Serialize)] | ||||||
|             " |         struct NewVmError { | ||||||
|             BEGIN TRANSACTION; |             error: String, | ||||||
| 
 |  | ||||||
|                 LET $new_vm_req = $new_vm_req_input; |  | ||||||
|                 LET $error = $error_input; |  | ||||||
|                 LET $record = (select * from $new_vm_req)[0]; |  | ||||||
|                 LET $admin = $record.in; |  | ||||||
| 
 |  | ||||||
|                 if $record == None {{ |  | ||||||
|                     THROW 'vm req not exist ' + <string>$new_vm_req |  | ||||||
|                 }}; |  | ||||||
| 
 |  | ||||||
|                 UPDATE $new_vm_req SET error = $error; |  | ||||||
| 
 |  | ||||||
|                 UPDATE $admin SET tmp_locked -= $record.locked_nano; |  | ||||||
|                 UPDATE $admin SET balance += $record.locked_nano; |  | ||||||
| 
 |  | ||||||
|             COMMIT TRANSACTION;",
 |  | ||||||
|         ); |  | ||||||
| 
 |  | ||||||
|         log::trace!("submit_new_vm_err query: {tx_query}"); |  | ||||||
| 
 |  | ||||||
|         let mut query_resp = db |  | ||||||
|             .query(tx_query) |  | ||||||
|             .bind(("new_vm_req_input", RecordId::from((NEW_VM_REQ, id)))) |  | ||||||
|             .bind(("error_input", error)) |  | ||||||
|             .await?; |  | ||||||
| 
 |  | ||||||
|         let query_err = query_resp.take_errors(); |  | ||||||
|         if !query_err.is_empty() { |  | ||||||
|             log::trace!("errors in submit_new_vm_err: {query_err:?}"); |  | ||||||
|             let tx_fail_err_str = |  | ||||||
|                 String::from("The query was not executed due to a failed transaction"); |  | ||||||
| 
 |  | ||||||
|             if query_err.contains_key(&4) && query_err[&4].to_string() != tx_fail_err_str { |  | ||||||
|                 log::error!("vm req not exist: {}", query_err[&4]); |  | ||||||
|                 return Err(Error::ContractNotFound); |  | ||||||
|             } else { |  | ||||||
|                 log::error!("Unknown error in submit_new_vm_err: {query_err:?}"); |  | ||||||
|                 return Err(Error::Unknown("submit_new_vm_req".to_string())); |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
| 
 |         let _: Option<Self> = db.update((NEW_VM_REQ, id)).merge(NewVmError { error }).await?; | ||||||
|         Ok(()) |         Ok(()) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     pub async fn submit(self, db: &Surreal<Client>) -> Result<(), Error> { |     pub async fn submit(self, db: &Surreal<Client>) -> Result<(), Error> { | ||||||
|         let locked_nano = self.locked_nano; |         let locked_nano = self.locked_nano; | ||||||
|         let tx_query = format!(" |         let account = self.admin.key().to_string(); | ||||||
|  |         let vm_id = self.id.key().to_string(); | ||||||
|  |         let vm_node = self.vm_node.key().to_string(); | ||||||
|  |         // TODO: check for possible injection and maybe use .bind()
 | ||||||
|  |         let query = format!( | ||||||
|  |             " | ||||||
|             BEGIN TRANSACTION; |             BEGIN TRANSACTION; | ||||||
| 
 |             UPDATE account:{account} SET balance -= {locked_nano}; | ||||||
|                 LET $account = $account_input; |             IF account:{account}.balance < 0 {{ | ||||||
|                 LET $new_vm_req = $new_vm_req_input; |                 THROW 'Insufficient funds.' | ||||||
|                 LET $vm_node = $vm_node_input; |             }}; | ||||||
|                 LET $hostname = $hostname_input; |             UPDATE account:{account} SET tmp_locked += {locked_nano}; | ||||||
|                 LET $dtrfs_url = $dtrfs_url_input; |             RELATE | ||||||
|                 LET $dtrfs_sha = $dtrfs_sha_input; |                 account:{account} | ||||||
|                 LET $kernel_url = $kernel_url_input; |                 ->new_vm_req:{vm_id} | ||||||
|                 LET $kernel_sha = $kernel_sha_input; |                 ->vm_node:{vm_node} | ||||||
| 
 |             CONTENT {{ | ||||||
|                 UPDATE $account SET balance -= {locked_nano}; |                 created_at: time::now(), hostname: '{}', vcpus: {}, memory_mb: {}, disk_size_gb: {}, | ||||||
|                 IF $account.balance < 0 {{ |                 extra_ports: {:?}, public_ipv4: {:?}, public_ipv6: {:?}, | ||||||
|                     THROW 'Insufficient funds.' |                 dtrfs_url: '{}', dtrfs_sha: '{}', kernel_url: '{}', kernel_sha: '{}', | ||||||
|                 }}; |                 price_per_unit: {}, locked_nano: {locked_nano}, error: '' | ||||||
|                 UPDATE $account SET tmp_locked += {locked_nano}; |             }}; | ||||||
|                 RELATE |             COMMIT TRANSACTION; | ||||||
|                     $account |         ",
 | ||||||
|                     ->$new_vm_req |             self.hostname, | ||||||
|                     ->$vm_node |  | ||||||
|                 CONTENT {{ |  | ||||||
|                     created_at: time::now(), hostname: $hostname, vcpus: {}, memory_mb: {}, disk_size_gb: {}, |  | ||||||
|                     extra_ports: {:?}, public_ipv4: {}, public_ipv6: {}, |  | ||||||
|                     dtrfs_url: $dtrfs_url, dtrfs_sha: $dtrfs_sha, kernel_url: $kernel_url, kernel_sha: $kernel_sha, |  | ||||||
|                     price_per_unit: {}, locked_nano: {locked_nano}, error: '' |  | ||||||
|                 }}; |  | ||||||
|             
 |  | ||||||
|             COMMIT TRANSACTION;",
 |  | ||||||
|             self.vcpus, |             self.vcpus, | ||||||
|             self.memory_mb, |             self.memory_mb, | ||||||
|             self.disk_size_gb, |             self.disk_size_gb, | ||||||
|             self.extra_ports, |             self.extra_ports, | ||||||
|             self.public_ipv4, |             self.public_ipv4, | ||||||
|             self.public_ipv6, |             self.public_ipv6, | ||||||
|  |             self.dtrfs_url, | ||||||
|  |             self.dtrfs_sha, | ||||||
|  |             self.kernel_url, | ||||||
|  |             self.kernel_sha, | ||||||
|             self.price_per_unit |             self.price_per_unit | ||||||
|         ); |         ); | ||||||
|  |         //let _: Vec<Self> = db.insert(NEW_VM_REQ).relation(self).await?;
 | ||||||
|  |         let mut query_resp = db.query(query).await?; | ||||||
|  |         let resp_err = query_resp.take_errors(); | ||||||
| 
 | 
 | ||||||
|         log::trace!("submit_new_vm_req query: {tx_query}"); |         if let Some(surrealdb::Error::Api(surrealdb::error::Api::Query(tx_query_error))) = | ||||||
| 
 |             resp_err.get(&1) | ||||||
|         let mut query_resp = db |         { | ||||||
|             .query(tx_query) |             log::error!("Transaction error: {tx_query_error}"); | ||||||
|             .bind(("account_input", self.admin)) |             return Err(Error::InsufficientFunds); | ||||||
|             .bind(("new_vm_req_input", self.id)) |  | ||||||
|             .bind(("vm_node_input", self.vm_node)) |  | ||||||
|             .bind(("hostname_input", self.hostname)) |  | ||||||
|             .bind(("dtrfs_url_input", self.dtrfs_url)) |  | ||||||
|             .bind(("dtrfs_sha_input", self.dtrfs_sha)) |  | ||||||
|             .bind(("kernel_url_input", self.kernel_url)) |  | ||||||
|             .bind(("kernel_sha_input", self.kernel_sha)) |  | ||||||
|             .await?; |  | ||||||
| 
 |  | ||||||
|         let query_err = query_resp.take_errors(); |  | ||||||
|         if !query_err.is_empty() { |  | ||||||
|             log::trace!("errors in submit_new_vm_req: {query_err:?}"); |  | ||||||
|             let tx_fail_err_str = |  | ||||||
|                 String::from("The query was not executed due to a failed transaction"); |  | ||||||
| 
 |  | ||||||
|             if query_err.contains_key(&9) && query_err[&9].to_string() != tx_fail_err_str { |  | ||||||
|                 log::error!("Transaction error: {}", query_err[&9]); |  | ||||||
|                 return Err(Error::InsufficientFunds); |  | ||||||
|             } else { |  | ||||||
|                 log::error!("Unknown error in submit_new_vm_req: {query_err:?}"); |  | ||||||
|                 return Err(Error::Unknown("submit_new_vm_req".to_string())); |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         Ok(()) |         Ok(()) | ||||||
| @ -329,18 +271,14 @@ impl WrappedMeasurement { | |||||||
|             UPDATE_VM_REQ => UPDATE_VM_REQ, |             UPDATE_VM_REQ => UPDATE_VM_REQ, | ||||||
|             _ => NEW_VM_REQ, |             _ => NEW_VM_REQ, | ||||||
|         }; |         }; | ||||||
| 
 |         let mut resp = db | ||||||
|         let mut args_stream = db |             .query(format!("live select error from {table} where id = {NEW_VM_REQ}:{vm_id};")) | ||||||
|             .query(format!( |             .query(format!( | ||||||
|                 "live select * from measurement_args where id = measurement_args:{vm_id};" |                 "live select * from measurement_args where id = measurement_args:{vm_id};" | ||||||
|             )) |             )) | ||||||
|             .await? |             .await?; | ||||||
|             .stream::<Notification<vm_proto::MeasurementArgs>>(0)?; |         let mut error_stream = resp.stream::<Notification<ErrorFromTable>>(0)?; | ||||||
| 
 |         let mut args_stream = resp.stream::<Notification<vm_proto::MeasurementArgs>>(1)?; | ||||||
|         let mut error_stream = db |  | ||||||
|             .query(format!("live select error from {table} where id = {NEW_VM_REQ}:{vm_id};")) |  | ||||||
|             .await? |  | ||||||
|             .stream::<Notification<ErrorFromTable>>(0)?; |  | ||||||
| 
 | 
 | ||||||
|         let args: Option<vm_proto::MeasurementArgs> = |         let args: Option<vm_proto::MeasurementArgs> = | ||||||
|             db.delete(("measurement_args", vm_id)).await?; |             db.delete(("measurement_args", vm_id)).await?; | ||||||
| @ -554,78 +492,6 @@ impl ActiveVm { | |||||||
|             Ok(false) |             Ok(false) | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 |  | ||||||
|     pub async fn extend_time( |  | ||||||
|         db: &Surreal<Client>, |  | ||||||
|         id: &str, |  | ||||||
|         admin: &str, |  | ||||||
|         nano_lp: u64, |  | ||||||
|     ) -> Result<(), Error> { |  | ||||||
|         if nano_lp > 100_000_000_000_000 { |  | ||||||
|             return Err(Error::TooBigTransaction(nano_lp.to_string())); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         let tx_query = format!( |  | ||||||
|             " |  | ||||||
|             BEGIN TRANSACTION; |  | ||||||
| 
 |  | ||||||
|                 LET $contract = $contract_input; |  | ||||||
|                 LET $admin = $admin_input; |  | ||||||
|                 LET $lock_amt = {nano_lp}; |  | ||||||
| 
 |  | ||||||
|                 if !record::exists($contract) {{ |  | ||||||
|                     THROW 'contract not exist ' + <string>$contract |  | ||||||
|                 }}; |  | ||||||
|                 if $contract.in != $admin {{ |  | ||||||
|                     THROW 'Unauthorized' |  | ||||||
|                 }}; |  | ||||||
|                 if $admin.balance + $contract.locked_nano < $lock_amt {{ |  | ||||||
|                     THROW 'InsufficientFunds' |  | ||||||
|                 }}; |  | ||||||
| 
 |  | ||||||
|                 UPDATE $admin SET balance = $admin.balance + $contract.locked_nano - $lock_amt; |  | ||||||
|                 UPDATE $contract SET locked_nano = $lock_amt; |  | ||||||
| 
 |  | ||||||
|             COMMIT TRANSACTION; |  | ||||||
|             " |  | ||||||
|         ); |  | ||||||
| 
 |  | ||||||
|         log::trace!("extend_time query: {tx_query}"); |  | ||||||
| 
 |  | ||||||
|         let mut query_res = db |  | ||||||
|             .query(tx_query) |  | ||||||
|             .bind(("contract_input", RecordId::from((ACTIVE_VM, id)))) |  | ||||||
|             .bind(("admin_input", RecordId::from((ACCOUNT, admin)))) |  | ||||||
|             .await?; |  | ||||||
| 
 |  | ||||||
|         log::trace!("tx_query response: {query_res:?}"); |  | ||||||
| 
 |  | ||||||
|         let query_err = query_res.take_errors(); |  | ||||||
|         if !query_err.is_empty() { |  | ||||||
|             let tx_fail_err_str = |  | ||||||
|                 String::from("The query was not executed due to a failed transaction"); |  | ||||||
| 
 |  | ||||||
|             if query_err.contains_key(&3) && query_err[&3].to_string() != tx_fail_err_str { |  | ||||||
|                 log::error!("contract not exist: {}", query_err[&3]); |  | ||||||
|                 return Err(Error::ContractNotFound); |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             if query_err.contains_key(&4) && query_err[&4].to_string() != tx_fail_err_str { |  | ||||||
|                 log::error!("Unauthorized: {}", query_err[&4]); |  | ||||||
|                 return Err(Error::AccessDenied); |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             if query_err.contains_key(&5) && query_err[&5].to_string() != tx_fail_err_str { |  | ||||||
|                 log::error!("InsufficientFunds: {}", query_err[&5]); |  | ||||||
|                 return Err(Error::InsufficientFunds); |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             log::error!("Unknown error in extend_time: {query_err:?}"); |  | ||||||
| 
 |  | ||||||
|             return Err(Error::Unknown("extend_time".to_string())); |  | ||||||
|         } |  | ||||||
|         Ok(()) |  | ||||||
|     } |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[derive(Debug, Serialize, Deserialize)] | #[derive(Debug, Serialize, Deserialize)] | ||||||
|  | |||||||
| @ -313,26 +313,15 @@ impl BrainVmCli for VmCliServer { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     async fn extend_vm(&self, req: Request<ExtendVmReq>) -> Result<Response<Empty>, Status> { |     async fn extend_vm(&self, req: Request<ExtendVmReq>) -> Result<Response<Empty>, Status> { | ||||||
|         let req = check_sig_from_req(req)?; |         let _req = check_sig_from_req(req)?; | ||||||
|         match db::ActiveVm::extend_time(&self.db, &req.uuid, &req.admin_pubkey, req.locked_nano) |         todo!(); | ||||||
|             .await |         // match self
 | ||||||
|         { |         //     .data
 | ||||||
|             Ok(()) => Ok(Response::new(Empty {})), |         //     .extend_vm_contract_time(&req.uuid, &req.admin_pubkey, req.locked_nano)
 | ||||||
|             Err(e) |         // {
 | ||||||
|                 if matches!( |         //     Ok(()) => Ok(Response::new(Empty {})),
 | ||||||
|                     e, |         //     Err(e) => Err(Status::unknown(format!("Could not extend contract: {e}"))),
 | ||||||
|                     db::Error::ContractNotFound |         // }
 | ||||||
|                         | db::Error::AccessDenied |  | ||||||
|                         | db::Error::InsufficientFunds |  | ||||||
|                 ) => |  | ||||||
|             { |  | ||||||
|                 Err(Status::failed_precondition(e.to_string())) |  | ||||||
|             } |  | ||||||
|             Err(e) => { |  | ||||||
|                 log::error!("Error extending VM contract {}: {e}", &req.uuid); |  | ||||||
|                 Err(Status::unknown(format!("Could not extend contract: {e}"))) |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     async fn delete_vm(&self, req: Request<DeleteVmReq>) -> Result<Response<Empty>, Status> { |     async fn delete_vm(&self, req: Request<DeleteVmReq>) -> Result<Response<Empty>, Status> { | ||||||
|  | |||||||
| @ -7,7 +7,7 @@ use detee_shared::general_proto::{Account, AirdropReq, RegOperatorReq, ReportNod | |||||||
| use detee_shared::vm_proto; | use detee_shared::vm_proto; | ||||||
| use detee_shared::vm_proto::brain_vm_cli_client::BrainVmCliClient; | use detee_shared::vm_proto::brain_vm_cli_client::BrainVmCliClient; | ||||||
| use futures::StreamExt; | use futures::StreamExt; | ||||||
| use surreal_brain::constants::{ACTIVE_VM, NEW_VM_REQ, TOKEN_DECIMAL}; | use surreal_brain::constants::{ACTIVE_VM, NEW_VM_REQ}; | ||||||
| use surreal_brain::db::prelude as db; | use surreal_brain::db::prelude as db; | ||||||
| use surrealdb::engine::remote::ws::Client; | use surrealdb::engine::remote::ws::Client; | ||||||
| use surrealdb::Surreal; | use surrealdb::Surreal; | ||||||
| @ -15,7 +15,7 @@ use tonic::transport::Channel; | |||||||
| 
 | 
 | ||||||
| pub async fn airdrop(brain_channel: &Channel, wallet: &str, amount: u64) -> Result<()> { | pub async fn airdrop(brain_channel: &Channel, wallet: &str, amount: u64) -> Result<()> { | ||||||
|     let mut client = BrainGeneralCliClient::new(brain_channel.clone()); |     let mut client = BrainGeneralCliClient::new(brain_channel.clone()); | ||||||
|     let airdrop_req = AirdropReq { pubkey: wallet.to_string(), tokens: amount * TOKEN_DECIMAL }; |     let airdrop_req = AirdropReq { pubkey: wallet.to_string(), tokens: amount }; | ||||||
| 
 | 
 | ||||||
|     let admin_key = admin_keys()[0].clone(); |     let admin_key = admin_keys()[0].clone(); | ||||||
| 
 | 
 | ||||||
| @ -46,7 +46,7 @@ pub async fn create_new_vm( | |||||||
|     assert!(new_vm_resp.uuid.len() == 40); |     assert!(new_vm_resp.uuid.len() == 40); | ||||||
| 
 | 
 | ||||||
|     // wait for update db
 |     // wait for update db
 | ||||||
|     tokio::time::sleep(tokio::time::Duration::from_millis(100)).await; |     tokio::time::sleep(tokio::time::Duration::from_millis(700)).await; | ||||||
| 
 | 
 | ||||||
|     let vm_req_db: Option<db::NewVmReq> = db.select((NEW_VM_REQ, new_vm_resp.uuid.clone())).await?; |     let vm_req_db: Option<db::NewVmReq> = db.select((NEW_VM_REQ, new_vm_resp.uuid.clone())).await?; | ||||||
| 
 | 
 | ||||||
| @ -80,13 +80,10 @@ pub async fn report_node( | |||||||
|     Ok(client_gen_cli.report_node(key.sign_request(report_req)?).await?) |     Ok(client_gen_cli.report_node(key.sign_request(report_req)?).await?) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub async fn register_operator(brain_channel: &Channel, key: &Key, escrow_nano: u64) -> Result<()> { | pub async fn register_operator(brain_channel: &Channel, key: &Key, escrow: u64) -> Result<()> { | ||||||
|     let mut cli_client = BrainGeneralCliClient::new(brain_channel.clone()); |     let mut cli_client = BrainGeneralCliClient::new(brain_channel.clone()); | ||||||
|     let reg_req = RegOperatorReq { |     let reg_req = | ||||||
|         pubkey: key.pubkey.clone(), |         RegOperatorReq { pubkey: key.pubkey.clone(), escrow, email: "foo@bar.com".to_string() }; | ||||||
|         escrow: escrow_nano, |  | ||||||
|         email: "foo@bar.com".to_string(), |  | ||||||
|     }; |  | ||||||
| 
 | 
 | ||||||
|     cli_client.register_operator(key.sign_request(reg_req.clone()).unwrap()).await?; |     cli_client.register_operator(key.sign_request(reg_req.clone()).unwrap()).await?; | ||||||
|     Ok(()) |     Ok(()) | ||||||
| @ -164,38 +161,3 @@ pub async fn list_all_app_contracts( | |||||||
| 
 | 
 | ||||||
|     Ok(app_contracts) |     Ok(app_contracts) | ||||||
| } | } | ||||||
| 
 |  | ||||||
| pub async fn user_list_vm_contracts( |  | ||||||
|     brain_channel: &Channel, |  | ||||||
|     key: &Key, |  | ||||||
|     as_operator: bool, |  | ||||||
|     uuid: &str, |  | ||||||
| ) -> Result<Vec<vm_proto::VmContract>> { |  | ||||||
|     let mut cli_client = BrainVmCliClient::new(brain_channel.clone()); |  | ||||||
|     let mut stream = cli_client |  | ||||||
|         .list_vm_contracts( |  | ||||||
|             key.sign_request(vm_proto::ListVmContractsReq { |  | ||||||
|                 wallet: key.pubkey.clone(), |  | ||||||
|                 as_operator, |  | ||||||
|                 uuid: uuid.to_string(), |  | ||||||
|             }) |  | ||||||
|             .unwrap(), |  | ||||||
|         ) |  | ||||||
|         .await? |  | ||||||
|         .into_inner(); |  | ||||||
| 
 |  | ||||||
|     let mut vm_contracts = Vec::new(); |  | ||||||
| 
 |  | ||||||
|     while let Some(stream_data) = stream.next().await { |  | ||||||
|         match stream_data { |  | ||||||
|             Ok(vm_contract) => { |  | ||||||
|                 vm_contracts.push(vm_contract); |  | ||||||
|             } |  | ||||||
|             Err(e) => { |  | ||||||
|                 panic!("Error while listing vm_contracts: {e:?}"); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     Ok(vm_contracts) |  | ||||||
| } |  | ||||||
|  | |||||||
| @ -8,10 +8,7 @@ use tokio::sync::mpsc; | |||||||
| use tokio_stream::wrappers::ReceiverStream; | use tokio_stream::wrappers::ReceiverStream; | ||||||
| use tonic::transport::Channel; | use tonic::transport::Channel; | ||||||
| 
 | 
 | ||||||
| pub async fn mock_vm_daemon( | pub async fn mock_vm_daemon(brain_channel: &Channel) -> Result<String> { | ||||||
|     brain_channel: &Channel, |  | ||||||
|     daemon_error: Option<String>, |  | ||||||
| ) -> Result<String> { |  | ||||||
|     let mut daemon_client = BrainVmDaemonClient::new(brain_channel.clone()); |     let mut daemon_client = BrainVmDaemonClient::new(brain_channel.clone()); | ||||||
|     let daemon_key = Key::new(); |     let daemon_key = Key::new(); | ||||||
| 
 | 
 | ||||||
| @ -29,7 +26,7 @@ pub async fn mock_vm_daemon( | |||||||
|         rx, |         rx, | ||||||
|     )); |     )); | ||||||
| 
 | 
 | ||||||
|     tokio::spawn(daemon_engine(daemon_msg_tx.clone(), brain_msg_rx, daemon_error)); |     tokio::spawn(daemon_engine(daemon_msg_tx.clone(), brain_msg_rx)); | ||||||
| 
 | 
 | ||||||
|     tokio::time::sleep(tokio::time::Duration::from_secs(1)).await; |     tokio::time::sleep(tokio::time::Duration::from_secs(1)).await; | ||||||
| 
 | 
 | ||||||
| @ -105,7 +102,6 @@ pub async fn daemon_msg_sender( | |||||||
| pub async fn daemon_engine( | pub async fn daemon_engine( | ||||||
|     tx: mpsc::Sender<vm_proto::VmDaemonMessage>, |     tx: mpsc::Sender<vm_proto::VmDaemonMessage>, | ||||||
|     mut rx: mpsc::Receiver<vm_proto::BrainVmMessage>, |     mut rx: mpsc::Receiver<vm_proto::BrainVmMessage>, | ||||||
|     new_vm_err: Option<String>, |  | ||||||
| ) -> Result<()> { | ) -> Result<()> { | ||||||
|     log::info!("daemon engine vm_daemon"); |     log::info!("daemon engine vm_daemon"); | ||||||
|     while let Some(brain_msg) = rx.recv().await { |     while let Some(brain_msg) = rx.recv().await { | ||||||
| @ -124,7 +120,7 @@ pub async fn daemon_engine( | |||||||
|                 let new_vm_resp = vm_proto::NewVmResp { |                 let new_vm_resp = vm_proto::NewVmResp { | ||||||
|                     uuid: new_vm_req.uuid.clone(), |                     uuid: new_vm_req.uuid.clone(), | ||||||
|                     args, |                     args, | ||||||
|                     error: new_vm_err.clone().unwrap_or_default(), |                     error: String::new(), | ||||||
|                 }; |                 }; | ||||||
| 
 | 
 | ||||||
|                 let res_data = vm_proto::VmDaemonMessage { |                 let res_data = vm_proto::VmDaemonMessage { | ||||||
|  | |||||||
| @ -53,8 +53,7 @@ async fn test_general_airdrop() { | |||||||
|     let user_01_key = Key::new(); |     let user_01_key = Key::new(); | ||||||
|     let user_01_pubkey = user_01_key.pubkey.clone(); |     let user_01_pubkey = user_01_key.pubkey.clone(); | ||||||
| 
 | 
 | ||||||
|     let airdrop_req = |     let airdrop_req = AirdropReq { pubkey: user_01_pubkey.clone(), tokens: airdrop_amount }; | ||||||
|         AirdropReq { pubkey: user_01_pubkey.clone(), tokens: airdrop_amount * TOKEN_DECIMAL }; |  | ||||||
| 
 | 
 | ||||||
|     // user airdroping himself
 |     // user airdroping himself
 | ||||||
|     let err = |     let err = | ||||||
| @ -98,8 +97,7 @@ async fn test_general_airdrop() { | |||||||
|     assert_eq!(acc_bal_user_01.balance, 3 * airdrop_amount * TOKEN_DECIMAL); |     assert_eq!(acc_bal_user_01.balance, 3 * airdrop_amount * TOKEN_DECIMAL); | ||||||
| 
 | 
 | ||||||
|     // self airdrop
 |     // self airdrop
 | ||||||
|     let airdrop_req = |     let airdrop_req = AirdropReq { pubkey: admin_keys[2].pubkey.clone(), tokens: airdrop_amount }; | ||||||
|         AirdropReq { pubkey: admin_keys[2].pubkey.clone(), tokens: airdrop_amount * TOKEN_DECIMAL }; |  | ||||||
| 
 | 
 | ||||||
|     let _ = client.airdrop(admin_keys[2].sign_request(airdrop_req.clone()).unwrap()).await.unwrap(); |     let _ = client.airdrop(admin_keys[2].sign_request(airdrop_req.clone()).unwrap()).await.unwrap(); | ||||||
| 
 | 
 | ||||||
| @ -118,7 +116,7 @@ async fn test_report_node() { | |||||||
|     let db = prepare_test_db().await.unwrap(); |     let db = prepare_test_db().await.unwrap(); | ||||||
| 
 | 
 | ||||||
|     let brain_channel = run_service_for_stream().await.unwrap(); |     let brain_channel = run_service_for_stream().await.unwrap(); | ||||||
|     let daemon_key = mock_vm_daemon(&brain_channel, None).await.unwrap(); |     let daemon_key = mock_vm_daemon(&brain_channel).await.unwrap(); | ||||||
| 
 | 
 | ||||||
|     let key = Key::new(); |     let key = Key::new(); | ||||||
| 
 | 
 | ||||||
| @ -225,19 +223,17 @@ async fn test_register_operator() { | |||||||
|     let min_escrew_error = register_operator(&brain_channel, &key, 10).await.err().unwrap(); |     let min_escrew_error = register_operator(&brain_channel, &key, 10).await.err().unwrap(); | ||||||
|     assert!(min_escrew_error.to_string().contains("Minimum escrow amount is 5000")); |     assert!(min_escrew_error.to_string().contains("Minimum escrow amount is 5000")); | ||||||
| 
 | 
 | ||||||
|     let no_balance = |     let no_balance = register_operator(&brain_channel, &key, 5000).await.err().unwrap(); | ||||||
|         register_operator(&brain_channel, &key, 5000 * TOKEN_DECIMAL).await.err().unwrap(); |  | ||||||
|     assert!(no_balance.to_string().contains("Insufficient funds, deposit more tokens")); |     assert!(no_balance.to_string().contains("Insufficient funds, deposit more tokens")); | ||||||
| 
 | 
 | ||||||
|     airdrop(&brain_channel, &key.pubkey, 1000).await.unwrap(); |     airdrop(&brain_channel, &key.pubkey, 1000).await.unwrap(); | ||||||
| 
 | 
 | ||||||
|     let no_balance = |     let no_balance = register_operator(&brain_channel, &key, 5000).await.err().unwrap(); | ||||||
|         register_operator(&brain_channel, &key, 5000 * TOKEN_DECIMAL).await.err().unwrap(); |  | ||||||
|     assert!(no_balance.to_string().contains("Insufficient funds, deposit more tokens")); |     assert!(no_balance.to_string().contains("Insufficient funds, deposit more tokens")); | ||||||
| 
 | 
 | ||||||
|     airdrop(&brain_channel, &key.pubkey, 7000).await.unwrap(); |     airdrop(&brain_channel, &key.pubkey, 7000).await.unwrap(); | ||||||
| 
 | 
 | ||||||
|     register_operator(&brain_channel, &key, 6000 * TOKEN_DECIMAL).await.unwrap(); |     register_operator(&brain_channel, &key, 6000).await.unwrap(); | ||||||
| 
 | 
 | ||||||
|     let operator_account: Option<db::Account> = |     let operator_account: Option<db::Account> = | ||||||
|         db_conn.select((ACCOUNT, key.pubkey)).await.unwrap(); |         db_conn.select((ACCOUNT, key.pubkey)).await.unwrap(); | ||||||
| @ -360,9 +356,9 @@ async fn test_slash_operator() { | |||||||
|     let slash_amt = 2500; |     let slash_amt = 2500; | ||||||
| 
 | 
 | ||||||
|     airdrop(&brain_channel, &op_key.pubkey, 10000).await.unwrap(); |     airdrop(&brain_channel, &op_key.pubkey, 10000).await.unwrap(); | ||||||
|     register_operator(&brain_channel, &op_key, escrew * TOKEN_DECIMAL).await.unwrap(); |     register_operator(&brain_channel, &op_key, escrew).await.unwrap(); | ||||||
| 
 | 
 | ||||||
|     let raw_slash_req = SlashReq { pubkey: op_key.pubkey.clone(), tokens: 2500 * TOKEN_DECIMAL }; |     let raw_slash_req = SlashReq { pubkey: op_key.pubkey.clone(), tokens: 2500 }; | ||||||
| 
 | 
 | ||||||
|     let other_key = Key::new(); |     let other_key = Key::new(); | ||||||
|     let admin_error = cli_client |     let admin_error = cli_client | ||||||
| @ -403,9 +399,9 @@ async fn test_admin_list_account() { | |||||||
| 
 | 
 | ||||||
|     airdrop(&brain_channel, &Key::new().pubkey, 10).await.unwrap(); |     airdrop(&brain_channel, &Key::new().pubkey, 10).await.unwrap(); | ||||||
| 
 | 
 | ||||||
|     let accounts = list_accounts(&brain_channel, &admin_key).await.unwrap(); |  | ||||||
|     let acc_in_db = db_conn.select::<Vec<db::Account>>(ACCOUNT).await.unwrap(); |     let acc_in_db = db_conn.select::<Vec<db::Account>>(ACCOUNT).await.unwrap(); | ||||||
| 
 | 
 | ||||||
|  |     let accounts = list_accounts(&brain_channel, &admin_key).await.unwrap(); | ||||||
|     assert_eq!(accounts.len(), acc_in_db.len()); |     assert_eq!(accounts.len(), acc_in_db.len()); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,31 +1,24 @@ | |||||||
| use common::prepare_test_env::{prepare_test_db, run_service_for_stream}; | use common::prepare_test_env::{prepare_test_db, run_service_for_stream}; | ||||||
| use common::test_utils::Key; | use common::test_utils::Key; | ||||||
| use common::vm_cli_utils::{airdrop, create_new_vm, user_list_vm_contracts}; | use common::vm_cli_utils::{airdrop, create_new_vm}; | ||||||
| use common::vm_daemon_utils::{mock_vm_daemon, register_vm_node}; | use common::vm_daemon_utils::{mock_vm_daemon, register_vm_node}; | ||||||
| use detee_shared::vm_proto; |  | ||||||
| use detee_shared::vm_proto::brain_vm_cli_client::BrainVmCliClient; | use detee_shared::vm_proto::brain_vm_cli_client::BrainVmCliClient; | ||||||
| use detee_shared::vm_proto::brain_vm_daemon_client::BrainVmDaemonClient; | use detee_shared::vm_proto::brain_vm_daemon_client::BrainVmDaemonClient; | ||||||
| use detee_shared::vm_proto::{ExtendVmReq, ListVmContractsReq, NewVmReq}; | use detee_shared::vm_proto::{ListVmContractsReq, NewVmReq}; | ||||||
| use futures::StreamExt; | use futures::StreamExt; | ||||||
| use std::vec; | use std::vec; | ||||||
| use surreal_brain::constants::{ACCOUNT, ACTIVE_VM, NEW_VM_REQ, TOKEN_DECIMAL}; | use surreal_brain::constants::ACTIVE_VM; | ||||||
| use surreal_brain::db::prelude as db; | use surreal_brain::db::vm::ActiveVm; | ||||||
| 
 | 
 | ||||||
| mod common; | mod common; | ||||||
| 
 | 
 | ||||||
| #[tokio::test] | #[tokio::test] | ||||||
| async fn test_vm_creation() { | async fn test_vm_creation() { | ||||||
|     let db = prepare_test_db().await.unwrap(); |     let db = prepare_test_db().await.unwrap(); | ||||||
|     /* |     // env_logger::builder().filter_level(log::LevelFilter::Error).init();
 | ||||||
|     env_logger::builder() |  | ||||||
|         .filter_level(log::LevelFilter::Debug) |  | ||||||
|         .filter_module("tungstenite", log::LevelFilter::Debug) |  | ||||||
|         .filter_module("tokio_tungstenite", log::LevelFilter::Debug) |  | ||||||
|         .init(); |  | ||||||
|     */ |  | ||||||
| 
 | 
 | ||||||
|     let brain_channel = run_service_for_stream().await.unwrap(); |     let brain_channel = run_service_for_stream().await.unwrap(); | ||||||
|     let daemon_key = mock_vm_daemon(&brain_channel, None).await.unwrap(); |     let daemon_key = mock_vm_daemon(&brain_channel).await.unwrap(); | ||||||
| 
 | 
 | ||||||
|     let key = Key::new(); |     let key = Key::new(); | ||||||
| 
 | 
 | ||||||
| @ -35,60 +28,11 @@ async fn test_vm_creation() { | |||||||
|     let grpc_error_message = new_vm_resp.err().unwrap().to_string(); |     let grpc_error_message = new_vm_resp.err().unwrap().to_string(); | ||||||
|     assert!(grpc_error_message.contains("Insufficient funds")); |     assert!(grpc_error_message.contains("Insufficient funds")); | ||||||
| 
 | 
 | ||||||
|     let airdrop_amount = 10; |     airdrop(&brain_channel, &key.pubkey, 10).await.unwrap(); | ||||||
|     airdrop(&brain_channel, &key.pubkey, airdrop_amount).await.unwrap(); |  | ||||||
| 
 | 
 | ||||||
|     let new_vm_id = create_new_vm(&db, &key, &daemon_key, &brain_channel).await.unwrap(); |     let new_vm_id = create_new_vm(&db, &key, &daemon_key, &brain_channel).await.unwrap(); | ||||||
|     let active_vm: Option<db::ActiveVm> = db.select((ACTIVE_VM, new_vm_id)).await.unwrap(); |     let active_vm: Option<ActiveVm> = db.select((ACTIVE_VM, new_vm_id)).await.unwrap(); | ||||||
|     assert!(active_vm.is_some()); |     assert!(active_vm.is_some()); | ||||||
| 
 |  | ||||||
|     let daemon_key_02 = |  | ||||||
|         mock_vm_daemon(&brain_channel, Some("something went wrong 04".to_string())).await.unwrap(); |  | ||||||
| 
 |  | ||||||
|     let locking_nano = 100; |  | ||||||
|     let mut new_vm_req = vm_proto::NewVmReq { |  | ||||||
|         admin_pubkey: key.pubkey.clone(), |  | ||||||
|         node_pubkey: daemon_key_02.clone(), |  | ||||||
|         price_per_unit: 1200, |  | ||||||
|         extra_ports: vec![8080, 8081], |  | ||||||
|         locked_nano: locking_nano, |  | ||||||
|         ..Default::default() |  | ||||||
|     }; |  | ||||||
| 
 |  | ||||||
|     let mut client_vm_cli = BrainVmCliClient::new(brain_channel.clone()); |  | ||||||
|     let new_vm_resp = client_vm_cli |  | ||||||
|         .new_vm(key.sign_request(new_vm_req.clone()).unwrap()) |  | ||||||
|         .await |  | ||||||
|         .unwrap() |  | ||||||
|         .into_inner(); |  | ||||||
| 
 |  | ||||||
|     assert!(!new_vm_resp.error.is_empty()); |  | ||||||
| 
 |  | ||||||
|     let vm_req_db: Option<db::NewVmReq> = |  | ||||||
|         db.select((NEW_VM_REQ, new_vm_resp.uuid.clone())).await.unwrap(); |  | ||||||
| 
 |  | ||||||
|     if let Some(new_vm_req) = vm_req_db { |  | ||||||
|         assert!(!new_vm_req.error.is_empty()); |  | ||||||
|         assert_eq!(new_vm_resp.error, new_vm_req.error); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     let acc_db: db::Account = db.select((ACCOUNT, key.pubkey.clone())).await.unwrap().unwrap(); |  | ||||||
|     assert_eq!(acc_db.balance, airdrop_amount * TOKEN_DECIMAL); |  | ||||||
|     assert_eq!(acc_db.tmp_locked, 0); |  | ||||||
| 
 |  | ||||||
|     new_vm_req.node_pubkey = daemon_key; |  | ||||||
| 
 |  | ||||||
|     let new_vm_resp = |  | ||||||
|         client_vm_cli.new_vm(key.sign_request(new_vm_req).unwrap()).await.unwrap().into_inner(); |  | ||||||
|     assert!(new_vm_resp.error.is_empty()); |  | ||||||
| 
 |  | ||||||
|     tokio::time::sleep(tokio::time::Duration::from_millis(100)).await; |  | ||||||
|     let active_vm: Option<db::ActiveVm> = db.select((ACTIVE_VM, new_vm_resp.uuid)).await.unwrap(); |  | ||||||
|     assert!(active_vm.is_some()); |  | ||||||
| 
 |  | ||||||
|     let acc_db: db::Account = db.select((ACCOUNT, key.pubkey.clone())).await.unwrap().unwrap(); |  | ||||||
|     assert_eq!(acc_db.balance, airdrop_amount * TOKEN_DECIMAL - locking_nano); |  | ||||||
|     assert_eq!(acc_db.tmp_locked, 0); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[tokio::test] | #[tokio::test] | ||||||
| @ -158,85 +102,3 @@ async fn test_list_vm_contracts() { | |||||||
| 
 | 
 | ||||||
|     // verify report in db
 |     // verify report in db
 | ||||||
| } | } | ||||||
| 
 |  | ||||||
| /* |  | ||||||
| Private Key: 69kPgwAzftzNf5oBFQwqocFAgsn17ZwKxCHFvpoZ1LRn |  | ||||||
| Public Key : HYo88ncAPekykFDTFGdJV9ehJ81LL4onQ8xzYRAu2Ph4 |  | ||||||
| 
 |  | ||||||
| Public Key : Hv5q3enK249RUnLRLi9YNQMrPCRxvL2XnhznkzrtCmkG // operator
 |  | ||||||
| Private Key: 2oQvpUMSzaZmaVLfVWsriRbhRK1JbnPEBed5UmpZSDNc */ |  | ||||||
| 
 |  | ||||||
| #[tokio::test] |  | ||||||
| async fn test_extend_vm() { |  | ||||||
|     let db_conn = prepare_test_db().await.unwrap(); |  | ||||||
| 
 |  | ||||||
|     let channel = run_service_for_stream().await.unwrap(); |  | ||||||
|     let mut cli_client = BrainVmCliClient::new(channel.clone()); |  | ||||||
| 
 |  | ||||||
|     /* |  | ||||||
|     env_logger::builder() |  | ||||||
|         .filter_level(log::LevelFilter::Debug) |  | ||||||
|         .filter_module("tungstenite", log::LevelFilter::Debug) |  | ||||||
|         .filter_module("tokio_tungstenite", log::LevelFilter::Debug) |  | ||||||
|         .init(); |  | ||||||
|      */ |  | ||||||
| 
 |  | ||||||
|     let key = Key::from("YnaZccN852KYvnhV5pbeBrHV4dSwgzpQXghdyMiHC6i"); // GmE4JH3bL4NpmzwKCBJemJzRTumJAnbcXLGqce5mREgS admin
 |  | ||||||
|     let vm_contract_id = "1d749a816c27a22efa0e574b023a6afef040fe5"; |  | ||||||
| 
 |  | ||||||
|     let locking_01 = 200; |  | ||||||
|     let locking_02 = 86000000000u64; |  | ||||||
| 
 |  | ||||||
|     let mut req = ExtendVmReq { |  | ||||||
|         admin_pubkey: key.pubkey.clone(), |  | ||||||
|         uuid: "foooooooo".to_string(), |  | ||||||
|         locked_nano: u64::MAX, |  | ||||||
|     }; |  | ||||||
| 
 |  | ||||||
|     let err_precondition = |  | ||||||
|         cli_client.extend_vm(key.sign_request(req.clone()).unwrap()).await.err().unwrap(); |  | ||||||
|     assert!(err_precondition.to_string().contains("Transation Too Big ")); |  | ||||||
| 
 |  | ||||||
|     req.locked_nano = 99999999999999; |  | ||||||
|     let err_precondition = |  | ||||||
|         cli_client.extend_vm(key.sign_request(req.clone()).unwrap()).await.err().unwrap(); |  | ||||||
|     assert!(err_precondition.to_string().contains("Contract not found")); |  | ||||||
| 
 |  | ||||||
|     req.uuid = vm_contract_id.to_string(); |  | ||||||
|     let err_precondition = |  | ||||||
|         cli_client.extend_vm(key.sign_request(req.clone()).unwrap()).await.err().unwrap(); |  | ||||||
|     assert!(err_precondition.to_string().contains("Insufficient funds")); |  | ||||||
| 
 |  | ||||||
|     req.locked_nano = locking_01; |  | ||||||
|     let err_precondition = |  | ||||||
|         cli_client.extend_vm(Key::new().sign_request(req.clone()).unwrap()).await.err().unwrap(); |  | ||||||
|     assert!(err_precondition.to_string().contains("signature does not match")); |  | ||||||
| 
 |  | ||||||
|     let acc: db::Account = db_conn.select((ACCOUNT, key.pubkey.clone())).await.unwrap().unwrap(); |  | ||||||
|     let contract: db::ActiveVm = |  | ||||||
|         db_conn.select((ACTIVE_VM, vm_contract_id)).await.unwrap().unwrap(); |  | ||||||
| 
 |  | ||||||
|     let expected_bal_01 = |  | ||||||
|         (acc.balance as i128 + (contract.locked_nano as i128 - locking_01 as i128)) as u64; |  | ||||||
| 
 |  | ||||||
|     cli_client.extend_vm(key.sign_request(req.clone()).unwrap()).await.unwrap(); |  | ||||||
| 
 |  | ||||||
|     let contract = &user_list_vm_contracts(&channel, &key, false, vm_contract_id).await.unwrap()[0]; |  | ||||||
|     assert_eq!(contract.locked_nano, locking_01); |  | ||||||
| 
 |  | ||||||
|     let acc: db::Account = db_conn.select((ACCOUNT, key.pubkey.clone())).await.unwrap().unwrap(); |  | ||||||
|     assert_eq!(acc.balance, expected_bal_01); |  | ||||||
| 
 |  | ||||||
|     let expected_bal_02 = |  | ||||||
|         (acc.balance as i128 + (contract.locked_nano as i128 - locking_02 as i128)) as u64; |  | ||||||
| 
 |  | ||||||
|     req.locked_nano = locking_02; |  | ||||||
| 
 |  | ||||||
|     cli_client.extend_vm(key.sign_request(req.clone()).unwrap()).await.unwrap(); |  | ||||||
| 
 |  | ||||||
|     let contract = &user_list_vm_contracts(&channel, &key, false, vm_contract_id).await.unwrap()[0]; |  | ||||||
|     assert_eq!(contract.locked_nano, locking_02); |  | ||||||
| 
 |  | ||||||
|     let acc: db::Account = db_conn.select((ACCOUNT, key.pubkey.clone())).await.unwrap().unwrap(); |  | ||||||
|     assert_eq!(acc.balance, expected_bal_02); |  | ||||||
| } |  | ||||||
|  | |||||||
| @ -29,7 +29,7 @@ async fn test_brain_message() { | |||||||
|     prepare_test_db().await.unwrap(); |     prepare_test_db().await.unwrap(); | ||||||
| 
 | 
 | ||||||
|     let brain_channel = run_service_for_stream().await.unwrap(); |     let brain_channel = run_service_for_stream().await.unwrap(); | ||||||
|     let daemon_key = mock_vm_daemon(&brain_channel, None).await.unwrap(); |     let daemon_key = mock_vm_daemon(&brain_channel).await.unwrap(); | ||||||
|     let mut cli_client = BrainVmCliClient::new(brain_channel.clone()); |     let mut cli_client = BrainVmCliClient::new(brain_channel.clone()); | ||||||
| 
 | 
 | ||||||
|     let cli_key = Key::new(); |     let cli_key = Key::new(); | ||||||
|  | |||||||
| @ -114,18 +114,6 @@ accounts: | |||||||
|     kicked_for: [] |     kicked_for: [] | ||||||
|     last_kick: 1970-01-01T00:00:00Z |     last_kick: 1970-01-01T00:00:00Z | ||||||
|     banned_by: [] |     banned_by: [] | ||||||
|   Hv5q3enK249RUnLRLi9YNQMrPCRxvL2XnhznkzrtCmkG: |  | ||||||
|     balance: 25949200000 |  | ||||||
|     tmp_locked: 0 |  | ||||||
|     kicked_for: [] |  | ||||||
|     last_kick: 1970-01-01T00:00:00Z |  | ||||||
|     banned_by: [] |  | ||||||
|   GmE4JH3bL4NpmzwKCBJemJzRTumJAnbcXLGqce5mREgS: |  | ||||||
|     balance: 500000000000 |  | ||||||
|     tmp_locked: 0 |  | ||||||
|     kicked_for: [] |  | ||||||
|     last_kick: 1970-01-01T00:00:00Z |  | ||||||
|     banned_by: [] |  | ||||||
| 
 | 
 | ||||||
| operators: | operators: | ||||||
|   BFopWmwcZAMF1h2PFECZNdEucdZfnZZ32p6R9ZaBiVsS: |   BFopWmwcZAMF1h2PFECZNdEucdZfnZZ32p6R9ZaBiVsS: | ||||||
| @ -163,14 +151,6 @@ operators: | |||||||
|       - 7fujZQeTme52RdXTLmQST5jBgAbvzic5iERtH5EWoYjk |       - 7fujZQeTme52RdXTLmQST5jBgAbvzic5iERtH5EWoYjk | ||||||
|     app_nodes: [] |     app_nodes: [] | ||||||
| 
 | 
 | ||||||
|   Hv5q3enK249RUnLRLi9YNQMrPCRxvL2XnhznkzrtCmkG: |  | ||||||
|     escrow: 5499700480000 |  | ||||||
|     email: "test_mock_extend@operator" |  | ||||||
|     banned_users: [] |  | ||||||
|     vm_nodes: |  | ||||||
|       - 8ue3VHMnJg2i8pwTQ6mJtvYuS2kd9n1XLLco8GUPfT95 |  | ||||||
|     app_nodes: [] |  | ||||||
| 
 |  | ||||||
| vm_nodes: | vm_nodes: | ||||||
|   - public_key: 7Xw3RxbP5pvfjZ8U6yA3HHVSS9YXjKH5Vkas3JRbQYd9 |   - public_key: 7Xw3RxbP5pvfjZ8U6yA3HHVSS9YXjKH5Vkas3JRbQYd9 | ||||||
|     operator_wallet: x52w7jARC5erhWWK65VZmjdGXzBK6ZDgfv1A283d8XK |     operator_wallet: x52w7jARC5erhWWK65VZmjdGXzBK6ZDgfv1A283d8XK | ||||||
| @ -285,22 +265,6 @@ vm_nodes: | |||||||
|     price: 24000 |     price: 24000 | ||||||
|     reports: {} |     reports: {} | ||||||
|     offline_minutes: 0 |     offline_minutes: 0 | ||||||
|   - public_key: 8ue3VHMnJg2i8pwTQ6mJtvYuS2kd9n1XLLco8GUPfT95 |  | ||||||
|     operator_wallet: Hv5q3enK249RUnLRLi9YNQMrPCRxvL2XnhznkzrtCmkG |  | ||||||
|     country: GB |  | ||||||
|     region: England |  | ||||||
|     city: London |  | ||||||
|     ip: 193.234.17.2 |  | ||||||
|     avail_mem_mb: 28000 |  | ||||||
|     avail_vcpus: 24 |  | ||||||
|     avail_storage_gbs: 1680 |  | ||||||
|     avail_ipv4: 1 |  | ||||||
|     avail_ipv6: 0 |  | ||||||
|     avail_ports: 19999 |  | ||||||
|     max_ports_per_vm: 10 |  | ||||||
|     price: 24000 |  | ||||||
|     reports: {} |  | ||||||
|     offline_minutes: 0 |  | ||||||
| 
 | 
 | ||||||
| vm_contracts: | vm_contracts: | ||||||
|   - uuid: 958165e3-dea8-407d-8c42-dd17002ef79c |   - uuid: 958165e3-dea8-407d-8c42-dd17002ef79c | ||||||
| @ -442,24 +406,6 @@ vm_contracts: | |||||||
|     locked_nano: 12730960000 |     locked_nano: 12730960000 | ||||||
|     collected_at: 2025-04-20T00:34:15.461240342Z |     collected_at: 2025-04-20T00:34:15.461240342Z | ||||||
| 
 | 
 | ||||||
|   - uuid: 1d749a81-6c27-a22e-fa0e574-b023-a6afef040fe5 |  | ||||||
|     hostname: test-extend |  | ||||||
|     admin_pubkey: GmE4JH3bL4NpmzwKCBJemJzRTumJAnbcXLGqce5mREgS |  | ||||||
|     node_pubkey: 8ue3VHMnJg2i8pwTQ6mJtvYuS2kd9n1XLLco8GUPfT95 |  | ||||||
|     exposed_ports: |  | ||||||
|       - 46393 |  | ||||||
|     public_ipv4: "" |  | ||||||
|     public_ipv6: "" |  | ||||||
|     disk_size_gb: 10 |  | ||||||
|     vcpus: 1 |  | ||||||
|     memory_mb: 1000 |  | ||||||
|     kernel_sha: e765e56166ef321b53399b9638584d1279821dbe3d46191c1f66bbaa075e7919 |  | ||||||
|     dtrfs_sha: d207644ee60d54009b6ecdfb720e2ec251cde31774dd249fcc7435aca0377990 |  | ||||||
|     created_at: 2025-04-16T20:37:57.176592933Z |  | ||||||
|     updated_at: 2025-04-16T20:37:57.176594069Z |  | ||||||
|     price_per_unit: 20000 |  | ||||||
|     locked_nano: 60000 |  | ||||||
|     collected_at: 2025-04-20T00:34:15.461240342Z |  | ||||||
|   - uuid: 5af49a71-4c64-a82e-f50e574-b023-b2a0ef0405ed |   - uuid: 5af49a71-4c64-a82e-f50e574-b023-b2a0ef0405ed | ||||||
|     hostname: hallow-hobo |     hostname: hallow-hobo | ||||||
|     admin_pubkey: 4qFJJJdRrSB9hCn8rrvYTXHLJg371ab36PJmZ4uxHjGQ |     admin_pubkey: 4qFJJJdRrSB9hCn8rrvYTXHLJg371ab36PJmZ4uxHjGQ | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user