diff --git a/src/constants.rs b/src/constants.rs index 33cc61f..0679043 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -24,6 +24,7 @@ pub const OLD_BRAIN_DATA_PATH: &str = "./saved_data.yaml"; pub const ACCOUNT: &str = "account"; pub const KICK: &str = "kick"; +pub const BAN: &str = "ban"; pub const VM_NODE: &str = "vm_node"; pub const ACTIVE_VM: &str = "active_vm"; diff --git a/src/db/general.rs b/src/db/general.rs index 7597e7a..952cfab 100644 --- a/src/db/general.rs +++ b/src/db/general.rs @@ -1,5 +1,5 @@ use super::Error; -use crate::constants::{ACCOUNT, KICK, MIN_ESCROW, TOKEN_DECIMAL}; +use crate::constants::{ACCOUNT, BAN, KICK, MIN_ESCROW, TOKEN_DECIMAL, VM_NODE}; use crate::db::prelude::*; use crate::old_brain; use serde::{Deserialize, Serialize}; @@ -86,20 +86,24 @@ impl Account { let mut query_response = db .query(format!( "(select operator->ban[0] as ban - from vm_node:{node} - where operator->ban->account contains account:{user} + from $vm_node_input + where operator->ban->account contains $user_account_input ).ban;" )) + .bind(("vm_node_input", RecordId::from((VM_NODE, node)))) + .bind(("user_account_input", RecordId::from((ACCOUNT, user)))) .query(format!( "(select operator->ban[0] as ban - from app_node:{node} - where operator->ban->account contains account:{user} + from $app_node_input + where operator->ban->account contains $user_account_input ).ban;" )) + .bind(("app_node_input", RecordId::from((APP_NODE, node)))) + .bind(("user_account_input", RecordId::from((ACCOUNT, user)))) .await?; - let vm_node_ban: Option = query_response.take(0)?; - let app_node_ban: Option = query_response.take(1)?; + let vm_node_ban: Option = query_response.take(0).unwrap(); + let app_node_ban: Option = query_response.take(1).unwrap(); Ok(vm_node_ban.is_some() || app_node_ban.is_some()) } @@ -128,12 +132,48 @@ impl From<&old_brain::BrainData> for Vec { #[derive(Debug, Serialize, Deserialize)] pub struct Ban { - id: RecordId, #[serde(rename = "in")] - from_account: RecordId, + pub from_account: RecordId, #[serde(rename = "out")] - to_account: RecordId, - created_at: Datetime, + pub to_account: RecordId, + pub created_at: Datetime, +} + +impl Ban { + pub async fn get_record_by_wallets( + db: &Surreal, + op_wallet: &str, + user_wallet: &str, + ) -> Result, Error> { + let query = + format!("SELECT * FROM {BAN} WHERE in = $operator_input AND out = $user_input;"); + let mut response = db + .query(query) + .bind(("operator_input", RecordId::from((ACCOUNT, op_wallet)))) + .bind(("user_input", RecordId::from((ACCOUNT, user_wallet)))) + .await?; + let ban_record: Option = response.take(0)?; + Ok(ban_record) + } + + pub async fn ban_a_user( + db: &Surreal, + op_wallet: &str, + user_wallet: &str, + ) -> Result<(), Error> { + if Self::get_record_by_wallets(db, op_wallet, user_wallet).await?.is_some() { + return Err(Error::AlreadyBanned(op_wallet.to_string())); + } + let _: Vec = db + .insert(BAN) + .relation(Self { + from_account: RecordId::from((ACCOUNT, op_wallet)), + to_account: RecordId::from((ACCOUNT, user_wallet)), + created_at: Default::default(), + }) + .await?; + Ok(()) + } } #[derive(Debug, Serialize, Deserialize)] diff --git a/src/db/mod.rs b/src/db/mod.rs index cd06be1..0f66625 100644 --- a/src/db/mod.rs +++ b/src/db/mod.rs @@ -45,6 +45,8 @@ pub enum Error { FailedToDeleteContract(String), #[error("Failed to kick contract {0}")] FailedKickContract(String), + #[error("Already banned {0}")] + AlreadyBanned(String), } pub mod prelude { diff --git a/src/grpc/general.rs b/src/grpc/general.rs index cf3bf2b..fa97751 100644 --- a/src/grpc/general.rs +++ b/src/grpc/general.rs @@ -152,11 +152,10 @@ impl BrainGeneralCli for GeneralCliServer { } } - async fn ban_user(&self, _req: Request) -> Result, Status> { - todo!(); - // let req = check_sig_from_req(req)?; - // self.data.ban_user(&req.operator_wallet, &req.user_wallet); - // Ok(Response::new(Empty {})) + async fn ban_user(&self, req: Request) -> Result, Status> { + let req = check_sig_from_req(req)?; + db::Ban::ban_a_user(&self.db, &req.operator_wallet, &req.user_wallet).await?; + Ok(Response::new(Empty {})) } // admin commands diff --git a/surql/tables.sql b/surql/tables.sql index 0071da4..4ab0a99 100644 --- a/surql/tables.sql +++ b/surql/tables.sql @@ -129,14 +129,14 @@ DEFINE FIELD vcpus ON TABLE deleted_app TYPE int; DEFINE FIELD memory_mb ON TABLE deleted_app TYPE int; DEFINE FIELD disk_size_gb ON TABLE deleted_app TYPE int; DEFINE FIELD created_at ON TABLE deleted_app TYPE datetime; -DEFINE FIELD deleted_at ON TABLE deleted_app TYPE datetime DEFAULT time::now();; +DEFINE FIELD deleted_at ON TABLE deleted_app TYPE datetime DEFAULT time::now(); DEFINE FIELD price_per_unit ON TABLE deleted_app TYPE int; DEFINE FIELD mr_enclave ON TABLE deleted_app TYPE string; DEFINE FIELD package_url ON TABLE deleted_app TYPE string; DEFINE FIELD hratls_pubkey ON TABLE deleted_app TYPE string; DEFINE TABLE ban TYPE RELATION FROM account TO account; -DEFINE FIELD created_at ON TABLE ban TYPE datetime; +DEFINE FIELD created_at ON TABLE ban TYPE datetime DEFAULT time::now();; DEFINE TABLE kick TYPE RELATION FROM account TO account; DEFINE FIELD created_at ON TABLE kick TYPE datetime; diff --git a/tests/common/prepare_test_env.rs b/tests/common/prepare_test_env.rs index 96a8587..42e6e0c 100644 --- a/tests/common/prepare_test_env.rs +++ b/tests/common/prepare_test_env.rs @@ -1,4 +1,4 @@ -use anyhow::{anyhow, Result}; +use anyhow::Result; use detee_shared::general_proto::brain_general_cli_server::BrainGeneralCliServer; use detee_shared::vm_proto::brain_vm_cli_server::BrainVmCliServer; use detee_shared::vm_proto::brain_vm_daemon_server::BrainVmDaemonServer; @@ -31,14 +31,15 @@ pub async fn prepare_test_db() -> Result> { let db = surreal_brain::db::db_connection(&db_url, &db_user, &db_pass, db_ns, db_name).await?; DB_STATE .get_or_init(|| async { - let old_brain_data = surreal_brain::old_brain::BrainData::load_from_disk() - .map_err(|e| anyhow!(e.to_string()))?; + let raw_mock_data = std::fs::read_to_string("tests/mock_data.yaml")?; + let mock_data: surreal_brain::old_brain::BrainData = + serde_yaml::from_str(&raw_mock_data)?; db.query(format!("REMOVE DATABASE {db_name}")).await?; for schema in DB_SCHEMA_FILES.map(std::fs::read_to_string) { db.query(schema?).await?; } - surreal_brain::db::migration0(&db, &old_brain_data).await?; + surreal_brain::db::migration0(&db, &mock_data).await?; Ok::<(), anyhow::Error>(()) }) .await; diff --git a/tests/common/test_utils.rs b/tests/common/test_utils.rs index 5ae3fae..a99efb0 100644 --- a/tests/common/test_utils.rs +++ b/tests/common/test_utils.rs @@ -32,6 +32,17 @@ impl Key { Key { sg_key: sk, pubkey } } + pub fn from(private_key: &str) -> Self { + let signing_key: SigningKey = bs58::decode(private_key) + .into_vec() + .expect("Failed to decode private key") + .as_slice() + .try_into() + .expect("Failed to convert to SigningKey"); + let pubkey = bs58::encode(signing_key.verifying_key().to_bytes()).into_string(); + Key { sg_key: signing_key, pubkey } + } + pub fn sign_request(&self, req: T) -> Result> { let pubkey = self.pubkey.clone(); let timestamp = chrono::Utc::now().to_rfc3339(); diff --git a/tests/grpc_general_test.rs b/tests/grpc_general_test.rs index e57c35b..b0a1092 100644 --- a/tests/grpc_general_test.rs +++ b/tests/grpc_general_test.rs @@ -6,10 +6,11 @@ use common::vm_cli_utils::{airdrop, create_new_vm, report_node}; use common::vm_daemon_utils::{mock_vm_daemon, register_vm_node}; use detee_shared::common_proto::{Empty, Pubkey}; use detee_shared::general_proto::brain_general_cli_client::BrainGeneralCliClient; -use detee_shared::general_proto::AirdropReq; +use detee_shared::general_proto::{AirdropReq, BanUserReq}; use detee_shared::vm_proto::brain_vm_daemon_client::BrainVmDaemonClient; use futures::StreamExt; -use surreal_brain::constants::{TOKEN_DECIMAL, VM_NODE}; +use surreal_brain::constants::{BAN, TOKEN_DECIMAL, VM_NODE}; +use surreal_brain::db::prelude as db; use surreal_brain::db::vm::VmNodeWithReports; mod common; @@ -221,11 +222,13 @@ async fn test_kick_contract() { // 6. refund amount calculation // 7. refund of multiple contract kick in a day for same user + /* env_logger::builder() .filter_level(log::LevelFilter::Info) .filter_module("tungstenite", log::LevelFilter::Debug) .filter_module("tokio_tungstenite", log::LevelFilter::Debug) .init(); + */ let db_conn = prepare_test_db().await.unwrap(); let contract_uuid = "e3d01f252b2a410b80e312f44e474334"; @@ -244,3 +247,64 @@ async fn test_kick_contract() { } } } + +#[tokio::test] +async fn test_ban_user() { + let db_conn = prepare_test_db().await.unwrap(); + + let brain_channel = run_service_for_stream().await.unwrap(); + let mut cli_client = BrainGeneralCliClient::new(brain_channel.clone()); + let op_key = Key::from("6f3WcQuv8sPrxAsSh24TdXkauwVd8vFUyCCfbNqxszvR"); // "4qFJJJdRrSB9hCn8rrvYTXHLJg371ab36PJmZ4uxHjGQ" + let user_key = Key::new(); + let node_pubkey = "7fujZQeTme52RdXTLmQST5jBgAbvzic5iERtH5EWoYjk"; + + /* + base58 = "6f3WcQuv8sPrxAsSh24TdXkauwVd8vFUyCCfbNqxszvR" + pubkey = "4qFJJJdRrSB9hCn8rrvYTXHLJg371ab36PJmZ4uxHjGQ" + base58 = "7fujZQeTme52RdXTLmQST5jBgAbvzic5iERtH5EWoYjk" + pubkey = "G2PetsFM8peG77rf9UTfVD7HEHNPmdjV3cebBpKuR3QT" + */ + + let user_wallet = user_key.pubkey.clone(); + let operator_wallet = op_key.pubkey.clone(); + + let _ = cli_client + .ban_user( + op_key + .sign_request(BanUserReq { + operator_wallet: operator_wallet.clone(), + user_wallet: user_wallet.clone(), + }) + .unwrap(), + ) + .await + .unwrap(); + + let ban_reconrd: Option = db_conn + .query(format!("SELECT * FROM {BAN} WHERE in = account:{operator_wallet} AND out = account:{user_wallet};")) + .await.unwrap().take(0).unwrap(); + + assert!(ban_reconrd.is_some()); + + let already_banned = cli_client + .ban_user( + op_key + .sign_request(BanUserReq { + operator_wallet: operator_wallet.clone(), + user_wallet: user_wallet.clone(), + }) + .unwrap(), + ) + .await + .err() + .unwrap(); + + assert!(already_banned.message().contains("Already banned")); + + airdrop(&brain_channel, &user_wallet, 10).await.unwrap(); + + let operator_banned_you = + create_new_vm(&db_conn, &user_key, node_pubkey, &brain_channel).await.err().unwrap(); + + assert!(operator_banned_you.to_string().contains("This operator banned you")); +} diff --git a/tests/mock_data.yaml b/tests/mock_data.yaml new file mode 100644 index 0000000..f651f11 --- /dev/null +++ b/tests/mock_data.yaml @@ -0,0 +1,475 @@ +accounts: + DXXkYSnhP3ijsHYxkedcuMomEyc122WaAbkDX7SaGuUS: + balance: 20293420000 + tmp_locked: 0 + kicked_for: [] + last_kick: 1970-01-01T00:00:00Z + banned_by: [] + FHuecMbeC1PfjkW2JKyoicJAuiU7khgQT16QUB3Q1XdL: + balance: 25949200000 + tmp_locked: 0 + kicked_for: [] + last_kick: 1970-01-01T00:00:00Z + banned_by: [] + Cnkvn3WuHYfTzh1YK1TAv2VD25sNvstJNnQtxjcdQSL7: + balance: 4794480000 + tmp_locked: 0 + kicked_for: [] + last_kick: 1970-01-01T00:00:00Z + banned_by: [] + BFopWmwcZAMF1h2PFECZNdEucdZfnZZ32p6R9ZaBiVsS: + balance: 4672207240000 + tmp_locked: 0 + kicked_for: [] + last_kick: 1970-01-01T00:00:00Z + banned_by: [] + E3bgXsWvgichXeC6AqULJCZDp7FbEdTxBD67UaYVWf9y: + balance: 21121600000 + tmp_locked: 0 + kicked_for: [] + last_kick: 1970-01-01T00:00:00Z + banned_by: [] + HQyGWpiteHbxjszngZvmiX7ZFZAmF6nFjEraBa1M6bbM: + balance: 979410300000 + tmp_locked: 0 + kicked_for: [] + last_kick: 1970-01-01T00:00:00Z + banned_by: [] + H21Shi4iE7vgfjWEQNvzmpmBMJSaiZ17PYUcdNoAoKNc: + balance: 976000000 + tmp_locked: 0 + kicked_for: [] + last_kick: 1970-01-01T00:00:00Z + banned_by: [] + 45Pyv9hRfub43NyRrYv95MhZs1Wrm8sj3RhBvA3F1Bvr: + balance: 1670441080000 + tmp_locked: 0 + kicked_for: [] + last_kick: 1970-01-01T00:00:00Z + banned_by: [] + 49JBVzmgsQbUURHzAWax2gxo6jmukqbEQzP97YeeNQyu: + balance: 1076960680000 + tmp_locked: 0 + kicked_for: [] + last_kick: 1970-01-01T00:00:00Z + banned_by: [] + 7V3rEuh6j8VuwMVB5PyGqWKLmjJ4fYSv6WtrTL51NZTB: + balance: 3271040000 + tmp_locked: 0 + kicked_for: [] + last_kick: 1970-01-01T00:00:00Z + banned_by: [] + x52w7jARC5erhWWK65VZmjdGXzBK6ZDgfv1A283d8XK: + balance: 554454460000 + tmp_locked: 547200000 + kicked_for: [] + last_kick: 1970-01-01T00:00:00Z + banned_by: [] + 3BNggj8ZTsoSjfAGdPfmcU2Gobm2qcTEBg9iHXEUPe1t: + balance: 9978460000 + tmp_locked: 0 + kicked_for: [] + last_kick: 1970-01-01T00:00:00Z + banned_by: [] + B981xPHmHthfKr15J9uJ64qd9zt2KsdiEuDRR7UUCGWi: + balance: 99980200000 + tmp_locked: 0 + kicked_for: [] + last_kick: 1970-01-01T00:00:00Z + banned_by: [] + CLYyE6id5876DW69LHDynuH6TjJPvWRBTQC5XDZ6jfT1: + balance: 25000000000 + tmp_locked: 0 + kicked_for: [] + last_kick: 1970-01-01T00:00:00Z + banned_by: [] + db5ZB6uDbF1mUUgeggBZ9XKbi3mUfX6WHkBpbwUHJpB: + balance: 25000000000 + tmp_locked: 0 + kicked_for: [] + last_kick: 1970-01-01T00:00:00Z + banned_by: [] + fY3NNjvFTeR1FBh5nXV3ujX7zZqrm3eBUWGEiG75TK1: + balance: 1000000000 + tmp_locked: 0 + kicked_for: [] + last_kick: 1970-01-01T00:00:00Z + banned_by: [] + FBMWVqME3t1i4R6zWyDQGUuiTeruZ1TxLhTmhaEcFypZ: + balance: 181560160000 + tmp_locked: 0 + kicked_for: [] + last_kick: 1970-01-01T00:00:00Z + banned_by: [] + DwfL5iFu32xh2YMCUxg63oEAThLRqehDAumiP9q6zuuX: + balance: 74660380000 + tmp_locked: 0 + kicked_for: [] + last_kick: 1970-01-01T00:00:00Z + banned_by: [] + + 4qFJJJdRrSB9hCn8rrvYTXHLJg371ab36PJmZ4uxHjGQ: + balance: 25949200000 + tmp_locked: 0 + kicked_for: [] + last_kick: 1970-01-01T00:00:00Z + banned_by: [] + +operators: + BFopWmwcZAMF1h2PFECZNdEucdZfnZZ32p6R9ZaBiVsS: + escrow: 5096692000000 + email: first_on_detee@proton.me + banned_users: [] + vm_nodes: + - HiyMp21zaBVbRCjDsD5hEjQnHeHv4e1gpUR6pVfHTKqv + - 3zRxiGRnf46vd3zAEmpaYBJocTV9oJB6yXf5GZFR1Sq4 + - Du3UfPSUUZmA5thQmc9Vrxdy7UimpygcpDsQNnwRQPtu + - 4QbUXDM915RUFnHm3NiysLXFLk1WRGZvABwLNzx4tTEW + - DgkbsrwttkZXvzxY5kDwQQoDd79GLmZ5tc7fYJUFkQQb + app_nodes: [] + x52w7jARC5erhWWK65VZmjdGXzBK6ZDgfv1A283d8XK: + escrow: 5499700480000 + email: gheo@detee.ltd + banned_users: [] + vm_nodes: + - 2Uf5pxhxKTUm6gRMnpbJHYDuyA6BWUfFsdmPyWfbMV1f + - 7Xw3RxbP5pvfjZ8U6yA3HHVSS9YXjKH5Vkas3JRbQYd9 + app_nodes: [] + 7V3rEuh6j8VuwMVB5PyGqWKLmjJ4fYSv6WtrTL51NZTB: + escrow: 888888888899999 + email: "" + banned_users: [] + vm_nodes: [] + app_nodes: + - BiqoPUEoAxYxMRXUmyofoS9H1TBQgQqvLJ6MbWh88AQg + + 4qFJJJdRrSB9hCn8rrvYTXHLJg371ab36PJmZ4uxHjGQ: + escrow: 5499700480000 + email: "test_mock@operator" + banned_users: [] + vm_nodes: + - 7fujZQeTme52RdXTLmQST5jBgAbvzic5iERtH5EWoYjk + app_nodes: [] + +vm_nodes: + - public_key: 7Xw3RxbP5pvfjZ8U6yA3HHVSS9YXjKH5Vkas3JRbQYd9 + operator_wallet: x52w7jARC5erhWWK65VZmjdGXzBK6ZDgfv1A283d8XK + country: GB + region: England + city: London + ip: 173.234.17.2 + avail_mem_mb: 26000 + avail_vcpus: 28 + avail_storage_gbs: 680 + avail_ipv4: 2 + avail_ipv6: 65516 + avail_ports: 19999 + max_ports_per_vm: 5 + price: 20000 + reports: {} + offline_minutes: 0 + - public_key: Du3UfPSUUZmA5thQmc9Vrxdy7UimpygcpDsQNnwRQPtu + operator_wallet: BFopWmwcZAMF1h2PFECZNdEucdZfnZZ32p6R9ZaBiVsS + country: FR + region: Île-de-France + city: Paris + ip: 156.146.63.215 + avail_mem_mb: 123000 + avail_vcpus: 46 + avail_storage_gbs: 440 + avail_ipv4: 2 + avail_ipv6: 0 + avail_ports: 20000 + max_ports_per_vm: 5 + price: 20000 + reports: {} + offline_minutes: 0 + - public_key: 2Uf5pxhxKTUm6gRMnpbJHYDuyA6BWUfFsdmPyWfbMV1f + operator_wallet: x52w7jARC5erhWWK65VZmjdGXzBK6ZDgfv1A283d8XK + country: CA + region: Quebec + city: Montréal + ip: 184.107.169.199 + avail_mem_mb: 30000 + avail_vcpus: 31 + avail_storage_gbs: 700 + avail_ipv4: 0 + avail_ipv6: 0 + avail_ports: 20000 + max_ports_per_vm: 5 + price: 18000 + reports: {} + offline_minutes: 0 + - public_key: DgkbsrwttkZXvzxY5kDwQQoDd79GLmZ5tc7fYJUFkQQb + operator_wallet: BFopWmwcZAMF1h2PFECZNdEucdZfnZZ32p6R9ZaBiVsS + country: CA + region: British Columbia + city: Vancouver + ip: 149.22.95.1 + avail_mem_mb: 109000 + avail_vcpus: 45 + avail_storage_gbs: 400 + avail_ipv4: 25 + avail_ipv6: 0 + avail_ports: 20000 + max_ports_per_vm: 5 + price: 20000 + reports: {} + offline_minutes: 0 + - public_key: 3zRxiGRnf46vd3zAEmpaYBJocTV9oJB6yXf5GZFR1Sq4 + operator_wallet: BFopWmwcZAMF1h2PFECZNdEucdZfnZZ32p6R9ZaBiVsS + country: US + region: California + city: San Jose + ip: 149.36.48.99 + avail_mem_mb: 120000 + avail_vcpus: 41 + avail_storage_gbs: 390 + avail_ipv4: 23 + avail_ipv6: 0 + avail_ports: 19999 + max_ports_per_vm: 5 + price: 20000 + reports: {} + offline_minutes: 0 + - public_key: HiyMp21zaBVbRCjDsD5hEjQnHeHv4e1gpUR6pVfHTKqv + operator_wallet: BFopWmwcZAMF1h2PFECZNdEucdZfnZZ32p6R9ZaBiVsS + country: CA + region: British Columbia + city: Vancouver + ip: 149.22.95.28 + avail_mem_mb: 125000 + avail_vcpus: 46 + avail_storage_gbs: 400 + avail_ipv4: 26 + avail_ipv6: 0 + avail_ports: 20000 + max_ports_per_vm: 5 + price: 20000 + reports: {} + offline_minutes: 0 + + - public_key: 7fujZQeTme52RdXTLmQST5jBgAbvzic5iERtH5EWoYjk + operator_wallet: 4qFJJJdRrSB9hCn8rrvYTXHLJg371ab36PJmZ4uxHjGQ + 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: + - uuid: 958165e3-dea8-407d-8c42-dd17002ef79c + hostname: detee-landing-fr + admin_pubkey: FHuecMbeC1PfjkW2JKyoicJAuiU7khgQT16QUB3Q1XdL + node_pubkey: Du3UfPSUUZmA5thQmc9Vrxdy7UimpygcpDsQNnwRQPtu + exposed_ports: [] + public_ipv4: 156.146.63.216 + public_ipv6: "" + disk_size_gb: 10 + vcpus: 2 + memory_mb: 3000 + kernel_sha: 3ec4fc5aa5729f515967ec71be4a851622785c0080f7191b1b07717149840151 + dtrfs_sha: 3f6b3e5740f249eedfb2f7248c521a551be8b2676f7fcb040f3f3bc840a5004b + created_at: 2025-02-28T23:19:41.769423466Z + updated_at: 2025-04-12T12:11:58.516768949Z + price_per_unit: 20000 + locked_nano: 14875500000 + collected_at: 2025-04-20T00:34:15.461165181Z + - uuid: e807a2fd-cf90-4a14-bc3a-89ce6dc59033 + hostname: detee-landing-gb + admin_pubkey: FHuecMbeC1PfjkW2JKyoicJAuiU7khgQT16QUB3Q1XdL + node_pubkey: 7Xw3RxbP5pvfjZ8U6yA3HHVSS9YXjKH5Vkas3JRbQYd9 + exposed_ports: [] + public_ipv4: 173.234.136.154 + public_ipv6: "" + disk_size_gb: 10 + vcpus: 2 + memory_mb: 3000 + kernel_sha: 3ec4fc5aa5729f515967ec71be4a851622785c0080f7191b1b07717149840151 + dtrfs_sha: 3f6b3e5740f249eedfb2f7248c521a551be8b2676f7fcb040f3f3bc840a5004b + created_at: 2025-03-06T19:51:39.595163157Z + updated_at: 2025-03-06T19:51:39.595163842Z + price_per_unit: 20000 + locked_nano: 14875500000 + collected_at: 2025-04-20T00:34:15.461181545Z + - uuid: 23094406-2307-4332-a642-acee718d0186 + hostname: heroic-door + admin_pubkey: DwfL5iFu32xh2YMCUxg63oEAThLRqehDAumiP9q6zuuX + node_pubkey: 7Xw3RxbP5pvfjZ8U6yA3HHVSS9YXjKH5Vkas3JRbQYd9 + exposed_ports: + - 38288 + public_ipv4: "" + public_ipv6: "" + disk_size_gb: 10 + vcpus: 1 + memory_mb: 1000 + kernel_sha: 14e225e4aaf84cc2e0b5f64206121186ddebc4b378b886da3b2f7515dfd41692 + dtrfs_sha: 03ce24dbbe917fdd4f6347e61036805ddbdded5044c272bab188ef9333093bee + created_at: 2025-03-12T16:28:24.749161605Z + updated_at: 2025-03-12T16:28:24.749162477Z + price_per_unit: 20000 + locked_nano: 14134140000 + collected_at: 2025-04-20T00:34:15.461191231Z + - uuid: 1f49a71c-f68c-4c64-a82e-f50e0ba0b574 + hostname: astromech-wrench + admin_pubkey: FHuecMbeC1PfjkW2JKyoicJAuiU7khgQT16QUB3Q1XdL + node_pubkey: DgkbsrwttkZXvzxY5kDwQQoDd79GLmZ5tc7fYJUFkQQb + exposed_ports: [] + public_ipv4: 149.22.95.2 + public_ipv6: "" + disk_size_gb: 10 + vcpus: 2 + memory_mb: 3000 + kernel_sha: 3a68709138bed09c16671949cf1f03acee95a08381ba84fc70fb586001fa6767 + dtrfs_sha: 0bb93443f65c9f4379ed469f94794f5c1bf14d8905b0b2c56a125df4a9ebe83e + created_at: 2025-03-20T14:40:25.557753393Z + updated_at: 2025-03-20T14:40:25.557754242Z + price_per_unit: 20000 + locked_nano: 11865620000 + collected_at: 2025-04-20T00:34:15.461201690Z + - uuid: 16577f1c-9867-4a17-80a8-6cf0490f1270 + hostname: sofenty + admin_pubkey: FHuecMbeC1PfjkW2JKyoicJAuiU7khgQT16QUB3Q1XdL + node_pubkey: Du3UfPSUUZmA5thQmc9Vrxdy7UimpygcpDsQNnwRQPtu + exposed_ports: [] + public_ipv4: 156.146.63.217 + public_ipv6: "" + disk_size_gb: 10 + vcpus: 2 + memory_mb: 3000 + kernel_sha: e49c8587287b21df7600c04326fd7393524453918c14d67f73757dc769a13542 + dtrfs_sha: b5f408d00e2b93dc594fed3a7f2466a9878802ff1c7ae502247471cd06728a45 + created_at: 2025-04-07T22:57:57.646151746Z + updated_at: 2025-04-07T22:57:57.646152630Z + price_per_unit: 20000 + locked_nano: 11867500000 + collected_at: 2025-04-20T00:34:15.461211040Z + - uuid: 4b6e25ca-87ac-478b-8f16-aa8f5c44c704 + hostname: cloaked-mailbox + admin_pubkey: DwfL5iFu32xh2YMCUxg63oEAThLRqehDAumiP9q6zuuX + node_pubkey: DgkbsrwttkZXvzxY5kDwQQoDd79GLmZ5tc7fYJUFkQQb + exposed_ports: [] + public_ipv4: 149.22.95.2 + public_ipv6: "" + disk_size_gb: 30 + vcpus: 1 + memory_mb: 1000 + kernel_sha: e49c8587287b21df7600c04326fd7393524453918c14d67f73757dc769a13542 + dtrfs_sha: b5f408d00e2b93dc594fed3a7f2466a9878802ff1c7ae502247471cd06728a45 + created_at: 2025-04-12T13:44:56.957037550Z + updated_at: 2025-04-12T13:44:56.957038546Z + price_per_unit: 20000 + locked_nano: 11177760000 + collected_at: 2025-04-20T00:34:15.461219779Z + - uuid: eb1a13ed-d782-4b71-8860-73540129cb7d + hostname: twenty + admin_pubkey: FHuecMbeC1PfjkW2JKyoicJAuiU7khgQT16QUB3Q1XdL + node_pubkey: 3zRxiGRnf46vd3zAEmpaYBJocTV9oJB6yXf5GZFR1Sq4 + exposed_ports: [] + public_ipv4: 149.36.48.100 + public_ipv6: "" + disk_size_gb: 10 + vcpus: 4 + memory_mb: 4000 + kernel_sha: e49c8587287b21df7600c04326fd7393524453918c14d67f73757dc769a13542 + dtrfs_sha: b5f408d00e2b93dc594fed3a7f2466a9878802ff1c7ae502247471cd06728a45 + created_at: 2025-04-15T00:46:35.622165457Z + updated_at: 2025-04-15T00:46:35.622166372Z + price_per_unit: 20000 + locked_nano: 15570720000 + collected_at: 2025-04-20T00:34:15.461230948Z + - uuid: 1bf36309-3774-4825-b023-b2a0ef0405ed + hostname: shadowy-hobo + admin_pubkey: x52w7jARC5erhWWK65VZmjdGXzBK6ZDgfv1A283d8XK + node_pubkey: 3zRxiGRnf46vd3zAEmpaYBJocTV9oJB6yXf5GZFR1Sq4 + 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: 12730960000 + collected_at: 2025-04-20T00:34:15.461240342Z +app_nodes: + - node_pubkey: BiqoPUEoAxYxMRXUmyofoS9H1TBQgQqvLJ6MbWh88AQg + operator_wallet: 7V3rEuh6j8VuwMVB5PyGqWKLmjJ4fYSv6WtrTL51NZTB + country: DE + region: Hesse + city: Frankfurt am Main + ip: 212.95.45.139 + avail_mem_mb: 16000 + avail_vcpus: 16 + avail_storage_mb: 200000 + avail_no_of_port: 20000 + max_ports_per_app: 9 + price: 20000 + offline_minutes: 0 +app_contracts: + - uuid: e3d01f25-2b2a-410b-80e3-12f44e474334 + package_url: https://registry.detee.ltd/sgx/packages/base_package_2025-04-17_11-01-08.tar.gz + admin_pubkey: H21Shi4iE7vgfjWEQNvzmpmBMJSaiZ17PYUcdNoAoKNc + node_pubkey: BiqoPUEoAxYxMRXUmyofoS9H1TBQgQqvLJ6MbWh88AQg + mapped_ports: + - - 27158 + - 34500 + - - 28667 + - 8080 + host_ipv4: 212.95.45.139 + disk_size_mb: 1000 + vcpus: 1 + memory_mb: 1000 + created_at: 2025-04-21T11:27:28.833236909Z + updated_at: 2025-04-21T11:27:28.833237729Z + price_per_unit: 200000 + locked_nano: 121200000 + collected_at: 2025-04-21T11:28:24.905665571Z + hratls_pubkey: 7E0F887AA6BB9104EEC1066F454D4C2D9063D676715F55F919D3FBCEDC63240B + public_package_mr_enclave: + - 52 + - 183 + - 102 + - 210 + - 251 + - 219 + - 218 + - 140 + - 168 + - 118 + - 10 + - 193 + - 98 + - 240 + - 147 + - 124 + - 240 + - 189 + - 46 + - 95 + - 138 + - 172 + - 15 + - 246 + - 227 + - 114 + - 70 + - 159 + - 232 + - 212 + - 9 + - 234 + app_name: diligent-seahorse