diff --git a/Cargo.lock b/Cargo.lock index 85bf0df..6dfb900 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -103,12 +103,68 @@ dependencies = [ "libc", ] +[[package]] +name = "anstream" +version = "0.6.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" + +[[package]] +name = "anstyle-parse" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" +dependencies = [ + "anstyle", + "once_cell", + "windows-sys 0.59.0", +] + [[package]] name = "any_ascii" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea50b14b7a4b9343f8c627a7a53c52076482bd4bdad0a24fd3ec533ed616cc2c" +[[package]] +name = "anyhow" +version = "1.0.98" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" + [[package]] name = "approx" version = "0.4.0" @@ -312,12 +368,65 @@ dependencies = [ "rustc_version", ] +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + [[package]] name = "autocfg" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +[[package]] +name = "axum" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edca88bc138befd0323b20752846e6587272d3b03b0343c8ea28a6f819e6e71f" +dependencies = [ + "async-trait", + "axum-core", + "bytes", + "futures-util", + "http", + "http-body", + "http-body-util", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "sync_wrapper", + "tower 0.5.2", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum-core" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http", + "http-body", + "http-body-util", + "mime", + "pin-project-lite", + "rustversion", + "sync_wrapper", + "tower-layer", + "tower-service", +] + [[package]] name = "backtrace" version = "0.3.74" @@ -470,6 +579,15 @@ dependencies = [ "syn 2.0.100", ] +[[package]] +name = "bs58" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" +dependencies = [ + "tinyvec", +] + [[package]] name = "bumpalo" version = "3.17.0" @@ -658,6 +776,12 @@ dependencies = [ "inout", ] +[[package]] +name = "colorchoice" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" + [[package]] name = "concurrent-queue" version = "2.5.0" @@ -667,6 +791,12 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + [[package]] name = "constant_time_eq" version = "0.3.1" @@ -729,6 +859,33 @@ dependencies = [ "typenum", ] +[[package]] +name = "curve25519-dalek" +version = "4.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" +dependencies = [ + "cfg-if", + "cpufeatures", + "curve25519-dalek-derive", + "digest", + "fiat-crypto", + "rustc_version", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] + [[package]] name = "darling" version = "0.20.11" @@ -798,6 +955,16 @@ version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" +[[package]] +name = "der" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" +dependencies = [ + "const-oid", + "zeroize", +] + [[package]] name = "deranged" version = "0.4.0" @@ -808,6 +975,20 @@ dependencies = [ "serde", ] +[[package]] +name = "detee-shared" +version = "0.1.0" +source = "git+ssh://git@gitea.detee.cloud/testnet/proto?branch=main#3024c00b8e1c93e70902793385b92bc0a8d1f26a" +dependencies = [ + "base64 0.22.1", + "prost", + "serde", + "serde_yaml", + "thiserror 2.0.12", + "tonic", + "tonic-build", +] + [[package]] name = "deunicode" version = "1.6.1" @@ -883,6 +1064,30 @@ dependencies = [ "num-traits", ] +[[package]] +name = "ed25519" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" +dependencies = [ + "pkcs8", + "signature", +] + +[[package]] +name = "ed25519-dalek" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871" +dependencies = [ + "curve25519-dalek", + "ed25519", + "serde", + "sha2", + "subtle", + "zeroize", +] + [[package]] name = "either" version = "1.15.0" @@ -913,12 +1118,45 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" +[[package]] +name = "env_filter" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "186e05a59d4c50738528153b83b0b0194d3a29507dfec16eccd4b342903397d0" +dependencies = [ + "log", + "regex", +] + +[[package]] +name = "env_logger" +version = "0.11.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c863f0904021b108aa8b2f55046443e6b1ebde8fd4a15c399893aae4fa069f" +dependencies = [ + "anstream", + "anstyle", + "env_filter", + "jiff", + "log", +] + [[package]] name = "equivalent" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" +[[package]] +name = "errno" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "976dd42dc7e85965fe702eb8164f21f450704bdde31faefd6471dba214cb594e" +dependencies = [ + "libc", + "windows-sys 0.59.0", +] + [[package]] name = "event-listener" version = "5.4.0" @@ -946,6 +1184,12 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" +[[package]] +name = "fiat-crypto" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" + [[package]] name = "fixedbitset" version = "0.4.2" @@ -1201,6 +1445,25 @@ version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" +[[package]] +name = "h2" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75249d144030531f8dee69fe9cea04d3edf809a017ae445e2abdff6629e86633" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http", + "indexmap 2.9.0", + "slab", + "tokio", + "tokio-util", + "tracing", +] + [[package]] name = "half" version = "2.6.0" @@ -1343,6 +1606,12 @@ version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + [[package]] name = "humantime" version = "2.2.0" @@ -1358,9 +1627,11 @@ dependencies = [ "bytes", "futures-channel", "futures-util", + "h2", "http", "http-body", "httparse", + "httpdate", "itoa", "pin-project-lite", "smallvec", @@ -1386,6 +1657,19 @@ dependencies = [ "webpki-roots", ] +[[package]] +name = "hyper-timeout" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b90d566bffbce6a75bd8b09a05aa8c2cb1fabb6cb348f8840c9e4c90a0d83b0" +dependencies = [ + "hyper", + "hyper-util", + "pin-project-lite", + "tokio", + "tower-service", +] + [[package]] name = "hyper-util" version = "0.1.11" @@ -1612,6 +1896,12 @@ version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + [[package]] name = "itertools" version = "0.10.5" @@ -1645,6 +1935,30 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" +[[package]] +name = "jiff" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ec30f7142be6fe14e1b021f50b85db8df2d4324ea6e91ec3e5dcde092021d0" +dependencies = [ + "jiff-static", + "log", + "portable-atomic", + "portable-atomic-util", + "serde", +] + +[[package]] +name = "jiff-static" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "526b834d727fd59d37b076b0c3236d9adde1b1729a4361e20b2026f738cc1dbe" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] + [[package]] name = "js-sys" version = "0.3.77" @@ -1750,6 +2064,12 @@ dependencies = [ "thiserror 1.0.69", ] +[[package]] +name = "linux-raw-sys" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" + [[package]] name = "litemap" version = "0.7.5" @@ -1798,6 +2118,12 @@ dependencies = [ "tendril", ] +[[package]] +name = "matchit" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" + [[package]] name = "matrixmultiply" version = "0.3.9" @@ -1900,6 +2226,12 @@ dependencies = [ "version_check", ] +[[package]] +name = "multimap" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "defc4c55412d89136f966bbb339008b474350e5e6e78d2714439c386b3137a03" + [[package]] name = "nanoid" version = "0.4.0" @@ -2232,6 +2564,26 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" +[[package]] +name = "pin-project" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] + [[package]] name = "pin-project-lite" version = "0.2.16" @@ -2244,6 +2596,31 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "portable-atomic" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e" + +[[package]] +name = "portable-atomic-util" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507" +dependencies = [ + "portable-atomic", +] + [[package]] name = "powerfmt" version = "0.2.0" @@ -2265,6 +2642,16 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" +[[package]] +name = "prettyplease" +version = "0.2.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "664ec5419c51e34154eec046ebcba56312d5a2fc3b09a06da188e1ad21afadf6" +dependencies = [ + "proc-macro2", + "syn 2.0.100", +] + [[package]] name = "proc-macro-crate" version = "3.3.0" @@ -2283,6 +2670,58 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "prost" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2796faa41db3ec313a31f7624d9286acf277b52de526150b7e69f3debf891ee5" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-build" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be769465445e8c1474e9c5dac2018218498557af32d9ed057325ec9a41ae81bf" +dependencies = [ + "heck 0.5.0", + "itertools 0.13.0", + "log", + "multimap", + "once_cell", + "petgraph", + "prettyplease", + "prost", + "prost-types", + "regex", + "syn 2.0.100", + "tempfile", +] + +[[package]] +name = "prost-derive" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a56d757972c98b346a9b766e3f02746cde6dd1cd1d1d563472929fdd74bec4d" +dependencies = [ + "anyhow", + "itertools 0.13.0", + "proc-macro2", + "quote", + "syn 2.0.100", +] + +[[package]] +name = "prost-types" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52c2c1bf36ddb1a1c396b3601a3cec27c2462e45f07c386894ec3ccf5332bd16" +dependencies = [ + "prost", +] + [[package]] name = "psl-types" version = "2.0.11" @@ -2620,7 +3059,7 @@ dependencies = [ "tokio", "tokio-rustls", "tokio-util", - "tower", + "tower 0.5.2", "tower-service", "url", "wasm-bindgen", @@ -2775,20 +3214,6 @@ dependencies = [ "serde_json", ] -[[package]] -name = "rust_test" -version = "0.1.0" -dependencies = [ - "chrono", - "dashmap 6.1.0", - "futures", - "serde", - "serde_json", - "serde_yaml", - "surrealdb", - "tokio", -] - [[package]] name = "rustc-demangle" version = "0.1.24" @@ -2819,6 +3244,19 @@ dependencies = [ "semver", ] +[[package]] +name = "rustix" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d97817398dd4bb2e6da002002db259209759911da105da92bec29ccb12cf58bf" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.59.0", +] + [[package]] name = "rustls" version = "0.23.26" @@ -3057,6 +3495,15 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "rand_core 0.6.4", +] + [[package]] name = "simdutf8" version = "0.1.5" @@ -3161,6 +3608,16 @@ version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + [[package]] name = "stable_deref_trait" version = "1.2.0" @@ -3257,6 +3714,27 @@ version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" +[[package]] +name = "surreal-brain" +version = "0.1.0" +dependencies = [ + "bs58", + "chrono", + "dashmap 6.1.0", + "detee-shared", + "ed25519-dalek", + "env_logger", + "futures", + "log", + "serde", + "serde_json", + "serde_yaml", + "surrealdb", + "tokio", + "tokio-stream", + "tonic", +] + [[package]] name = "surrealdb" version = "2.2.2" @@ -3447,6 +3925,19 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" +[[package]] +name = "tempfile" +version = "3.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7437ac7763b9b123ccf33c338a5cc1bac6f69b45a136c19bdd8a65e3916435bf" +dependencies = [ + "fastrand", + "getrandom 0.3.2", + "once_cell", + "rustix", + "windows-sys 0.59.0", +] + [[package]] name = "tendril" version = "0.4.3" @@ -3621,6 +4112,17 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-stream" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + [[package]] name = "tokio-tungstenite" version = "0.23.1" @@ -3668,6 +4170,72 @@ dependencies = [ "winnow", ] +[[package]] +name = "tonic" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877c5b330756d856ffcc4553ab34a5684481ade925ecc54bcd1bf02b1d0d4d52" +dependencies = [ + "async-stream", + "async-trait", + "axum", + "base64 0.22.1", + "bytes", + "h2", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-timeout", + "hyper-util", + "percent-encoding", + "pin-project", + "prost", + "rustls-pemfile", + "socket2", + "tokio", + "tokio-rustls", + "tokio-stream", + "tower 0.4.13", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tonic-build" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9557ce109ea773b399c9b9e5dca39294110b74f1f342cb347a80d1fce8c26a11" +dependencies = [ + "prettyplease", + "proc-macro2", + "prost-build", + "prost-types", + "quote", + "syn 2.0.100", +] + +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "indexmap 1.9.3", + "pin-project", + "pin-project-lite", + "rand 0.8.5", + "slab", + "tokio", + "tokio-util", + "tower-layer", + "tower-service", + "tracing", +] + [[package]] name = "tower" version = "0.5.2" @@ -3883,6 +4451,12 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + [[package]] name = "uuid" version = "1.16.0" diff --git a/Cargo.toml b/Cargo.toml index 2ec54ff..b5faf6f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "rust_test" +name = "surreal-brain" version = "0.1.0" edition = "2021" @@ -12,6 +12,13 @@ serde_json = "1.0.140" serde_yaml = "0.9.34" surrealdb = "2.2.2" tokio = { version = "1.44.2", features = ["macros", "rt-multi-thread"] } +tonic = { version = "0.12", features = ["tls"] } +detee-shared = { git = "ssh://git@gitea.detee.cloud/testnet/proto", branch = "main" } +ed25519-dalek = "2.1.1" +bs58 = "0.5.1" +tokio-stream = "0.1.17" +log = "0.4.27" +env_logger = "0.11.8" [profile.release] lto = true diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 0000000..a484977 --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1,3 @@ +reorder_impl_items = true +use_small_heuristics = "Max" +imports_granularity = "Crate" diff --git a/src/bin/brain.rs b/src/bin/brain.rs new file mode 100644 index 0000000..e4f2532 --- /dev/null +++ b/src/bin/brain.rs @@ -0,0 +1,28 @@ +use detee_shared::general_proto::brain_general_cli_server::BrainGeneralCliServer; +use detee_shared::vm_proto::brain_vm_cli_server::BrainVmCliServer; +use surreal_brain::grpc::BrainGeneralCliMock; +use surreal_brain::grpc::BrainVmCliMock; +use tonic::transport::{Identity, Server, ServerTlsConfig}; + +#[tokio::main] +async fn main() { + env_logger::builder().filter_level(log::LevelFilter::Debug).init(); + let addr = "0.0.0.0:31337".parse().unwrap(); + + let snp_cli_server = BrainVmCliServer::new(BrainVmCliMock {}); + let general_service_server = BrainGeneralCliServer::new(BrainGeneralCliMock {}); + + let cert = std::fs::read_to_string("./brain-crt.pem").unwrap(); + let key = std::fs::read_to_string("./brain-mock/brain-key.pem").unwrap(); + + let identity = Identity::from_pem(cert, key); + + Server::builder() + .tls_config(ServerTlsConfig::new().identity(identity)) + .unwrap() + .add_service(snp_cli_server) + .add_service(general_service_server) + .serve(addr) + .await + .unwrap(); +} diff --git a/src/main.rs b/src/bin/migration0.rs similarity index 56% rename from src/main.rs rename to src/bin/migration0.rs index 2bf9d95..c04b08a 100644 --- a/src/main.rs +++ b/src/bin/migration0.rs @@ -1,15 +1,15 @@ +// After deleting this migration, also delete old_brain structs +// and dangling impls from the model use std::error::Error; - -mod old_brain; -mod surreal_brain; +use surreal_brain::{models, old_brain}; #[tokio::main] async fn main() -> Result<(), Box> { let old_brain_data = old_brain::BrainData::load_from_disk()?; // println!("{}", serde_yaml::to_string(&old_brain_data)?); - let result = surreal_brain::migrate(&old_brain_data).await?; - + let result = models::migrate(&old_brain_data).await?; + println!("{result:?}"); Ok(()) diff --git a/src/grpc.rs b/src/grpc.rs new file mode 100644 index 0000000..088539b --- /dev/null +++ b/src/grpc.rs @@ -0,0 +1,428 @@ +#![allow(dead_code)] +use detee_shared::app_proto::AppContract; +use detee_shared::{ + common_proto::{Empty, Pubkey}, + general_proto::{ + brain_general_cli_server::BrainGeneralCli, Account, AccountBalance, AirdropReq, BanUserReq, + InspectOperatorResp, KickReq, KickResp, ListOperatorsResp, RegOperatorReq, ReportNodeReq, + SlashReq, + }, + vm_proto::{brain_vm_cli_server::BrainVmCli, ListVmContractsReq, *}, +}; + +use log::info; +use std::pin::Pin; +// use tokio::sync::mpsc; +// use tokio_stream::{wrappers::ReceiverStream, Stream}; +use tokio_stream::Stream; +use tonic::{Request, Response, Status}; + +pub struct BrainGeneralCliMock {} + +#[tonic::async_trait] +impl BrainGeneralCli for BrainGeneralCliMock { + type ListAccountsStream = Pin> + Send>>; + type ListAllAppContractsStream = + Pin> + Send>>; + type ListAllVmContractsStream = Pin> + Send>>; + type ListOperatorsStream = + Pin> + Send>>; + + async fn get_balance(&self, req: Request) -> Result, Status> { + let _req = check_sig_from_req(req)?; + todo!("Ok(Response::new(self.data.get_balance(&req.pubkey).into()))") + } + + async fn report_node(&self, req: Request) -> Result, Status> { + let _req = check_sig_from_req(req)?; + todo!(); + // match self.data.find_any_contract_by_uuid(&req.contract) { + // Ok((Some(vm_contract), _)) + // if vm_contract.admin_pubkey == req.admin_pubkey + // && vm_contract.node_pubkey == req.node_pubkey => + // { + // () + // } + // Ok((_, Some(app_contract))) + // if app_contract.admin_pubkey == req.admin_pubkey + // && app_contract.node_pubkey == req.node_pubkey => + // { + // () + // } + // _ => 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( + &self, + _req: Request, + ) -> Result, Status> { + todo!(); + // 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, + ) -> Result, Status> { + todo!(); + // 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")), + // } + } + + async fn register_operator( + &self, + _req: Request, + ) -> Result, Status> { + todo!(); + // let req = check_sig_from_req(req)?; + // info!("Regitering new operator: {req:?}"); + // match self.data.register_operator(req) { + // Ok(()) => Ok(Response::new(Empty {})), + // Err(e) => Err(Status::failed_precondition(e.to_string())), + // } + } + + async fn kick_contract(&self, _req: Request) -> Result, Status> { + todo!(); + // 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) -> Result, Status> { + todo!(); + // let req = check_sig_from_req(req)?; + // self.data.ban_user(&req.operator_wallet, &req.user_wallet); + // Ok(Response::new(Empty {})) + } + + // admin commands + + async fn airdrop(&self, _req: Request) -> Result, Status> { + todo!(); + // check_admin_key(&req)?; + // let req = check_sig_from_req(req)?; + // self.data.give_airdrop(&req.pubkey, req.tokens); + // Ok(Response::new(Empty {})) + } + + async fn slash(&self, _req: Request) -> Result, Status> { + todo!(); + // check_admin_key(&req)?; + // let req = check_sig_from_req(req)?; + // self.data.slash_account(&req.pubkey, req.tokens); + // Ok(Response::new(Empty {})) + } + + async fn list_accounts( + &self, + _req: Request, + ) -> Result, Status> { + todo!(); + // check_admin_key(&req)?; + // let _ = check_sig_from_req(req)?; + // let accounts = self.data.list_accounts(); + // let (tx, rx) = mpsc::channel(6); + // tokio::spawn(async move { + // for account in accounts { + // let _ = tx.send(Ok(account.into())).await; + // } + // }); + // let output_stream = ReceiverStream::new(rx); + // Ok(Response::new(Box::pin(output_stream) as Self::ListAccountsStream)) + } + + async fn list_all_vm_contracts( + &self, + _req: Request, + ) -> Result, Status> { + todo!(); + // check_admin_key(&req)?; + // let _ = check_sig_from_req(req)?; + // let contracts = self.data.list_all_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) as Self::ListAllVmContractsStream)) + } + + async fn list_all_app_contracts( + &self, + _req: tonic::Request, + ) -> Result, Status> { + todo!(); + // 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))) + } +} + +pub struct BrainVmCliMock {} + +#[tonic::async_trait] +impl BrainVmCli for BrainVmCliMock { + type ListVmContractsStream = Pin> + Send>>; + type ListVmNodesStream = Pin> + Send>>; + + async fn new_vm(&self, req: Request) -> Result, Status> { + let req = check_sig_from_req(req)?; + info!("New VM requested via CLI: {req:?}"); + todo!(); + // 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; + // match oneshot_rx.await { + // Ok(response) => { + // info!("Sending VM confirmation to {admin_pubkey}: {response:?}"); + // Ok(Response::new(response)) + // } + // Err(e) => { + // log::error!("Something weird happened. Reached error {e:?}"); + // Err(Status::unknown( + // "Request failed due to unknown error. Please try again or contact the DeTEE devs team.", + // )) + // } + // } + } + + async fn update_vm(&self, req: Request) -> Result, Status> { + let req = check_sig_from_req(req)?; + info!("Update VM requested via CLI: {req:?}"); + todo!(); + // let (oneshot_tx, oneshot_rx) = tokio::sync::oneshot::channel(); + // self.data.submit_updatevm_req(req, oneshot_tx).await; + // match oneshot_rx.await { + // Ok(response) => { + // info!("Sending UpdateVMResp: {response:?}"); + // Ok(Response::new(response)) + // } + // Err(e) => Err(Status::unknown(format!( + // "Update VM request failed due to error: {e}" + // ))), + // } + } + + async fn extend_vm(&self, req: Request) -> Result, Status> { + let _req = check_sig_from_req(req)?; + todo!(); + // match self + // .data + // .extend_vm_contract_time(&req.uuid, &req.admin_pubkey, req.locked_nano) + // { + // Ok(()) => Ok(Response::new(Empty {})), + // Err(e) => Err(Status::unknown(format!("Could not extend contract: {e}"))), + // } + } + + async fn delete_vm(&self, req: Request) -> Result, Status> { + let _req = check_sig_from_req(req)?; + todo!(); + // match self.data.delete_vm(req).await { + // Ok(()) => Ok(Response::new(Empty {})), + // Err(e) => Err(Status::not_found(e.to_string())), + // } + } + + async fn list_vm_contracts( + &self, + req: Request, + ) -> Result, Status> { + let req = check_sig_from_req(req)?; + info!( + "CLI {} requested ListVMVmContractsStream. As operator: {}", + req.wallet, req.as_operator + ); + todo!(); + // 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 { + // let _ = tx.send(Ok(contract.into())).await; + // } + // }); + // let output_stream = ReceiverStream::new(rx); + // Ok(Response::new( + // Box::pin(output_stream) as Self::ListVmContractsStream + // )) + } + + async fn list_vm_nodes( + &self, + req: Request, + ) -> Result, tonic::Status> { + let req = check_sig_from_req(req)?; + info!("CLI requested ListVmNodesStream: {req:?}"); + todo!(); + // let nodes = self.data.find_vm_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) as Self::ListVmNodesStream + // )) + } + + async fn get_one_vm_node( + &self, + req: Request, + ) -> Result, Status> { + let req = check_sig_from_req(req)?; + info!("Unknown CLI requested ListVmNodesStream: {req:?}"); + todo!(); + // match self.data.get_one_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", + // )), + // } + } +} + +trait PubkeyGetter { + fn get_pubkey(&self) -> Option; +} + +macro_rules! impl_pubkey_getter { + ($t:ty, $field:ident) => { + impl PubkeyGetter for $t { + fn get_pubkey(&self) -> Option { + Some(self.$field.clone()) + } + } + }; + ($t:ty) => { + impl PubkeyGetter for $t { + fn get_pubkey(&self) -> Option { + None + } + } + }; +} + +impl_pubkey_getter!(Pubkey, pubkey); +impl_pubkey_getter!(NewVmReq, admin_pubkey); +impl_pubkey_getter!(DeleteVmReq, admin_pubkey); +impl_pubkey_getter!(ReportNodeReq, admin_pubkey); +impl_pubkey_getter!(UpdateVmReq, admin_pubkey); +impl_pubkey_getter!(ExtendVmReq, admin_pubkey); +impl_pubkey_getter!(ListVmContractsReq, wallet); +impl_pubkey_getter!(RegisterVmNodeReq, node_pubkey); +impl_pubkey_getter!(VmNodeFilters); +impl_pubkey_getter!(Empty); + +fn check_sig_from_req(req: Request) -> Result { + let time = match req.metadata().get("timestamp") { + Some(t) => t.clone(), + None => return Err(Status::unauthenticated("Timestamp not found in metadata.")), + }; + let time = time + .to_str() + .map_err(|_| Status::unauthenticated("Timestamp in metadata is not a string"))?; + + let now = chrono::Utc::now(); + 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 > 4 || seconds_elapsed < -4 { + return Err(Status::unauthenticated(format!( + "Date is not within 4 sec of the time of the server: CLI {} vs Server {}", + parsed_time, now + ))); + } + + let signature = match req.metadata().get("request-signature") { + Some(t) => t, + None => return Err(Status::unauthenticated("signature not found in metadata.")), + }; + let signature = bs58::decode(signature) + .into_vec() + .map_err(|_| Status::unauthenticated("signature is not a bs58 string"))?; + let signature = ed25519_dalek::Signature::from_bytes( + signature + .as_slice() + .try_into() + .map_err(|_| Status::unauthenticated("could not parse ed25519 signature"))?, + ); + + let pubkey_value = match req.metadata().get("pubkey") { + Some(p) => p.clone(), + None => return Err(Status::unauthenticated("pubkey not found in metadata.")), + }; + let pubkey = ed25519_dalek::VerifyingKey::from_bytes( + &bs58::decode(&pubkey_value) + .into_vec() + .map_err(|_| Status::unauthenticated("pubkey is not a bs58 string"))? + .try_into() + .map_err(|_| Status::unauthenticated("pubkey does not have the correct size."))?, + ) + .map_err(|_| Status::unauthenticated("could not parse ed25519 pubkey"))?; + + let req = req.into_inner(); + let message = format!("{time}{req:?}"); + use ed25519_dalek::Verifier; + pubkey + .verify(message.as_bytes(), &signature) + .map_err(|_| Status::unauthenticated("the signature is not valid"))?; + if let Some(req_pubkey) = req.get_pubkey() { + if pubkey_value.to_str().unwrap().to_string() != req_pubkey { + return Err(Status::unauthenticated( + "pubkey of signature does not match pubkey of request", + )); + } + } + Ok(req) +} diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..4377622 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,3 @@ +pub mod grpc; +pub mod models; +pub mod old_brain; diff --git a/src/surreal_brain.rs b/src/models.rs similarity index 98% rename from src/surreal_brain.rs rename to src/models.rs index a13fd70..072a1a3 100644 --- a/src/surreal_brain.rs +++ b/src/models.rs @@ -14,11 +14,7 @@ static DB: LazyLock> = LazyLock::new(Surreal::init); async fn init() -> surrealdb::Result<()> { DB.connect::("localhost:8000").await?; // Sign in to the server - DB.signin(Root { - username: "root", - password: "root", - }) - .await?; + DB.signin(Root { username: "root", password: "root" }).await?; DB.use_ns("brain").use_db("migration").await?; Ok(()) } @@ -73,27 +69,6 @@ pub struct Account { email: String, } -impl From<&old_brain::BrainData> for Vec { - fn from(old_data: &old_brain::BrainData) -> Self { - let mut accounts = Vec::new(); - for old_account in old_data.accounts.iter() { - let mut a = Account { - id: RecordId::from(("account", old_account.key())), - balance: old_account.value().balance, - tmp_locked: old_account.value().tmp_locked, - escrow: 0, - email: String::new(), - }; - if let Some(operator) = old_data.operators.get(old_account.key()) { - a.escrow = operator.escrow; - a.email = operator.email.clone(); - } - accounts.push(a); - } - accounts - } -} - #[derive(Debug, Serialize, Deserialize)] pub struct VmNode { id: RecordId, @@ -112,31 +87,6 @@ pub struct VmNode { offline_minutes: u64, } -impl From<&old_brain::BrainData> for Vec { - fn from(old_data: &old_brain::BrainData) -> Self { - let mut nodes = Vec::new(); - for old_node in old_data.vm_nodes.iter() { - nodes.push(VmNode { - id: RecordId::from(("vm_node", old_node.public_key.clone())), - country: old_node.country.clone(), - region: old_node.region.clone(), - city: old_node.city.clone(), - ip: old_node.ip.clone(), - avail_mem_mb: old_node.avail_mem_mb, - avail_vcpus: old_node.avail_vcpus, - avail_storage_gbs: old_node.avail_storage_gbs, - avail_ipv4: old_node.avail_ipv4, - avail_ipv6: old_node.avail_ipv6, - avail_ports: old_node.avail_ports, - max_ports_per_vm: old_node.max_ports_per_vm, - price: old_node.price, - offline_minutes: old_node.offline_minutes, - }); - } - nodes - } -} - #[derive(Debug, Serialize, Deserialize)] pub struct VmContract { id: RecordId, @@ -161,39 +111,6 @@ pub struct VmContract { collected_at: Datetime, } -impl From<&old_brain::BrainData> for Vec { - fn from(old_data: &old_brain::BrainData) -> Self { - let mut contracts = Vec::new(); - for old_c in old_data.vm_contracts.iter() { - let mut mapped_ports = Vec::new(); - for port in old_c.exposed_ports.iter() { - mapped_ports.push((*port, 8080 as u32)); - } - contracts.push(VmContract { - id: RecordId::from(("vm_contract", old_c.uuid.replace("-", ""))), - admin: RecordId::from(("account", old_c.admin_pubkey.clone())), - vm_node: RecordId::from(("vm_node", old_c.node_pubkey.clone())), - state: "active".to_string(), - hostname: old_c.hostname.clone(), - mapped_ports, - public_ipv4: old_c.public_ipv4.clone(), - public_ipv6: old_c.public_ipv6.clone(), - disk_size_gb: old_c.disk_size_gb, - vcpus: old_c.vcpus, - memory_mb: old_c.memory_mb, - dtrfs_sha: old_c.dtrfs_sha.clone(), - kernel_sha: old_c.kernel_sha.clone(), - price_per_unit: old_c.price_per_unit, - locked_nano: old_c.locked_nano, - created_at: old_c.created_at.into(), - updated_at: old_c.updated_at.into(), - collected_at: old_c.collected_at.into(), - }); - } - contracts - } -} - #[derive(Debug, Serialize, Deserialize)] pub struct AppNode { id: RecordId, @@ -210,29 +127,6 @@ pub struct AppNode { offline_minutes: u64, } -impl From<&old_brain::BrainData> for Vec { - fn from(old_data: &old_brain::BrainData) -> Self { - let mut nodes = Vec::new(); - for old_node in old_data.app_nodes.iter() { - nodes.push(AppNode { - id: RecordId::from(("app_node", old_node.node_pubkey.clone())), - country: old_node.country.clone(), - region: old_node.region.clone(), - city: old_node.city.clone(), - ip: old_node.ip.clone(), - avail_mem_mb: old_node.avail_mem_mb, - avail_vcpus: old_node.avail_vcpus, - avail_storage_gbs: old_node.avail_storage_mb, - avail_ports: old_node.avail_no_of_port, - max_ports_per_app: old_node.max_ports_per_app, - price: old_node.price, - offline_minutes: old_node.offline_minutes, - }); - } - nodes - } -} - #[derive(Debug, Serialize, Deserialize)] pub struct AppContract { id: RecordId, @@ -307,6 +201,110 @@ impl Operator { } } +// TODO: delete all of these From implementation after migration 0 gets executed + +impl From<&old_brain::BrainData> for Vec { + fn from(old_data: &old_brain::BrainData) -> Self { + let mut nodes = Vec::new(); + for old_node in old_data.vm_nodes.iter() { + nodes.push(VmNode { + id: RecordId::from(("vm_node", old_node.public_key.clone())), + country: old_node.country.clone(), + region: old_node.region.clone(), + city: old_node.city.clone(), + ip: old_node.ip.clone(), + avail_mem_mb: old_node.avail_mem_mb, + avail_vcpus: old_node.avail_vcpus, + avail_storage_gbs: old_node.avail_storage_gbs, + avail_ipv4: old_node.avail_ipv4, + avail_ipv6: old_node.avail_ipv6, + avail_ports: old_node.avail_ports, + max_ports_per_vm: old_node.max_ports_per_vm, + price: old_node.price, + offline_minutes: old_node.offline_minutes, + }); + } + nodes + } +} + +impl From<&old_brain::BrainData> for Vec { + fn from(old_data: &old_brain::BrainData) -> Self { + let mut contracts = Vec::new(); + for old_c in old_data.vm_contracts.iter() { + let mut mapped_ports = Vec::new(); + for port in old_c.exposed_ports.iter() { + mapped_ports.push((*port, 8080 as u32)); + } + contracts.push(VmContract { + id: RecordId::from(("vm_contract", old_c.uuid.replace("-", ""))), + admin: RecordId::from(("account", old_c.admin_pubkey.clone())), + vm_node: RecordId::from(("vm_node", old_c.node_pubkey.clone())), + state: "active".to_string(), + hostname: old_c.hostname.clone(), + mapped_ports, + public_ipv4: old_c.public_ipv4.clone(), + public_ipv6: old_c.public_ipv6.clone(), + disk_size_gb: old_c.disk_size_gb, + vcpus: old_c.vcpus, + memory_mb: old_c.memory_mb, + dtrfs_sha: old_c.dtrfs_sha.clone(), + kernel_sha: old_c.kernel_sha.clone(), + price_per_unit: old_c.price_per_unit, + locked_nano: old_c.locked_nano, + created_at: old_c.created_at.into(), + updated_at: old_c.updated_at.into(), + collected_at: old_c.collected_at.into(), + }); + } + contracts + } +} + +impl From<&old_brain::BrainData> for Vec { + fn from(old_data: &old_brain::BrainData) -> Self { + let mut nodes = Vec::new(); + for old_node in old_data.app_nodes.iter() { + nodes.push(AppNode { + id: RecordId::from(("app_node", old_node.node_pubkey.clone())), + country: old_node.country.clone(), + region: old_node.region.clone(), + city: old_node.city.clone(), + ip: old_node.ip.clone(), + avail_mem_mb: old_node.avail_mem_mb, + avail_vcpus: old_node.avail_vcpus, + avail_storage_gbs: old_node.avail_storage_mb, + avail_ports: old_node.avail_no_of_port, + max_ports_per_app: old_node.max_ports_per_app, + price: old_node.price, + offline_minutes: old_node.offline_minutes, + }); + } + nodes + } +} + +impl From<&old_brain::BrainData> for Vec { + fn from(old_data: &old_brain::BrainData) -> Self { + let mut accounts = Vec::new(); + for old_account in old_data.accounts.iter() { + let mut a = Account { + id: RecordId::from(("account", old_account.key())), + balance: old_account.value().balance, + tmp_locked: old_account.value().tmp_locked, + escrow: 0, + email: String::new(), + }; + if let Some(operator) = old_data.operators.get(old_account.key()) { + a.escrow = operator.escrow; + a.email = operator.email.clone(); + } + accounts.push(a); + } + accounts + } +} + impl From<&old_brain::BrainData> for Vec { fn from(old_data: &old_brain::BrainData) -> Self { let mut operator_entries = Vec::new(); diff --git a/src/old_brain.rs b/src/old_brain.rs index 79df79c..bbf42ec 100644 --- a/src/old_brain.rs +++ b/src/old_brain.rs @@ -1,3 +1,5 @@ +// TODO: delete this file after migration0 gets executed + use chrono::Utc; use dashmap::DashMap; use serde::{Deserialize, Serialize};