Compare commits
14 Commits
eaed502805
...
ee1b12f85f
Author | SHA1 | Date | |
---|---|---|---|
ee1b12f85f | |||
d4e499126d | |||
8d1721ca11 | |||
39ee3cd84b | |||
7b1bb98074 | |||
9bff01a440 | |||
6bd30bf87c | |||
ff72ff6c1e | |||
9363750d5b | |||
5de6bd7cbf | |||
786489fcbd | |||
af7d4157ee | |||
d398198f63 | |||
d1921eb838 |
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,3 +1,5 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
/target
|
||||
secrets
|
||||
tmp
|
||||
|
@ -5,4 +5,5 @@ DB_NAMESPACE = "brain"
|
||||
DB_NAME = "migration"
|
||||
CERT_PATH = "./tmp/brain-crt.pem"
|
||||
CERT_KEY_PATH = "./tmp/brain-key.pem"
|
||||
BRAIN_PUBLIC_ENDPOINT = "127.0.0.1:31337"
|
||||
# ADMIN_PUB_KEYS = "admin_key01, admin_key02, admin_key03"
|
||||
|
372
Cargo.lock
generated
372
Cargo.lock
generated
@ -1,5 +1,6 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
@ -439,7 +440,7 @@ dependencies = [
|
||||
"miniz_oxide",
|
||||
"object",
|
||||
"rustc-demangle",
|
||||
"windows-targets 0.52.6",
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -825,6 +826,16 @@ version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6"
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation"
|
||||
version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation-sys"
|
||||
version = "0.8.7"
|
||||
@ -1000,7 +1011,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "detee-shared"
|
||||
version = "0.1.0"
|
||||
source = "git+ssh://git@gitea.detee.cloud/testnet/proto?branch=surreal_brain_app#005677153b3fcd3251b64111a736c806106fdc04"
|
||||
source = "git+ssh://git@gitea.detee.cloud/testnet/proto?branch=surreal_brain_app#0b195b4589e4ec689af7ddca27dc051716ecee78"
|
||||
dependencies = [
|
||||
"bincode 2.0.1",
|
||||
"prost",
|
||||
@ -1257,6 +1268,21 @@ version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
|
||||
|
||||
[[package]]
|
||||
name = "foreign-types"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
|
||||
dependencies = [
|
||||
"foreign-types-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "foreign-types-shared"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
|
||||
|
||||
[[package]]
|
||||
name = "form_urlencoded"
|
||||
version = "1.2.1"
|
||||
@ -1697,7 +1723,7 @@ dependencies = [
|
||||
"tokio",
|
||||
"tokio-rustls",
|
||||
"tower-service",
|
||||
"webpki-roots",
|
||||
"webpki-roots 0.26.8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1714,23 +1740,45 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hyper-util"
|
||||
version = "0.1.11"
|
||||
name = "hyper-tls"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "497bbc33a26fdd4af9ed9c70d63f61cf56a938375fbb32df34db9b1cd6d643f2"
|
||||
checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"http-body-util",
|
||||
"hyper",
|
||||
"hyper-util",
|
||||
"native-tls",
|
||||
"tokio",
|
||||
"tokio-native-tls",
|
||||
"tower-service",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hyper-util"
|
||||
version = "0.1.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc2fdfdbff08affe55bb779f33b053aa1fe5dd5b54c257343c17edfa55711bdb"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"bytes",
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"http",
|
||||
"http-body",
|
||||
"hyper",
|
||||
"ipnet",
|
||||
"libc",
|
||||
"percent-encoding",
|
||||
"pin-project-lite",
|
||||
"socket2",
|
||||
"system-configuration",
|
||||
"tokio",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
"windows-registry",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1939,6 +1987,16 @@ version = "2.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130"
|
||||
|
||||
[[package]]
|
||||
name = "iri-string"
|
||||
version = "0.7.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "is_terminal_polyfill"
|
||||
version = "1.70.1"
|
||||
@ -2304,6 +2362,23 @@ dependencies = [
|
||||
"rand 0.8.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "native-tls"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
"openssl",
|
||||
"openssl-probe",
|
||||
"openssl-sys",
|
||||
"schannel",
|
||||
"security-framework",
|
||||
"security-framework-sys",
|
||||
"tempfile",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ndarray"
|
||||
version = "0.15.6"
|
||||
@ -2456,6 +2531,50 @@ version = "1.21.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
|
||||
|
||||
[[package]]
|
||||
name = "openssl"
|
||||
version = "0.10.73"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8505734d46c8ab1e19a1dce3aef597ad87dcb4c37e7188231769bd6bd51cebf8"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cfg-if",
|
||||
"foreign-types",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"openssl-macros",
|
||||
"openssl-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openssl-macros"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.100",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openssl-probe"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e"
|
||||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.9.109"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90096e2e47630d78b7d1c20952dc621f957103f8bc2c8359ec81290d75238571"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking"
|
||||
version = "2.2.1"
|
||||
@ -2482,7 +2601,7 @@ dependencies = [
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"smallvec",
|
||||
"windows-targets 0.52.6",
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2756,7 +2875,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "be769465445e8c1474e9c5dac2018218498557af32d9ed057325ec9a41ae81bf"
|
||||
dependencies = [
|
||||
"heck 0.5.0",
|
||||
"itertools 0.11.0",
|
||||
"itertools 0.14.0",
|
||||
"log",
|
||||
"multimap",
|
||||
"once_cell",
|
||||
@ -2776,7 +2895,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a56d757972c98b346a9b766e3f02746cde6dd1cd1d1d563472929fdd74bec4d"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"itertools 0.11.0",
|
||||
"itertools 0.14.0",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.100",
|
||||
@ -3095,48 +3214,53 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reqwest"
|
||||
version = "0.12.15"
|
||||
version = "0.12.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d19c46a6fdd48bc4dab94b6103fccc55d34c67cc0ad04653aad4ea2a07cd7bbb"
|
||||
checksum = "a2f8e5513d63f2e5b386eb5106dc67eaf3f84e95258e210489136b8b92ad6119"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"bytes",
|
||||
"encoding_rs",
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"h2",
|
||||
"http",
|
||||
"http-body",
|
||||
"http-body-util",
|
||||
"hyper",
|
||||
"hyper-rustls",
|
||||
"hyper-tls",
|
||||
"hyper-util",
|
||||
"ipnet",
|
||||
"js-sys",
|
||||
"log",
|
||||
"mime",
|
||||
"mime_guess",
|
||||
"native-tls",
|
||||
"once_cell",
|
||||
"percent-encoding",
|
||||
"pin-project-lite",
|
||||
"quinn",
|
||||
"rustls",
|
||||
"rustls-pemfile",
|
||||
"rustls-pki-types",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_urlencoded",
|
||||
"sync_wrapper",
|
||||
"tokio",
|
||||
"tokio-native-tls",
|
||||
"tokio-rustls",
|
||||
"tokio-util",
|
||||
"tower 0.5.2",
|
||||
"tower-http",
|
||||
"tower-service",
|
||||
"url",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures",
|
||||
"wasm-streams",
|
||||
"web-sys",
|
||||
"webpki-roots",
|
||||
"windows-registry",
|
||||
"webpki-roots 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3400,6 +3524,15 @@ dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "schannel"
|
||||
version = "0.1.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d"
|
||||
dependencies = [
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.2.0"
|
||||
@ -3424,6 +3557,29 @@ version = "4.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b"
|
||||
|
||||
[[package]]
|
||||
name = "security-framework"
|
||||
version = "2.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"core-foundation",
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
"security-framework-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "security-framework-sys"
|
||||
version = "2.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "1.0.26"
|
||||
@ -3802,6 +3958,7 @@ dependencies = [
|
||||
"log",
|
||||
"nanoid",
|
||||
"rand 0.8.5",
|
||||
"reqwest",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_yaml",
|
||||
@ -3997,6 +4154,27 @@ dependencies = [
|
||||
"windows",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "system-configuration"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"core-foundation",
|
||||
"system-configuration-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "system-configuration-sys"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tap"
|
||||
version = "1.0.1"
|
||||
@ -4191,6 +4369,16 @@ dependencies = [
|
||||
"syn 2.0.100",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-native-tls"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2"
|
||||
dependencies = [
|
||||
"native-tls",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-rustls"
|
||||
version = "0.26.2"
|
||||
@ -4225,7 +4413,7 @@ dependencies = [
|
||||
"tokio",
|
||||
"tokio-rustls",
|
||||
"tungstenite",
|
||||
"webpki-roots",
|
||||
"webpki-roots 0.26.8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4340,6 +4528,24 @@ dependencies = [
|
||||
"tower-service",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tower-http"
|
||||
version = "0.6.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bytes",
|
||||
"futures-util",
|
||||
"http",
|
||||
"http-body",
|
||||
"iri-string",
|
||||
"pin-project-lite",
|
||||
"tower 0.5.2",
|
||||
"tower-layer",
|
||||
"tower-service",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tower-layer"
|
||||
version = "0.3.3"
|
||||
@ -4570,6 +4776,12 @@ version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87782b74f898179396e93c0efabb38de0d58d50bbd47eae00c71b3a1144dbbae"
|
||||
|
||||
[[package]]
|
||||
name = "vcpkg"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.5"
|
||||
@ -4742,6 +4954,15 @@ dependencies = [
|
||||
"rustls-pki-types",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "webpki-roots"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2853738d1cc4f2da3a225c18ec6c3721abb31961096e9dbf5ab35fa88b19cfdb"
|
||||
dependencies = [
|
||||
"rustls-pki-types",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
@ -4780,7 +5001,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "12342cb4d8e3b046f3d80effd474a7a02447231330ef77d71daa6fbc40681143"
|
||||
dependencies = [
|
||||
"windows-core 0.57.0",
|
||||
"windows-targets 0.52.6",
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4792,7 +5013,7 @@ dependencies = [
|
||||
"windows-implement 0.57.0",
|
||||
"windows-interface 0.57.0",
|
||||
"windows-result 0.1.2",
|
||||
"windows-targets 0.52.6",
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4804,8 +5025,8 @@ dependencies = [
|
||||
"windows-implement 0.60.0",
|
||||
"windows-interface 0.59.1",
|
||||
"windows-link",
|
||||
"windows-result 0.3.2",
|
||||
"windows-strings 0.4.0",
|
||||
"windows-result 0.3.4",
|
||||
"windows-strings",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4860,13 +5081,13 @@ checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38"
|
||||
|
||||
[[package]]
|
||||
name = "windows-registry"
|
||||
version = "0.4.0"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4286ad90ddb45071efd1a66dfa43eb02dd0dfbae1545ad6cc3c51cf34d7e8ba3"
|
||||
checksum = "b3bab093bdd303a1240bb99b8aba8ea8a69ee19d34c9e2ef9594e708a4878820"
|
||||
dependencies = [
|
||||
"windows-result 0.3.2",
|
||||
"windows-strings 0.3.1",
|
||||
"windows-targets 0.53.0",
|
||||
"windows-link",
|
||||
"windows-result 0.3.4",
|
||||
"windows-strings",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4875,32 +5096,23 @@ version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8"
|
||||
dependencies = [
|
||||
"windows-targets 0.52.6",
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-result"
|
||||
version = "0.3.2"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252"
|
||||
checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6"
|
||||
dependencies = [
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-strings"
|
||||
version = "0.3.1"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319"
|
||||
dependencies = [
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-strings"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a2ba9642430ee452d5a7aa78d72907ebe8cfda358e8cb7918a2050581322f97"
|
||||
checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57"
|
||||
dependencies = [
|
||||
"windows-link",
|
||||
]
|
||||
@ -4911,7 +5123,7 @@ version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
|
||||
dependencies = [
|
||||
"windows-targets 0.52.6",
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4920,7 +5132,7 @@ version = "0.59.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
|
||||
dependencies = [
|
||||
"windows-targets 0.52.6",
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4929,30 +5141,14 @@ version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm 0.52.6",
|
||||
"windows_aarch64_msvc 0.52.6",
|
||||
"windows_i686_gnu 0.52.6",
|
||||
"windows_i686_gnullvm 0.52.6",
|
||||
"windows_i686_msvc 0.52.6",
|
||||
"windows_x86_64_gnu 0.52.6",
|
||||
"windows_x86_64_gnullvm 0.52.6",
|
||||
"windows_x86_64_msvc 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b1e4c7e8ceaaf9cb7d7507c974735728ab453b67ef8f18febdd7c11fe59dca8b"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm 0.53.0",
|
||||
"windows_aarch64_msvc 0.53.0",
|
||||
"windows_i686_gnu 0.53.0",
|
||||
"windows_i686_gnullvm 0.53.0",
|
||||
"windows_i686_msvc 0.53.0",
|
||||
"windows_x86_64_gnu 0.53.0",
|
||||
"windows_x86_64_gnullvm 0.53.0",
|
||||
"windows_x86_64_msvc 0.53.0",
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_gnullvm",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4961,96 +5157,48 @@ version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnullvm"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"
|
||||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.7.6"
|
||||
|
@ -1,3 +1,5 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
[package]
|
||||
name = "surreal-brain"
|
||||
version = "0.1.0"
|
||||
@ -38,4 +40,5 @@ ed25519-dalek = { version = "2.1.1", features = ["rand_core"] }
|
||||
hyper-util = "0.1.11"
|
||||
itertools = "0.14.0"
|
||||
rand = "0.8"
|
||||
reqwest = { version = "0.12.19", features = ["blocking"] }
|
||||
tower = "0.5.2"
|
||||
|
474
LICENSE
474
LICENSE
@ -1,338 +1,202 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
<https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
Preamble
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
1. Definitions.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Moe Ghoul>, 1 April 1989
|
||||
Moe Ghoul, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
@ -1 +1,5 @@
|
||||
<!--
|
||||
SPDX-License-Identifier: Apache-2.0
|
||||
-->
|
||||
|
||||
# Brain Miration to SurrealDB
|
@ -1,3 +1,5 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
reorder_impl_items = true
|
||||
use_small_heuristics = "Max"
|
||||
imports_granularity = "Module"
|
||||
|
@ -1,3 +1,5 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
accounts:
|
||||
DXXkYSnhP3ijsHYxkedcuMomEyc122WaAbkDX7SaGuUS:
|
||||
balance: 20293420000
|
||||
|
1
scripts/ca_cert.pem.license
Normal file
1
scripts/ca_cert.pem.license
Normal file
@ -0,0 +1 @@
|
||||
SPDX-License-Identifier: Apache-2.0
|
@ -1,4 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
cd -- "$( dirname -- "${BASH_SOURCE[0]}" )"
|
||||
|
||||
mkdir -p secrets
|
||||
|
@ -1,4 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
cd -- "$( dirname -- "${BASH_SOURCE[0]}" )"
|
||||
cd ..
|
||||
|
||||
@ -10,7 +13,7 @@ server="$1"
|
||||
}
|
||||
|
||||
[[ "$server" == "testnet" ]] && server="root@prod-brain-1"
|
||||
[[ "$server" == "staging" ]] && server="root@staging-brain-1"
|
||||
[[ "$server" == "staging" ]] && server="brain-staging"
|
||||
|
||||
cargo build --release --bin brain
|
||||
ssh $server systemctl stop detee-brain.service
|
||||
|
1
scripts/staging_cert.pem.license
Normal file
1
scripts/staging_cert.pem.license
Normal file
@ -0,0 +1 @@
|
||||
SPDX-License-Identifier: Apache-2.0
|
1
scripts/testnet_cert.pem.license
Normal file
1
scripts/testnet_cert.pem.license
Normal file
@ -0,0 +1 @@
|
||||
SPDX-License-Identifier: Apache-2.0
|
@ -1,9 +1,12 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use detee_shared::app_proto::brain_app_cli_server::BrainAppCliServer;
|
||||
use detee_shared::app_proto::brain_app_daemon_server::BrainAppDaemonServer;
|
||||
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;
|
||||
use dotenv::dotenv;
|
||||
use std::net::SocketAddr;
|
||||
use std::sync::Arc;
|
||||
use surreal_brain::constants::{BRAIN_GRPC_ADDR, CERT_KEY_PATH, CERT_PATH};
|
||||
use surreal_brain::db;
|
||||
@ -19,6 +22,7 @@ async fn main() {
|
||||
}
|
||||
env_logger::builder()
|
||||
.filter_level(log::LevelFilter::Trace)
|
||||
.filter_module("rustls", log::LevelFilter::Debug)
|
||||
.filter_module("tungstenite", log::LevelFilter::Debug)
|
||||
.filter_module("tokio_tungstenite", log::LevelFilter::Debug)
|
||||
.init();
|
||||
@ -29,6 +33,12 @@ async fn main() {
|
||||
let db_ns = std::env::var("DB_NAMESPACE").expect("the env variable DB_NAMESPACE is not set");
|
||||
let db_name = std::env::var("DB_NAME").expect("the environment variable DB_NAME is not set");
|
||||
|
||||
// To make sure env is set correctly
|
||||
std::env::var("BRAIN_PUBLIC_ENDPOINT")
|
||||
.expect("the environment variable BRAIN_PUBLIC_ENDPOINT is not set")
|
||||
.parse::<SocketAddr>()
|
||||
.expect("BRAIN_PUBLIC_ENDPOINT is not a socket address");
|
||||
|
||||
let db = db::db_connection(&db_url, &db_user, &db_pass, &db_ns, &db_name).await.unwrap();
|
||||
let db_arc = Arc::new(db);
|
||||
|
||||
|
52
src/bin/brain_local.rs
Normal file
52
src/bin/brain_local.rs
Normal file
@ -0,0 +1,52 @@
|
||||
use detee_shared::app_proto::brain_app_cli_server::BrainAppCliServer;
|
||||
use detee_shared::app_proto::brain_app_daemon_server::BrainAppDaemonServer;
|
||||
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;
|
||||
use dotenv::dotenv;
|
||||
use std::sync::Arc;
|
||||
use surreal_brain::constants::BRAIN_GRPC_ADDR;
|
||||
use surreal_brain::db;
|
||||
use surreal_brain::grpc::app::{AppCliServer, AppDaemonServer};
|
||||
use surreal_brain::grpc::general::GeneralCliServer;
|
||||
use surreal_brain::grpc::vm::{VmCliServer, VmDaemonServer};
|
||||
use tonic::transport::Server;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
if dotenv::from_filename("/etc/detee/brain/config.ini").is_err() {
|
||||
dotenv().ok();
|
||||
}
|
||||
env_logger::builder()
|
||||
.filter_level(log::LevelFilter::Trace)
|
||||
.filter_module("tungstenite", log::LevelFilter::Debug)
|
||||
.filter_module("tokio_tungstenite", log::LevelFilter::Debug)
|
||||
.init();
|
||||
|
||||
let db_url = std::env::var("DB_URL").expect("the environment variable DB_URL is not set");
|
||||
let db_user = std::env::var("DB_USER").expect("the environment variable DB_USER is not set");
|
||||
let db_pass = std::env::var("DB_PASS").expect("the environment variable DB_PASS is not set");
|
||||
let db_ns = std::env::var("DB_NAMESPACE").expect("the env variable DB_NAMESPACE is not set");
|
||||
let db_name = std::env::var("DB_NAME").expect("the environment variable DB_NAME is not set");
|
||||
|
||||
let db = db::db_connection(&db_url, &db_user, &db_pass, &db_ns, &db_name).await.unwrap();
|
||||
let db_arc = Arc::new(db);
|
||||
|
||||
let addr = BRAIN_GRPC_ADDR.parse().unwrap();
|
||||
|
||||
let snp_daemon_server = BrainVmDaemonServer::new(VmDaemonServer::new(db_arc.clone()));
|
||||
let snp_cli_server = BrainVmCliServer::new(VmCliServer::new(db_arc.clone()));
|
||||
let general_service_server = BrainGeneralCliServer::new(GeneralCliServer::new(db_arc.clone()));
|
||||
let sgx_daemon_server = BrainAppDaemonServer::new(AppDaemonServer::new(db_arc.clone()));
|
||||
let sgx_cli_server = BrainAppCliServer::new(AppCliServer::new(db_arc.clone()));
|
||||
|
||||
Server::builder()
|
||||
.add_service(snp_daemon_server)
|
||||
.add_service(snp_cli_server)
|
||||
.add_service(general_service_server)
|
||||
.add_service(sgx_daemon_server)
|
||||
.add_service(sgx_cli_server)
|
||||
.serve(addr)
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
@ -1,3 +1,5 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// After deleting this migration, also delete old_brain structs
|
||||
// and dangling impls from the model
|
||||
use dotenv::dotenv;
|
||||
|
@ -1,6 +1,9 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use std::sync::LazyLock;
|
||||
|
||||
pub const BRAIN_GRPC_ADDR: &str = "0.0.0.0:31337";
|
||||
|
||||
pub const CERT_PATH: &str = "/etc/detee/brain/brain-crt.pem";
|
||||
pub const CERT_KEY_PATH: &str = "/etc/detee/brain/brain-key.pem";
|
||||
pub const CONFIG_PATH: &str = "/etc/detee/brain/config.ini";
|
||||
@ -51,3 +54,5 @@ pub const MIN_ESCROW: u64 = 5000 * TOKEN_DECIMAL;
|
||||
|
||||
pub const APP_DAEMON_TIMEOUT: u64 = 20;
|
||||
pub const VM_DAEMON_TIMEOUT: u64 = 10;
|
||||
|
||||
pub const DEFAULT_ENDPOINT: &str = "127.0.0.1:31337";
|
||||
|
@ -1,8 +1,10 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use std::time::Duration;
|
||||
|
||||
use super::Error;
|
||||
use crate::constants::{
|
||||
ACCOUNT, ACTIVE_APP, APP_DAEMON_TIMEOUT, APP_NODE, DELETED_APP, NEW_APP_REQ,
|
||||
ACCOUNT, ACTIVE_APP, APP_DAEMON_TIMEOUT, APP_NODE, DEFAULT_ENDPOINT, DELETED_APP, NEW_APP_REQ,
|
||||
};
|
||||
use crate::db;
|
||||
use crate::db::general::Report;
|
||||
@ -18,6 +20,7 @@ use tokio_stream::StreamExt;
|
||||
pub struct AppNode {
|
||||
pub id: RecordId,
|
||||
pub operator: RecordId,
|
||||
pub pub_sub_node: String,
|
||||
pub country: String,
|
||||
pub region: String,
|
||||
pub city: String,
|
||||
@ -83,6 +86,12 @@ impl NewAppReq {
|
||||
let new_app_req: Option<Self> = db.select((NEW_APP_REQ, id)).await?;
|
||||
Ok(new_app_req)
|
||||
}
|
||||
|
||||
pub async fn delete(db: &Surreal<Client>, id: &str) -> Result<(), Error> {
|
||||
let _: Option<Self> = db.delete((NEW_APP_REQ, id)).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn submit_error(db: &Surreal<Client>, id: &str, error: String) -> Result<(), Error> {
|
||||
let tx_query = String::from(
|
||||
"
|
||||
@ -133,7 +142,7 @@ impl NewAppReq {
|
||||
|
||||
pub async fn submit(self, db: &Surreal<Client>) -> Result<(), Error> {
|
||||
let locked_nano = self.locked_nano;
|
||||
let tx_query = format!( "
|
||||
let tx_query = format!("
|
||||
BEGIN TRANSACTION;
|
||||
|
||||
LET $account = $account_input;
|
||||
@ -150,7 +159,6 @@ impl NewAppReq {
|
||||
}};
|
||||
UPDATE $account SET tmp_locked += {locked_nano};
|
||||
|
||||
|
||||
RELATE
|
||||
$account
|
||||
->$new_app_req
|
||||
@ -161,8 +169,7 @@ impl NewAppReq {
|
||||
vcpus: {}, disk_size_gb: {}, locked_nano: {locked_nano}, price_per_unit: {}, error: '',
|
||||
}};
|
||||
|
||||
COMMIT TRANSACTION;
|
||||
",
|
||||
COMMIT TRANSACTION;",
|
||||
self.ports, self.memory_mb, self.vcpus, self.disk_size_gb, self.price_per_unit);
|
||||
|
||||
log::trace!("submit_new_app_req query: {tx_query}");
|
||||
@ -222,7 +229,7 @@ impl AppNodeWithReports {
|
||||
limit_one: bool,
|
||||
) -> Result<Vec<Self>, Error> {
|
||||
let mut filter_query = format!(
|
||||
"select *, <-report.* from {APP_NODE} where
|
||||
"select *, <-report.* as reports from {APP_NODE} where
|
||||
avail_ports >= {} &&
|
||||
max_ports_per_app >= {} &&
|
||||
avail_vcpus >= {} &&
|
||||
@ -232,9 +239,10 @@ impl AppNodeWithReports {
|
||||
filters.free_ports,
|
||||
filters.vcpus,
|
||||
filters.memory_mb,
|
||||
filters.storage_mb
|
||||
filters.storage_gb
|
||||
);
|
||||
|
||||
// TODO: bind all strings
|
||||
if !filters.city.is_empty() {
|
||||
filter_query += &format!("&& city = '{}' ", filters.city);
|
||||
}
|
||||
@ -312,6 +320,15 @@ impl ActiveApp {
|
||||
(self.vcpus as f64 * 5f64) + (self.memory_mb as f64 / 200f64) + (self.disk_size_gb as f64)
|
||||
}
|
||||
|
||||
pub async fn get_by_uuid(db: &Surreal<Client>, uuid: &str) -> Result<Option<Self>, Error> {
|
||||
let contract: Option<Self> = db
|
||||
.query("select * from $active_app_id;".to_string())
|
||||
.bind(("active_app_id", RecordId::from((ACTIVE_APP, uuid))))
|
||||
.await?
|
||||
.take(0)?;
|
||||
Ok(contract)
|
||||
}
|
||||
|
||||
pub async fn activate(
|
||||
db: &Surreal<Client>,
|
||||
new_app_res: app_proto::NewAppRes,
|
||||
@ -333,7 +350,7 @@ impl ActiveApp {
|
||||
app_node: new_app_req.app_node,
|
||||
app_name: new_app_req.app_name,
|
||||
mapped_ports,
|
||||
host_ipv4: String::new(),
|
||||
host_ipv4: new_app_res.ip_address,
|
||||
vcpus: new_app_req.vcpus,
|
||||
memory_mb: new_app_req.memory_mb,
|
||||
disk_size_gb: new_app_req.disk_size_gb,
|
||||
@ -350,7 +367,7 @@ impl ActiveApp {
|
||||
let locked_nano = active_app.locked_nano;
|
||||
|
||||
let _: Vec<ActiveApp> = db.insert(()).relation(active_app).await?;
|
||||
db.delete::<Option<NewAppReq>>((NEW_APP_REQ, &new_app_res.uuid)).await?;
|
||||
NewAppReq::delete(&db, &new_app_res.uuid).await?;
|
||||
db.query(format!("UPDATE {ACCOUNT}:{admin_account} SET tmp_locked -= {locked_nano};"))
|
||||
.await?;
|
||||
|
||||
@ -457,7 +474,6 @@ impl WrappedAppResp {
|
||||
match active_app_notif {
|
||||
Ok(active_app_notif) =>{
|
||||
if active_app_notif.action == surrealdb::Action::Create {
|
||||
let _: Option<NewAppReq> = db.delete((NEW_APP_REQ, app_id)).await?;
|
||||
return Ok(Self::NewAppRes(active_app_notif.data.into()));
|
||||
}
|
||||
}
|
||||
@ -581,10 +597,10 @@ impl ActiveAppWithNode {
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct AppNodeResources {
|
||||
pub avail_no_of_port: u32,
|
||||
pub avail_ports: u32,
|
||||
pub avail_vcpus: u32,
|
||||
pub avail_memory_mb: u32,
|
||||
pub avail_storage_mb: u32,
|
||||
pub avail_mem_mb: u32,
|
||||
pub avail_storage_gbs: u32,
|
||||
pub max_ports_per_app: u32,
|
||||
}
|
||||
|
||||
@ -595,6 +611,7 @@ impl AppNodeResources {
|
||||
node_pubkey: &str,
|
||||
) -> Result<Option<AppNode>, Error> {
|
||||
let app_node: Option<AppNode> = db.update((APP_NODE, node_pubkey)).merge(self).await?;
|
||||
log::trace!("Merged app node resources for {node_pubkey}: {:?}", app_node);
|
||||
Ok(app_node)
|
||||
}
|
||||
}
|
||||
@ -606,6 +623,7 @@ impl From<&old_brain::BrainData> for Vec<AppNode> {
|
||||
nodes.push(AppNode {
|
||||
id: RecordId::from((APP_NODE, old_node.node_pubkey.clone())),
|
||||
operator: RecordId::from((ACCOUNT, old_node.operator_wallet.clone())),
|
||||
pub_sub_node: DEFAULT_ENDPOINT.to_string(),
|
||||
country: old_node.country.clone(),
|
||||
region: old_node.region.clone(),
|
||||
city: old_node.city.clone(),
|
||||
@ -685,6 +703,7 @@ pub struct DeletedApp {
|
||||
|
||||
impl DeletedApp {
|
||||
pub async fn list_by_node(db: &Surreal<Client>, node_pubkey: &str) -> Result<Vec<Self>, Error> {
|
||||
// TODO: bind all strings
|
||||
let mut result = db
|
||||
.query(format!("select * from {DELETED_APP} where out = {APP_NODE}:{node_pubkey};"))
|
||||
.await?;
|
||||
|
@ -1,3 +1,5 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use super::Error;
|
||||
use crate::constants::{ACCOUNT, BAN, KICK, MIN_ESCROW, VM_NODE};
|
||||
use crate::db::prelude::*;
|
||||
|
@ -1,17 +1,19 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
pub mod app;
|
||||
pub mod general;
|
||||
pub mod vm;
|
||||
|
||||
use crate::constants::{
|
||||
APP_NODE, DB_SCHEMA_FILES, DELETED_APP, DELETED_VM, MIN_ESCROW, NEW_APP_REQ, NEW_VM_REQ,
|
||||
UPDATE_VM_REQ,
|
||||
APP_NODE, DB_SCHEMA_FILES, DEFAULT_ENDPOINT, DELETED_APP, DELETED_VM, MIN_ESCROW, NEW_APP_REQ,
|
||||
NEW_VM_REQ, UPDATE_VM_REQ,
|
||||
};
|
||||
use crate::old_brain;
|
||||
use prelude::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use surrealdb::engine::remote::ws::{Client, Ws};
|
||||
use surrealdb::opt::auth::Root;
|
||||
use surrealdb::{Notification, Surreal};
|
||||
use surrealdb::{Notification, RecordId, Surreal};
|
||||
use tokio::sync::mpsc::Sender;
|
||||
use tokio_stream::StreamExt;
|
||||
|
||||
@ -51,6 +53,8 @@ pub enum Error {
|
||||
TooBigTransaction(String),
|
||||
#[error("Unknown: {0}")]
|
||||
Unknown(String),
|
||||
#[error(transparent)]
|
||||
Tonic(#[from] tonic::Status),
|
||||
}
|
||||
|
||||
pub mod prelude {
|
||||
@ -169,6 +173,8 @@ pub async fn live_appnode_msgs<
|
||||
return Err(Error::UnknownTable(t.to_string()));
|
||||
}
|
||||
};
|
||||
log::trace!("live_appnode_msgs for {table_name} DB stream for node {node_pubkey}");
|
||||
// TODO: bind node_pubkey
|
||||
let mut query_resp = db
|
||||
.query(format!("live select * from {table_name} where out = {APP_NODE}:{node_pubkey};"))
|
||||
.await?;
|
||||
@ -194,7 +200,36 @@ pub async fn live_appnode_msgs<
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn check_pubsub_node(
|
||||
db: &Surreal<Client>,
|
||||
id: RecordId,
|
||||
) -> Result<Option<tonic::Status>, Error> {
|
||||
let pub_endpoint =
|
||||
std::env::var("BRAIN_PUBLIC_ENDPOINT").unwrap_or(DEFAULT_ENDPOINT.to_string());
|
||||
|
||||
let mut query_resp =
|
||||
db.query("select pub_sub_node from $record_id").bind(("record_id", id)).await?;
|
||||
let node_endpoint = query_resp
|
||||
.take::<Option<PubSubNode>>(0)?
|
||||
.ok_or(tonic::Status::internal("Could not get current brain endpoint"))?
|
||||
.pub_sub_node;
|
||||
|
||||
if pub_endpoint == node_endpoint {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
let mut status = tonic::Status::new(tonic::Code::Unavailable, "moved");
|
||||
status.metadata_mut().insert("location", node_endpoint.parse().unwrap());
|
||||
|
||||
Ok(Some(status))
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug, Clone)]
|
||||
pub struct ErrorFromTable {
|
||||
pub error: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
struct PubSubNode {
|
||||
pub pub_sub_node: String,
|
||||
}
|
||||
|
15
src/db/vm.rs
15
src/db/vm.rs
@ -1,10 +1,12 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use std::str::FromStr;
|
||||
use std::time::Duration;
|
||||
|
||||
use super::Error;
|
||||
use crate::constants::{
|
||||
ACCOUNT, ACTIVE_VM, DELETED_VM, NEW_VM_REQ, UPDATE_VM_REQ, VM_DAEMON_TIMEOUT, VM_NODE,
|
||||
VM_UPDATE_EVENT,
|
||||
ACCOUNT, ACTIVE_VM, DEFAULT_ENDPOINT, DELETED_VM, NEW_VM_REQ, UPDATE_VM_REQ, VM_DAEMON_TIMEOUT,
|
||||
VM_NODE, VM_UPDATE_EVENT,
|
||||
};
|
||||
use crate::db::{Account, ErrorFromTable, Report};
|
||||
use crate::old_brain;
|
||||
@ -19,6 +21,7 @@ use tokio_stream::StreamExt as _;
|
||||
pub struct VmNode {
|
||||
pub id: RecordId,
|
||||
pub operator: RecordId,
|
||||
pub pub_sub_node: String,
|
||||
pub country: String,
|
||||
pub region: String,
|
||||
pub city: String,
|
||||
@ -430,8 +433,11 @@ impl ActiveVm {
|
||||
}
|
||||
|
||||
pub async fn get_by_uuid(db: &Surreal<Client>, uuid: &str) -> Result<Option<Self>, Error> {
|
||||
let contract: Option<Self> =
|
||||
db.query(format!("select * from {ACTIVE_VM}:{uuid};")).await?.take(0)?;
|
||||
let contract: Option<Self> = db
|
||||
.query("select * from $active_vm_id;".to_string())
|
||||
.bind(("active_vm_id", RecordId::from((ACTIVE_VM, uuid))))
|
||||
.await?
|
||||
.take(0)?;
|
||||
Ok(contract)
|
||||
}
|
||||
|
||||
@ -994,6 +1000,7 @@ impl From<&old_brain::BrainData> for Vec<VmNode> {
|
||||
nodes.push(VmNode {
|
||||
id: RecordId::from((VM_NODE, old_node.public_key.clone())),
|
||||
operator: RecordId::from((ACCOUNT, old_node.operator_wallet.clone())),
|
||||
pub_sub_node: DEFAULT_ENDPOINT.to_string(),
|
||||
country: old_node.country.clone(),
|
||||
region: old_node.region.clone(),
|
||||
city: old_node.city.clone(),
|
||||
|
@ -1,4 +1,6 @@
|
||||
use crate::constants::{ACCOUNT, APP_NODE};
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::constants::{ACCOUNT, APP_NODE, DEFAULT_ENDPOINT};
|
||||
use crate::db::app::ActiveApp;
|
||||
use crate::db::prelude as db;
|
||||
use crate::grpc::{check_sig_from_parts, check_sig_from_req};
|
||||
@ -42,6 +44,8 @@ impl BrainAppDaemon for AppDaemonServer {
|
||||
let app_node = db::AppNode {
|
||||
id: RecordId::from((APP_NODE, req.node_pubkey.clone())),
|
||||
operator: RecordId::from((ACCOUNT, req.operator_wallet)),
|
||||
pub_sub_node: std::env::var("BRAIN_PUBLIC_ENDPOINT")
|
||||
.unwrap_or(DEFAULT_ENDPOINT.to_string()),
|
||||
country: req.country,
|
||||
region: req.region,
|
||||
city: req.city,
|
||||
@ -137,6 +141,7 @@ impl BrainAppDaemon for AppDaemonServer {
|
||||
match daemon_message {
|
||||
Ok(msg) => match msg.msg {
|
||||
Some(daemon_message_app::Msg::NewAppRes(new_app_resp)) => {
|
||||
log::trace!("New app response from node: {pubkey}, {:?}", new_app_resp);
|
||||
if !new_app_resp.error.is_empty() {
|
||||
db::NewAppReq::submit_error(
|
||||
&self.db,
|
||||
@ -150,6 +155,7 @@ impl BrainAppDaemon for AppDaemonServer {
|
||||
}
|
||||
Some(daemon_message_app::Msg::AppNodeResources(app_node_resources)) => {
|
||||
let node_resource: db::AppNodeResources = app_node_resources.into();
|
||||
log::trace!("App node {pubkey} resources: {:?}", node_resource);
|
||||
node_resource.merge(&self.db, &pubkey).await?;
|
||||
}
|
||||
_ => {}
|
||||
@ -182,6 +188,13 @@ impl BrainAppCli for AppCliServer {
|
||||
|
||||
async fn new_app(&self, req: Request<NewAppReq>) -> Result<Response<NewAppRes>, Status> {
|
||||
let req = check_sig_from_req(req)?;
|
||||
|
||||
let id = surrealdb::RecordId::from((APP_NODE, req.node_pubkey.clone()));
|
||||
if let Some(redirect) = db::check_pubsub_node(&self.db, id).await? {
|
||||
log::info!("redirect: {redirect}");
|
||||
return Err(redirect);
|
||||
}
|
||||
|
||||
// TODO: make it atleast 1 hour
|
||||
if req.locked_nano < 100 {
|
||||
log::error!("locking lessthan 100 nano lps: {}", req.locked_nano);
|
||||
@ -215,7 +228,9 @@ impl BrainAppCli for AppCliServer {
|
||||
))
|
||||
}
|
||||
Err(e) => {
|
||||
log::error!("Something weird happened during CLI NewAppReq. Reached error {e:?}");
|
||||
log::error!(
|
||||
"Something wrong happened on channel during CLI NewAppReq. Reached error {e:?}"
|
||||
);
|
||||
Err(Status::unknown(
|
||||
"Unknown error. Please try again or contact the DeTEE devs team.",
|
||||
))
|
||||
@ -225,6 +240,15 @@ impl BrainAppCli for AppCliServer {
|
||||
|
||||
async fn delete_app(&self, req: Request<DelAppReq>) -> Result<Response<Empty>, Status> {
|
||||
let req = check_sig_from_req(req)?;
|
||||
let app_node = db::ActiveApp::get_by_uuid(&self.db, &req.uuid)
|
||||
.await?
|
||||
.ok_or(Status::permission_denied("Unauthorized"))?
|
||||
.app_node;
|
||||
|
||||
if let Some(redirect) = db::check_pubsub_node(&self.db, app_node).await? {
|
||||
log::info!("redirect: {redirect}");
|
||||
return Err(redirect);
|
||||
}
|
||||
info!("delete_app process starting for {:?}", req);
|
||||
match ActiveApp::delete(&self.db, &req.admin_pubkey, &req.uuid).await {
|
||||
Ok(()) => Ok(Response::new(Empty {})),
|
||||
|
@ -1,3 +1,5 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::db::prelude as db;
|
||||
use crate::grpc::{check_admin_key, check_sig_from_req};
|
||||
use detee_shared::app_proto::AppContract;
|
||||
|
@ -1,3 +1,5 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
pub mod app;
|
||||
pub mod general;
|
||||
pub mod types;
|
||||
|
@ -1,3 +1,5 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::constants::{ACCOUNT, APP_NODE, ID_ALPHABET, NEW_APP_REQ, NEW_VM_REQ, VM_NODE};
|
||||
use crate::db::prelude as db;
|
||||
use detee_shared::app_proto::AppNodeListResp;
|
||||
@ -289,7 +291,7 @@ impl From<db::ActiveAppWithNode> for AppContract {
|
||||
nano_per_minute: value.price_per_unit,
|
||||
locked_nano: value.locked_nano,
|
||||
collected_at: value.collected_at.to_rfc3339(),
|
||||
hratls_pubkey: value.mr_enclave,
|
||||
hratls_pubkey: value.hratls_pubkey,
|
||||
public_package_mr_enclave,
|
||||
app_name: value.app_name,
|
||||
}
|
||||
@ -373,10 +375,10 @@ impl From<db::AppDaemonMsg> for BrainMessageApp {
|
||||
impl From<AppNodeResources> for db::AppNodeResources {
|
||||
fn from(value: AppNodeResources) -> Self {
|
||||
Self {
|
||||
avail_no_of_port: value.avail_no_of_port,
|
||||
avail_ports: value.avail_no_of_port,
|
||||
avail_vcpus: value.avail_vcpus,
|
||||
avail_memory_mb: value.avail_memory_mb,
|
||||
avail_storage_mb: value.avail_storage_mb,
|
||||
avail_mem_mb: value.avail_memory_mb,
|
||||
avail_storage_gbs: value.avail_storage_gb,
|
||||
max_ports_per_app: value.max_ports_per_app,
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,8 @@
|
||||
#![allow(dead_code)]
|
||||
use crate::constants::{ACCOUNT, NEW_VM_REQ, UPDATE_VM_REQ, VM_NODE};
|
||||
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::constants::{ACCOUNT, DEFAULT_ENDPOINT, NEW_VM_REQ, UPDATE_VM_REQ, VM_NODE};
|
||||
use crate::db::prelude as db;
|
||||
use crate::grpc::{check_sig_from_parts, check_sig_from_req};
|
||||
use detee_shared::common_proto::Empty;
|
||||
@ -41,6 +44,8 @@ impl BrainVmDaemon for VmDaemonServer {
|
||||
db::VmNode {
|
||||
id: surrealdb::RecordId::from((VM_NODE, req.node_pubkey.clone())),
|
||||
operator: surrealdb::RecordId::from((ACCOUNT, req.operator_wallet)),
|
||||
pub_sub_node: std::env::var("BRAIN_PUBLIC_ENDPOINT")
|
||||
.unwrap_or(DEFAULT_ENDPOINT.to_string()),
|
||||
country: req.country,
|
||||
region: req.region,
|
||||
city: req.city,
|
||||
@ -222,6 +227,12 @@ impl BrainVmCli for VmCliServer {
|
||||
|
||||
async fn new_vm(&self, req: Request<NewVmReq>) -> Result<Response<NewVmResp>, Status> {
|
||||
let req = check_sig_from_req(req)?;
|
||||
let id = surrealdb::RecordId::from((VM_NODE, req.node_pubkey.clone()));
|
||||
if let Some(redirect) = db::check_pubsub_node(&self.db, id).await? {
|
||||
log::info!("redirect: {redirect}");
|
||||
return Err(redirect);
|
||||
}
|
||||
|
||||
// TODO: make it atleast 1 hour
|
||||
if req.locked_nano < 100 {
|
||||
log::error!("locking lessthan 100 nano lps: {}", req.locked_nano);
|
||||
@ -261,6 +272,11 @@ impl BrainVmCli for VmCliServer {
|
||||
info!("Update VM requested via CLI: {req:?}");
|
||||
|
||||
let db_req: db::UpdateVmReq = req.clone().into();
|
||||
|
||||
if let Some(redirect) = db::check_pubsub_node(&self.db, db_req.vm_node.clone()).await? {
|
||||
log::info!("redirect: {redirect}");
|
||||
return Err(redirect);
|
||||
}
|
||||
let id = db_req.id.key().to_string();
|
||||
|
||||
let mut hostname_changed = false;
|
||||
@ -342,6 +358,15 @@ impl BrainVmCli for VmCliServer {
|
||||
|
||||
async fn delete_vm(&self, req: Request<DeleteVmReq>) -> Result<Response<Empty>, Status> {
|
||||
let req = check_sig_from_req(req)?;
|
||||
let vm_node = db::ActiveVm::get_by_uuid(&self.db, &req.uuid)
|
||||
.await?
|
||||
.ok_or(Status::permission_denied("Unauthorized"))?
|
||||
.vm_node;
|
||||
|
||||
if let Some(redirect) = db::check_pubsub_node(&self.db, vm_node).await? {
|
||||
log::info!("redirect: {redirect}");
|
||||
return Err(redirect);
|
||||
}
|
||||
match db::ActiveVm::delete(&self.db, &req.admin_pubkey, &req.uuid).await {
|
||||
Ok(()) => Ok(Response::new(Empty {})),
|
||||
Err(db::Error::AccessDenied) => Err(Status::permission_denied("Unauthorized")),
|
||||
|
@ -1,3 +1,5 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
pub mod constants;
|
||||
pub mod db;
|
||||
pub mod grpc;
|
||||
|
@ -1,3 +1,5 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// TODO: delete this file after migration0 gets executed
|
||||
|
||||
use chrono::Utc;
|
||||
|
@ -1,2 +1,6 @@
|
||||
<!--
|
||||
SPDX-License-Identifier: Apache-2.0
|
||||
-->
|
||||
|
||||
This is actually SurrealQL (`.surql`), but the files have the `.sql`
|
||||
extension to enable syntax coloring.
|
||||
|
@ -1,5 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
source /etc/detee/brain/config.ini
|
||||
|
||||
surreal import \
|
||||
|
@ -1,3 +1,5 @@
|
||||
-- SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
DEFINE FUNCTION OVERWRITE fn::vm_price_per_minute(
|
||||
$vm_id: record
|
||||
) {
|
||||
|
@ -1,3 +1,5 @@
|
||||
-- SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
DEFINE TABLE account SCHEMAFULL;
|
||||
DEFINE FIELD balance ON TABLE account TYPE int DEFAULT 0;
|
||||
DEFINE FIELD tmp_locked ON TABLE account TYPE int DEFAULT 0;
|
||||
@ -6,6 +8,7 @@ DEFINE FIELD email ON TABLE account TYPE string DEFAULT "";
|
||||
|
||||
DEFINE TABLE vm_node SCHEMAFULL;
|
||||
DEFINE FIELD operator ON TABLE vm_node TYPE record<account>;
|
||||
DEFINE FIELD pub_sub_node ON TABLE vm_node TYPE string default "127.0.0.1:31337";
|
||||
DEFINE FIELD country ON TABLE vm_node TYPE string;
|
||||
DEFINE FIELD region ON TABLE vm_node TYPE string;
|
||||
DEFINE FIELD city ON TABLE vm_node TYPE string;
|
||||
@ -80,6 +83,7 @@ DEFINE FIELD price_per_unit ON TABLE deleted_vm TYPE int;
|
||||
|
||||
DEFINE TABLE app_node SCHEMAFULL;
|
||||
DEFINE FIELD operator ON TABLE app_node TYPE record<account>;
|
||||
DEFINE FIELD pub_sub_node ON TABLE app_node TYPE string default "127.0.0.1:31337";
|
||||
DEFINE FIELD country ON TABLE app_node TYPE string;
|
||||
DEFINE FIELD region ON TABLE app_node TYPE string;
|
||||
DEFINE FIELD city ON TABLE app_node TYPE string;
|
||||
|
@ -1,3 +1,5 @@
|
||||
-- SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
INSERT {
|
||||
id: vm_node:online_node,
|
||||
avail_ipv4: 0,
|
||||
|
@ -1,4 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
cd -- "$( dirname -- "${BASH_SOURCE[0]}" )"
|
||||
import="docker run -i --rm --net=host \
|
||||
--volume "$(pwd)/../:/opt/scripts/" \
|
||||
|
@ -1,3 +1,5 @@
|
||||
-- SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
if (select balance from account:operator1)[0].balance != 15_000_000_000 {
|
||||
throw("Operator 1 did't get paid for serving a VM.")
|
||||
};
|
||||
|
@ -1,3 +1,5 @@
|
||||
-- SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
FOR $contract IN (select * from active_vm fetch out) {
|
||||
LET $operator = (select * from $contract.out.operator)[0];
|
||||
LET $node_is_online = $contract.out.connected_at > $contract.out.disconnected_at;
|
||||
|
@ -1,3 +1,5 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use anyhow::Result;
|
||||
use detee_shared::app_proto::{
|
||||
brain_app_cli_client::BrainAppCliClient, AppResource, NewAppReq, NewAppRes,
|
||||
|
@ -1,3 +1,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use super::test_utils::Key;
|
||||
use crate::common::test_utils::{generate_random_public_ip, get_ip_info};
|
||||
use anyhow::Result;
|
||||
use detee_shared::app_proto::brain_app_daemon_client::BrainAppDaemonClient;
|
||||
use detee_shared::app_proto::{self, NewAppRes, RegisterAppNodeReq};
|
||||
@ -7,8 +11,6 @@ use tokio::sync::mpsc;
|
||||
use tokio_stream::wrappers::ReceiverStream;
|
||||
use tonic::transport::Channel;
|
||||
|
||||
use super::test_utils::Key;
|
||||
|
||||
pub async fn mock_app_daemon(
|
||||
brain_channel: &Channel,
|
||||
daemon_error: Option<String>,
|
||||
@ -45,13 +47,16 @@ pub async fn register_app_node(
|
||||
log::info!("Registering app_node: {}", key.pubkey);
|
||||
let node_pubkey = key.pubkey.clone();
|
||||
|
||||
let ip = generate_random_public_ip().to_string();
|
||||
let ip_info = get_ip_info(&ip).await?;
|
||||
|
||||
let req = RegisterAppNodeReq {
|
||||
node_pubkey,
|
||||
operator_wallet: operator_wallet.to_string(),
|
||||
main_ip: String::from("185.243.218.213"),
|
||||
city: String::from("Oslo"),
|
||||
country: String::from("Norway"),
|
||||
region: String::from("EU"),
|
||||
main_ip: ip_info.ip,
|
||||
city: ip_info.city,
|
||||
country: ip_info.country,
|
||||
region: ip_info.region,
|
||||
price: 1200,
|
||||
};
|
||||
|
||||
@ -134,7 +139,7 @@ pub async fn daemon_engine(
|
||||
tx.send(res).await?;
|
||||
}
|
||||
Some(app_proto::brain_message_app::Msg::DeleteAppReq(del_app_req)) => {
|
||||
println!("MOCK_APP_DAEMON:: delete app request for {}", del_app_req.uuid);
|
||||
println!("MOCK_APP_DAEMON::delete app request for {}", del_app_req.uuid);
|
||||
}
|
||||
None => todo!(),
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub mod prepare_test_env;
|
||||
#[allow(dead_code)]
|
||||
|
@ -1,3 +1,5 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use anyhow::Result;
|
||||
use detee_shared::app_proto::brain_app_cli_server::BrainAppCliServer;
|
||||
use detee_shared::app_proto::brain_app_daemon_server::BrainAppDaemonServer;
|
||||
@ -6,7 +8,6 @@ use detee_shared::vm_proto::brain_vm_cli_server::BrainVmCliServer;
|
||||
use detee_shared::vm_proto::brain_vm_daemon_server::BrainVmDaemonServer;
|
||||
use dotenv::dotenv;
|
||||
use hyper_util::rt::TokioIo;
|
||||
use std::net::SocketAddr;
|
||||
use std::sync::Arc;
|
||||
use surreal_brain::constants::DB_SCHEMA_FILES;
|
||||
use surreal_brain::grpc::app::{AppCliServer, AppDaemonServer};
|
||||
@ -15,9 +16,8 @@ use surreal_brain::grpc::vm::{VmCliServer, VmDaemonServer};
|
||||
use surrealdb::engine::remote::ws::Client;
|
||||
use surrealdb::Surreal;
|
||||
use tokio::io::DuplexStream;
|
||||
use tokio::net::TcpListener;
|
||||
use tokio::sync::OnceCell;
|
||||
use tonic::transport::{Channel, Endpoint, Server, Uri};
|
||||
use tonic::transport::{Channel, Endpoint, Uri};
|
||||
use tower::service_fn;
|
||||
|
||||
pub static DB_STATE: OnceCell<Result<()>> = OnceCell::const_new();
|
||||
@ -29,7 +29,7 @@ pub async fn prepare_test_db() -> Result<Surreal<Client>> {
|
||||
let db_user = std::env::var("DB_USER").expect("DB_USER not set in .env");
|
||||
let db_pass = std::env::var("DB_PASS").expect("DB_PASS not set in .env");
|
||||
let db_ns = "test_brain";
|
||||
let db_name = "test_migration_db";
|
||||
let db_name = "test_brain_db";
|
||||
|
||||
let db = surreal_brain::db::db_connection(&db_url, &db_user, &db_pass, db_ns, db_name).await?;
|
||||
DB_STATE
|
||||
@ -49,37 +49,6 @@ pub async fn prepare_test_db() -> Result<Surreal<Client>> {
|
||||
Ok(db)
|
||||
}
|
||||
|
||||
pub async fn run_service_in_background() -> Result<SocketAddr> {
|
||||
dotenv().ok();
|
||||
let listener = TcpListener::bind("127.0.0.1:0").await?;
|
||||
let addr = listener.local_addr()?;
|
||||
|
||||
let db_url = std::env::var("DB_URL").expect("DB_URL not set in .env");
|
||||
let db_user = std::env::var("DB_USER").expect("DB_USER not set in .env");
|
||||
let db_pass = std::env::var("DB_PASS").expect("DB_PASS not set in .env");
|
||||
let db_ns = "test_brain";
|
||||
let db_name = "test_migration_db";
|
||||
|
||||
tokio::spawn(async move {
|
||||
let db =
|
||||
surreal_brain::db::db_connection(&db_url, &db_user, &db_pass, db_ns, db_name).await?;
|
||||
let db_arc = Arc::new(db);
|
||||
|
||||
Server::builder()
|
||||
.add_service(BrainGeneralCliServer::new(GeneralCliServer::new(db_arc.clone())))
|
||||
.add_service(BrainVmCliServer::new(VmCliServer::new(db_arc.clone())))
|
||||
.add_service(BrainVmDaemonServer::new(VmDaemonServer::new(db_arc.clone())))
|
||||
.serve_with_incoming(tokio_stream::wrappers::TcpListenerStream::new(listener))
|
||||
.await?;
|
||||
|
||||
Ok::<(), anyhow::Error>(())
|
||||
});
|
||||
|
||||
tokio::time::sleep(tokio::time::Duration::from_millis(300)).await;
|
||||
|
||||
Ok(addr)
|
||||
}
|
||||
|
||||
pub async fn run_service_for_stream_server() -> DuplexStream {
|
||||
dotenv().ok();
|
||||
let (client, server) = tokio::io::duplex(1024);
|
||||
@ -88,7 +57,7 @@ pub async fn run_service_for_stream_server() -> DuplexStream {
|
||||
let db_user = std::env::var("DB_USER").expect("DB_USER not set in .env");
|
||||
let db_pass = std::env::var("DB_PASS").expect("DB_PASS not set in .env");
|
||||
let db_ns = "test_brain";
|
||||
let db_name = "test_migration_db";
|
||||
let db_name = "test_brain_db";
|
||||
|
||||
tokio::spawn(async move {
|
||||
let db =
|
||||
|
@ -1,3 +1,5 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use anyhow::Result;
|
||||
use detee_shared::app_proto as sgx_proto;
|
||||
use detee_shared::general_proto::brain_general_cli_client::BrainGeneralCliClient;
|
||||
@ -5,6 +7,8 @@ use detee_shared::general_proto::AirdropReq;
|
||||
use detee_shared::vm_proto as snp_proto;
|
||||
use ed25519_dalek::{Signer, SigningKey};
|
||||
use itertools::Itertools;
|
||||
use rand::Rng;
|
||||
use std::net::Ipv4Addr;
|
||||
use std::sync::OnceLock;
|
||||
use surreal_brain::constants::TOKEN_DECIMAL;
|
||||
use tonic::metadata::AsciiMetadataValue;
|
||||
@ -98,3 +102,35 @@ pub async fn airdrop(brain_channel: &Channel, wallet: &str, amount: u64) -> Resu
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn get_ip_info(ip: &str) -> anyhow::Result<IPInfo> {
|
||||
let body = reqwest::get(format!("https://ipinfo.io/{ip}")).await?.text().await?;
|
||||
log::info!("Got the following data from ipinfo.io: {body}");
|
||||
Ok(serde_json::de::from_str(&body)?)
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize, Clone, Debug)]
|
||||
pub struct IPInfo {
|
||||
pub country: String,
|
||||
pub region: String,
|
||||
pub city: String,
|
||||
pub ip: String,
|
||||
}
|
||||
|
||||
pub fn generate_random_public_ip() -> Ipv4Addr {
|
||||
let mut rng = rand::thread_rng();
|
||||
loop {
|
||||
let ip = Ipv4Addr::from(rng.gen::<u32>());
|
||||
if !ip.is_private()
|
||||
&& !ip.is_loopback()
|
||||
&& !ip.is_link_local()
|
||||
&& !ip.is_broadcast()
|
||||
&& !ip.is_documentation()
|
||||
&& !ip.is_unspecified()
|
||||
&& !ip.is_multicast()
|
||||
&& ip.octets()[0] < 240
|
||||
{
|
||||
return ip;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use super::test_utils::Key;
|
||||
use anyhow::{anyhow, Result};
|
||||
use detee_shared::app_proto;
|
||||
|
@ -1,4 +1,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use super::test_utils::Key;
|
||||
use crate::common::test_utils::{generate_random_public_ip, get_ip_info};
|
||||
use anyhow::Result;
|
||||
use detee_shared::vm_proto;
|
||||
use detee_shared::vm_proto::brain_vm_daemon_client::BrainVmDaemonClient;
|
||||
@ -44,13 +47,16 @@ pub async fn register_vm_node(
|
||||
log::info!("Registering vm_node: {}", key.pubkey);
|
||||
let node_pubkey = key.pubkey.clone();
|
||||
|
||||
let ip = generate_random_public_ip().to_string();
|
||||
let ip_info = get_ip_info(&ip).await?;
|
||||
|
||||
let req = RegisterVmNodeReq {
|
||||
node_pubkey,
|
||||
operator_wallet: operator_wallet.to_string(),
|
||||
main_ip: String::from("185.243.218.213"),
|
||||
city: String::from("Oslo"),
|
||||
country: String::from("Norway"),
|
||||
region: String::from("EU"),
|
||||
main_ip: ip_info.ip,
|
||||
city: ip_info.city,
|
||||
country: ip_info.country,
|
||||
region: ip_info.region,
|
||||
price: 1200,
|
||||
};
|
||||
|
||||
@ -137,7 +143,7 @@ pub async fn daemon_engine(
|
||||
todo!()
|
||||
}
|
||||
Some(vm_proto::brain_vm_message::Msg::DeleteVm(del_vm_req)) => {
|
||||
println!("MOCK_VM_DAEMON:: delete vm request for {}", del_vm_req.uuid);
|
||||
println!("MOCK_VM_DAEMON::delete vm request for {}", del_vm_req.uuid);
|
||||
}
|
||||
None => todo!(),
|
||||
}
|
||||
|
35
tests/db_tx_new_app_test.rs
Normal file
35
tests/db_tx_new_app_test.rs
Normal file
@ -0,0 +1,35 @@
|
||||
use common::prepare_test_env::prepare_test_db;
|
||||
use detee_shared::app_proto::{AppResource, NewAppReq};
|
||||
use surreal_brain::db::prelude as db;
|
||||
|
||||
mod common;
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_new_app_db_tx() {
|
||||
let db = prepare_test_db().await.unwrap();
|
||||
|
||||
let req = NewAppReq {
|
||||
package_url: "https://registry.detee.ltd/sgx/packages/actix-app-info_package_2025-04-16_21-59-38.tar.gz".to_string(),
|
||||
node_pubkey: "AH3SpV6ZjXMGSSe6xGH2ekUZxyUhnesAFz4LjX7PnvVn".to_string(),
|
||||
resource: Some(
|
||||
AppResource {
|
||||
memory_mb: 1500,
|
||||
disk_size_gb: 2,
|
||||
vcpus: 1,
|
||||
ports: vec![ 8080 ],
|
||||
},
|
||||
),
|
||||
uuid: "".to_string(),
|
||||
admin_pubkey: "H21Shi4iE7vgfjWEQNvzmpmBMJSaiZ17PYUcdNoAoKNc".to_string(),
|
||||
price_per_unit: 200000,
|
||||
locked_nano: 152400000,
|
||||
hratls_pubkey: "7E0F887AA6BB9104EEC1066F454D4C2D9063D676715F55F919D3FBCEDC63240B".to_string(),
|
||||
public_package_mr_enclave: Some(
|
||||
vec![ 128, 0, 97, 103, 165, 103, 68, 203, 240, 145, 153, 254, 34, 129, 75, 140, 8, 186, 63, 226, 144, 129, 201, 187, 175, 66, 80, 1, 151, 114, 183, 159, ],
|
||||
),
|
||||
app_name: "lively-ferret".to_string(),
|
||||
};
|
||||
|
||||
let db_req: db::NewAppReq = req.into();
|
||||
db_req.submit(&db).await.unwrap();
|
||||
}
|
@ -1,13 +1,20 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use common::app_daemon_utils::mock_app_daemon;
|
||||
use common::prepare_test_env::{prepare_test_db, run_service_for_stream};
|
||||
use common::test_utils::{airdrop, Key};
|
||||
use detee_shared::app_proto::brain_app_cli_client::BrainAppCliClient;
|
||||
use detee_shared::app_proto::{self, DelAppReq};
|
||||
use detee_shared::app_proto::brain_app_daemon_client::BrainAppDaemonClient;
|
||||
use detee_shared::app_proto::{self, AppNodeFilters, DelAppReq};
|
||||
use std::vec;
|
||||
use surreal_brain::constants::{ACCOUNT, ACTIVE_APP, DELETED_APP, NEW_APP_REQ, TOKEN_DECIMAL};
|
||||
use surreal_brain::constants::{
|
||||
ACCOUNT, ACTIVE_APP, APP_NODE, DELETED_APP, NEW_APP_REQ, TOKEN_DECIMAL,
|
||||
};
|
||||
use surreal_brain::db::app::AppNode;
|
||||
use surreal_brain::db::prelude as db;
|
||||
|
||||
use crate::common::app_cli_utils::create_new_app;
|
||||
use crate::common::app_daemon_utils::register_app_node;
|
||||
|
||||
mod common;
|
||||
|
||||
@ -95,13 +102,16 @@ async fn test_app_creation() {
|
||||
async fn test_timeout_app_creation() {
|
||||
let _ = prepare_test_db().await.unwrap();
|
||||
let brain_channel = run_service_for_stream().await.unwrap();
|
||||
let daemon_key = Key::new().pubkey.clone();
|
||||
let daemon_key = Key::new();
|
||||
|
||||
let key = Key::new();
|
||||
|
||||
let mut daemon_client = BrainAppDaemonClient::new(brain_channel.clone());
|
||||
register_app_node(&mut daemon_client, &daemon_key, &Key::new().pubkey).await.unwrap();
|
||||
|
||||
let new_app_req = app_proto::NewAppReq {
|
||||
admin_pubkey: key.pubkey.clone(),
|
||||
node_pubkey: daemon_key.clone(),
|
||||
node_pubkey: daemon_key.pubkey.clone(),
|
||||
price_per_unit: 1200,
|
||||
resource: Some(app_proto::AppResource { ports: vec![8080, 8081], ..Default::default() }),
|
||||
locked_nano: 100,
|
||||
@ -179,4 +189,38 @@ async fn test_app_deletion() {
|
||||
assert!(deleted_app.is_some());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_get_one_app_node() {
|
||||
let db = prepare_test_db().await.unwrap();
|
||||
let brain_channel = run_service_for_stream().await.unwrap();
|
||||
|
||||
let mut client_app_cli = BrainAppCliClient::new(brain_channel.clone());
|
||||
let key = Key::new();
|
||||
|
||||
let mut req = AppNodeFilters { ..Default::default() };
|
||||
|
||||
let mock_app_node = client_app_cli
|
||||
.get_one_app_node(key.sign_request(req.clone()).unwrap())
|
||||
.await
|
||||
.unwrap()
|
||||
.into_inner();
|
||||
|
||||
assert_eq!(
|
||||
mock_app_node.node_pubkey,
|
||||
"BiqoPUEoAxYxMRXUmyofoS9H1TBQgQqvLJ6MbWh88AQg".to_string()
|
||||
);
|
||||
|
||||
let node_pubkey = mock_app_daemon(&brain_channel, None).await.unwrap();
|
||||
|
||||
let new_node_ip =
|
||||
db.select::<Option<AppNode>>((APP_NODE, node_pubkey.clone())).await.unwrap().unwrap().ip;
|
||||
|
||||
req.ip = new_node_ip;
|
||||
|
||||
let new_app_node =
|
||||
client_app_cli.get_one_app_node(key.sign_request(req).unwrap()).await.unwrap().into_inner();
|
||||
|
||||
assert_eq!(new_app_node.node_pubkey, node_pubkey);
|
||||
}
|
||||
|
||||
// TODO: test register app node, delete app contract while node offline, kick, etc..
|
||||
|
139
tests/grpc_app_daemon_test.rs
Normal file
139
tests/grpc_app_daemon_test.rs
Normal file
@ -0,0 +1,139 @@
|
||||
use common::app_daemon_utils::{mock_app_daemon, register_app_node};
|
||||
use common::prepare_test_env::{prepare_test_db, run_service_for_stream};
|
||||
use common::test_utils::{airdrop, Key};
|
||||
use detee_shared::app_proto::brain_app_cli_client::BrainAppCliClient;
|
||||
use detee_shared::app_proto::brain_app_daemon_client::BrainAppDaemonClient;
|
||||
use detee_shared::app_proto::{self, AppNodeResources};
|
||||
use surreal_brain::constants::APP_NODE;
|
||||
use surreal_brain::db::app::AppNode;
|
||||
use surreal_brain::db::prelude as db;
|
||||
use tokio_stream::wrappers::ReceiverStream;
|
||||
|
||||
mod common;
|
||||
|
||||
// TODO: test app registration and resource handling
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_reg_app_node() {
|
||||
let db = prepare_test_db().await.unwrap();
|
||||
|
||||
let channel = run_service_for_stream().await.unwrap();
|
||||
let mut client = BrainAppDaemonClient::new(channel);
|
||||
|
||||
let node_key = Key::new();
|
||||
|
||||
let del_app_req = register_app_node(&mut client, &node_key, &Key::new().pubkey).await.unwrap();
|
||||
|
||||
assert!(del_app_req.is_empty());
|
||||
|
||||
let app_node: Option<db::AppNode> = db.select((APP_NODE, node_key.pubkey)).await.unwrap();
|
||||
assert!(app_node.is_some());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_brain_message() {
|
||||
env_logger::builder().filter_level(log::LevelFilter::Error).init();
|
||||
let _ = prepare_test_db().await.unwrap();
|
||||
|
||||
let brain_channel = run_service_for_stream().await.unwrap();
|
||||
let daemon_key = mock_app_daemon(&brain_channel, None).await.unwrap();
|
||||
let mut cli_client = BrainAppCliClient::new(brain_channel.clone());
|
||||
|
||||
let cli_key = Key::new();
|
||||
|
||||
let req = app_proto::NewAppReq {
|
||||
admin_pubkey: cli_key.pubkey.clone(),
|
||||
node_pubkey: daemon_key,
|
||||
price_per_unit: 1200,
|
||||
// extra_ports: vec![8080, 8081],
|
||||
locked_nano: 100,
|
||||
..Default::default()
|
||||
};
|
||||
airdrop(&brain_channel, &cli_key.pubkey, 10).await.unwrap();
|
||||
let new_app_resp =
|
||||
cli_client.new_app(cli_key.sign_request(req).unwrap()).await.unwrap().into_inner();
|
||||
|
||||
assert!(new_app_resp.error.is_empty());
|
||||
assert!(new_app_resp.uuid.len() == 40);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_app_daemon_resource_msg() {
|
||||
/*
|
||||
env_logger::builder()
|
||||
.filter_level(log::LevelFilter::Trace)
|
||||
.filter_module("tungstenite", log::LevelFilter::Debug)
|
||||
.filter_module("tokio_tungstenite", log::LevelFilter::Debug)
|
||||
.init();
|
||||
*/
|
||||
|
||||
let db = prepare_test_db().await.unwrap();
|
||||
|
||||
let brain_channel = run_service_for_stream().await.unwrap();
|
||||
let mut daemon_client = BrainAppDaemonClient::new(brain_channel);
|
||||
|
||||
let daemon_key = Key::new();
|
||||
|
||||
register_app_node(&mut daemon_client, &daemon_key, &Key::new().pubkey).await.unwrap();
|
||||
|
||||
let (tx, rx) = tokio::sync::mpsc::channel(32);
|
||||
|
||||
let tx_01 = tx.clone();
|
||||
let daemon_key_01 = daemon_key.clone();
|
||||
|
||||
tokio::spawn(async move {
|
||||
tx_01
|
||||
.send(app_proto::DaemonMessageApp {
|
||||
msg: Some(app_proto::daemon_message_app::Msg::Auth(
|
||||
daemon_key_01.clone().sign_stream_auth_app(vec![]).unwrap(),
|
||||
)),
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let rx_stream = ReceiverStream::new(rx);
|
||||
daemon_client.daemon_messages(rx_stream).await.unwrap();
|
||||
});
|
||||
|
||||
let tx_02 = tx.clone();
|
||||
let daemon_pubkey = daemon_key.clone().pubkey;
|
||||
|
||||
let req_data = AppNodeResources {
|
||||
node_pubkey: daemon_pubkey,
|
||||
avail_no_of_port: 5,
|
||||
avail_vcpus: 4,
|
||||
avail_memory_mb: 8192,
|
||||
avail_storage_gb: 100,
|
||||
max_ports_per_app: 5,
|
||||
};
|
||||
|
||||
let req_data_copy = req_data.clone();
|
||||
|
||||
tokio::spawn(async move {
|
||||
tx_02
|
||||
.send(app_proto::DaemonMessageApp {
|
||||
msg: Some(app_proto::daemon_message_app::Msg::AppNodeResources(req_data_copy)),
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
});
|
||||
|
||||
tokio::time::sleep(tokio::time::Duration::from_secs(1)).await;
|
||||
|
||||
let app_node_opt: Option<AppNode> = db.select((APP_NODE, daemon_key.pubkey)).await.unwrap();
|
||||
assert!(app_node_opt.is_some());
|
||||
let db::AppNode {
|
||||
avail_mem_mb,
|
||||
avail_vcpus,
|
||||
avail_storage_gbs,
|
||||
avail_ports,
|
||||
max_ports_per_app,
|
||||
..
|
||||
} = app_node_opt.unwrap();
|
||||
|
||||
assert_eq!(avail_mem_mb, req_data.avail_memory_mb);
|
||||
assert_eq!(avail_vcpus, req_data.avail_vcpus);
|
||||
assert_eq!(avail_storage_gbs, req_data.avail_storage_gb);
|
||||
assert_eq!(avail_ports, req_data.avail_no_of_port);
|
||||
assert_eq!(max_ports_per_app, req_data.max_ports_per_app);
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
use common::prepare_test_env::{
|
||||
prepare_test_db, run_service_for_stream, run_service_in_background,
|
||||
};
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use common::prepare_test_env::{prepare_test_db, run_service_for_stream};
|
||||
use common::test_utils::{admin_keys, airdrop, Key};
|
||||
use common::vm_cli_utils::{
|
||||
create_new_vm, list_accounts, list_all_app_contracts, list_all_vm_contracts, register_operator,
|
||||
@ -20,11 +20,17 @@ mod common;
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_general_balance() {
|
||||
// env_logger::builder().filter_level(log::LevelFilter::Trace).init();
|
||||
/*
|
||||
env_logger::builder()
|
||||
.filter_level(log::LevelFilter::Info)
|
||||
.filter_module("tungstenite", log::LevelFilter::Debug)
|
||||
.filter_module("tokio_tungstenite", log::LevelFilter::Debug)
|
||||
.init();
|
||||
*/
|
||||
prepare_test_db().await.unwrap();
|
||||
|
||||
let addr = run_service_in_background().await.unwrap();
|
||||
let mut client = BrainGeneralCliClient::connect(format!("http://{}", addr)).await.unwrap();
|
||||
let channel = run_service_for_stream().await.unwrap();
|
||||
let mut client = BrainGeneralCliClient::new(channel);
|
||||
|
||||
let key = Key::new();
|
||||
let pubkey = key.pubkey.clone();
|
||||
@ -45,8 +51,8 @@ async fn test_general_airdrop() {
|
||||
|
||||
let airdrop_amount = 10;
|
||||
|
||||
let addr = run_service_in_background().await.unwrap();
|
||||
let mut client = BrainGeneralCliClient::connect(format!("http://{}", addr)).await.unwrap();
|
||||
let channel = run_service_for_stream().await.unwrap();
|
||||
let mut client = BrainGeneralCliClient::new(channel);
|
||||
|
||||
let admin_keys = admin_keys();
|
||||
|
||||
|
95
tests/grpc_redirect_test.rs
Normal file
95
tests/grpc_redirect_test.rs
Normal file
@ -0,0 +1,95 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use common::prepare_test_env::{prepare_test_db, run_service_for_stream};
|
||||
use common::test_utils::{airdrop, Key};
|
||||
use common::vm_daemon_utils::register_vm_node;
|
||||
use detee_shared::app_proto;
|
||||
use detee_shared::app_proto::brain_app_cli_client::BrainAppCliClient;
|
||||
use detee_shared::app_proto::brain_app_daemon_client::BrainAppDaemonClient;
|
||||
use detee_shared::vm_proto;
|
||||
use detee_shared::vm_proto::brain_vm_cli_client::BrainVmCliClient;
|
||||
use detee_shared::vm_proto::brain_vm_daemon_client::BrainVmDaemonClient;
|
||||
|
||||
use crate::common::app_daemon_utils::register_app_node;
|
||||
|
||||
mod common;
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_vm_pub_sub_redirect() {
|
||||
let _ = prepare_test_db().await.unwrap();
|
||||
|
||||
let brain_channel = run_service_for_stream().await.unwrap();
|
||||
let mut vm_daemon_client = BrainVmDaemonClient::new(brain_channel.clone());
|
||||
|
||||
let node_key = Key::new();
|
||||
|
||||
let pubsub_brain_endpoint = "192.168.1.1:31337";
|
||||
std::env::set_var("BRAIN_PUBLIC_ENDPOINT", pubsub_brain_endpoint);
|
||||
register_vm_node(&mut vm_daemon_client, &node_key, &Key::new().pubkey).await.unwrap();
|
||||
std::env::set_var("BRAIN_PUBLIC_ENDPOINT", "127.0.0.1:31337");
|
||||
|
||||
let client_key = Key::new();
|
||||
|
||||
let new_vm_req = vm_proto::NewVmReq {
|
||||
admin_pubkey: client_key.pubkey.clone(),
|
||||
node_pubkey: node_key.pubkey.clone(),
|
||||
price_per_unit: 1200,
|
||||
extra_ports: vec![8080, 8081],
|
||||
locked_nano: 100,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
airdrop(&brain_channel, &client_key.pubkey, 10).await.unwrap();
|
||||
|
||||
std::env::set_var("BRAIN_PUBLIC_ENDPOINT", "10.0.0.1:31337");
|
||||
let mut client_vm_cli = BrainVmCliClient::new(brain_channel.clone());
|
||||
let redirect =
|
||||
client_vm_cli.new_vm(client_key.sign_request(new_vm_req).unwrap()).await.err().unwrap();
|
||||
std::env::set_var("BRAIN_PUBLIC_ENDPOINT", "127.0.0.1:31337");
|
||||
assert_eq!(redirect.code(), tonic::Code::Unavailable);
|
||||
let redirect_url =
|
||||
redirect.metadata().get("location").and_then(|v| v.to_str().ok()).unwrap_or_default();
|
||||
assert_eq!(redirect_url, pubsub_brain_endpoint);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_app_pub_sub_redirect() {
|
||||
let _ = prepare_test_db().await.unwrap();
|
||||
|
||||
let brain_channel = run_service_for_stream().await.unwrap();
|
||||
let mut app_daemon_client = BrainAppDaemonClient::new(brain_channel.clone());
|
||||
|
||||
let node_key = Key::new();
|
||||
|
||||
let pubsub_brain_endpoint = "192.168.1.1:31337";
|
||||
std::env::set_var("BRAIN_PUBLIC_ENDPOINT", pubsub_brain_endpoint);
|
||||
register_app_node(&mut app_daemon_client, &node_key, &Key::new().pubkey).await.unwrap();
|
||||
std::env::set_var("BRAIN_PUBLIC_ENDPOINT", "127.0.0.1:31337");
|
||||
|
||||
let client_key = Key::new();
|
||||
|
||||
let new_app_req = app_proto::NewAppReq {
|
||||
admin_pubkey: client_key.pubkey.clone(),
|
||||
node_pubkey: node_key.pubkey.clone(),
|
||||
price_per_unit: 1200,
|
||||
resource: Some(app_proto::AppResource { ports: vec![8080, 8081], ..Default::default() }),
|
||||
locked_nano: 100,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
airdrop(&brain_channel, &client_key.pubkey, 10).await.unwrap();
|
||||
|
||||
std::env::set_var("BRAIN_PUBLIC_ENDPOINT", "10.0.0.1:31337");
|
||||
|
||||
let mut client_app_cli = BrainAppCliClient::new(brain_channel.clone());
|
||||
let redirect = client_app_cli
|
||||
.new_app(client_key.sign_request(new_app_req.clone()).unwrap())
|
||||
.await
|
||||
.err()
|
||||
.unwrap();
|
||||
std::env::set_var("BRAIN_PUBLIC_ENDPOINT", "127.0.0.1:31337");
|
||||
assert_eq!(redirect.code(), tonic::Code::Unavailable);
|
||||
let redirect_url =
|
||||
redirect.metadata().get("location").and_then(|v| v.to_str().ok()).unwrap_or_default();
|
||||
assert_eq!(redirect_url, pubsub_brain_endpoint);
|
||||
}
|
@ -1,14 +1,19 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use common::prepare_test_env::{prepare_test_db, run_service_for_stream};
|
||||
use common::test_utils::{airdrop, Key};
|
||||
use common::vm_cli_utils::{create_new_vm, user_list_vm_contracts};
|
||||
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_daemon_client::BrainVmDaemonClient;
|
||||
use detee_shared::vm_proto::{self, DeleteVmReq};
|
||||
use detee_shared::vm_proto::{ExtendVmReq, ListVmContractsReq, NewVmReq};
|
||||
use detee_shared::vm_proto::{
|
||||
DeleteVmReq, ExtendVmReq, ListVmContractsReq, NewVmReq, VmNodeFilters,
|
||||
};
|
||||
use futures::StreamExt;
|
||||
use std::vec;
|
||||
use surreal_brain::constants::{ACCOUNT, ACTIVE_VM, DELETED_VM, NEW_VM_REQ, TOKEN_DECIMAL};
|
||||
use surreal_brain::constants::{
|
||||
ACCOUNT, ACTIVE_VM, DELETED_VM, NEW_VM_REQ, TOKEN_DECIMAL, VM_NODE,
|
||||
};
|
||||
use surreal_brain::db::prelude as db;
|
||||
|
||||
mod common;
|
||||
@ -300,4 +305,42 @@ async fn test_extend_vm() {
|
||||
assert_eq!(acc.balance, expected_bal_02);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_get_one_vm_node() {
|
||||
let db = prepare_test_db().await.unwrap();
|
||||
let brain_channel = run_service_for_stream().await.unwrap();
|
||||
|
||||
let mut client_vm_cli = BrainVmCliClient::new(brain_channel.clone());
|
||||
let key = Key::new();
|
||||
|
||||
let mut req = VmNodeFilters::default();
|
||||
|
||||
let mock_vm_node = client_vm_cli
|
||||
.get_one_vm_node(key.sign_request(req.clone()).unwrap())
|
||||
.await
|
||||
.unwrap()
|
||||
.into_inner();
|
||||
|
||||
let mock_data_vm_nodes = [
|
||||
"2Uf5pxhxKTUm6gRMnpbJHYDuyA6BWUfFsdmPyWfbMV1f",
|
||||
"3zRxiGRnf46vd3zAEmpaYBJocTV9oJB6yXf5GZFR1Sq4",
|
||||
"7Xw3RxbP5pvfjZ8U6yA3HHVSS9YXjKH5Vkas3JRbQYd9",
|
||||
"DgkbsrwttkZXvzxY5kDwQQoDd79GLmZ5tc7fYJUFkQQb",
|
||||
"Du3UfPSUUZmA5thQmc9Vrxdy7UimpygcpDsQNnwRQPtu",
|
||||
"HiyMp21zaBVbRCjDsD5hEjQnHeHv4e1gpUR6pVfHTKqv",
|
||||
];
|
||||
assert!(mock_data_vm_nodes.contains(&mock_vm_node.node_pubkey.as_str()));
|
||||
|
||||
let node_pubkey = mock_vm_daemon(&brain_channel, None).await.unwrap();
|
||||
let new_node_ip =
|
||||
db.select::<Option<db::VmNode>>((VM_NODE, node_pubkey.clone())).await.unwrap().unwrap().ip;
|
||||
|
||||
req.ip = new_node_ip;
|
||||
|
||||
let new_app_node =
|
||||
client_vm_cli.get_one_vm_node(key.sign_request(req).unwrap()).await.unwrap().into_inner();
|
||||
|
||||
assert_eq!(new_app_node.node_pubkey, node_pubkey);
|
||||
}
|
||||
|
||||
// TODO: test register vm node, delete vm contract while node offline, kick, etc..
|
||||
|
@ -1,11 +1,14 @@
|
||||
use common::prepare_test_env::{
|
||||
prepare_test_db, run_service_for_stream, run_service_in_background,
|
||||
};
|
||||
use common::test_utils::{airdrop, Key};
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::common::test_utils::{airdrop, Key};
|
||||
use common::prepare_test_env::{prepare_test_db, run_service_for_stream};
|
||||
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_daemon_client::BrainVmDaemonClient;
|
||||
use surreal_brain::constants::VM_NODE;
|
||||
use surreal_brain::db::prelude as db;
|
||||
use tokio_stream::wrappers::ReceiverStream;
|
||||
|
||||
mod common;
|
||||
|
||||
@ -13,13 +16,12 @@ mod common;
|
||||
async fn test_reg_vm_node() {
|
||||
prepare_test_db().await.unwrap();
|
||||
|
||||
let addr = run_service_in_background().await.unwrap();
|
||||
let mut client = BrainVmDaemonClient::connect(format!("http://{}", addr)).await.unwrap();
|
||||
let channel = run_service_for_stream().await.unwrap();
|
||||
let mut client = BrainVmDaemonClient::new(channel);
|
||||
|
||||
let vm_contracts =
|
||||
register_vm_node(&mut client, &Key::new(), &Key::new().pubkey).await.unwrap();
|
||||
let del_vm_reqs = register_vm_node(&mut client, &Key::new(), &Key::new().pubkey).await.unwrap();
|
||||
|
||||
assert!(vm_contracts.is_empty())
|
||||
assert!(del_vm_reqs.is_empty())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
@ -50,3 +52,83 @@ async fn test_brain_message() {
|
||||
assert!(new_vm_resp.args.is_some());
|
||||
assert!(new_vm_resp.args.unwrap().exposed_ports.len() == 3);
|
||||
}
|
||||
#[tokio::test]
|
||||
async fn test_vm_daemon_resource_msg() {
|
||||
let db = prepare_test_db().await.unwrap();
|
||||
|
||||
let brain_channel = run_service_for_stream().await.unwrap();
|
||||
let mut daemon_client = BrainVmDaemonClient::new(brain_channel);
|
||||
|
||||
let daemon_key = Key::new();
|
||||
|
||||
register_vm_node(&mut daemon_client, &daemon_key, &Key::new().pubkey).await.unwrap();
|
||||
|
||||
let (tx, rx) = tokio::sync::mpsc::channel(32);
|
||||
|
||||
let tx_01 = tx.clone();
|
||||
let daemon_key_01 = daemon_key.clone();
|
||||
|
||||
tokio::spawn(async move {
|
||||
tx_01
|
||||
.send(vm_proto::VmDaemonMessage {
|
||||
msg: Some(vm_proto::vm_daemon_message::Msg::Auth(
|
||||
daemon_key_01.clone().sign_stream_auth_vm(vec![]).unwrap(),
|
||||
)),
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let rx_stream = ReceiverStream::new(rx);
|
||||
daemon_client.daemon_messages(rx_stream).await.unwrap();
|
||||
});
|
||||
|
||||
let tx_02 = tx.clone();
|
||||
let daemon_pubkey = daemon_key.clone().pubkey;
|
||||
|
||||
let req_data = vm_proto::VmNodeResources {
|
||||
node_pubkey: daemon_pubkey,
|
||||
avail_ports: 5,
|
||||
avail_ipv4: 2,
|
||||
avail_ipv6: 88,
|
||||
avail_vcpus: 4,
|
||||
avail_memory_mb: 8192,
|
||||
avail_storage_gb: 100,
|
||||
max_ports_per_vm: 5,
|
||||
};
|
||||
|
||||
let req_data_copy = req_data.clone();
|
||||
|
||||
tokio::spawn(async move {
|
||||
tx_02
|
||||
.send(vm_proto::VmDaemonMessage {
|
||||
msg: Some(vm_proto::vm_daemon_message::Msg::VmNodeResources(req_data_copy)),
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
});
|
||||
|
||||
tokio::time::sleep(tokio::time::Duration::from_millis(300)).await;
|
||||
|
||||
let vm_node_opt: Option<db::VmNode> = db.select((VM_NODE, daemon_key.pubkey)).await.unwrap();
|
||||
|
||||
assert!(vm_node_opt.is_some());
|
||||
|
||||
let db::VmNode {
|
||||
avail_mem_mb,
|
||||
avail_vcpus,
|
||||
avail_storage_gbs,
|
||||
avail_ports,
|
||||
avail_ipv4,
|
||||
avail_ipv6,
|
||||
max_ports_per_vm,
|
||||
..
|
||||
} = vm_node_opt.unwrap();
|
||||
|
||||
assert_eq!(avail_mem_mb, req_data.avail_memory_mb);
|
||||
assert_eq!(avail_vcpus, req_data.avail_vcpus);
|
||||
assert_eq!(avail_storage_gbs, req_data.avail_storage_gb);
|
||||
assert_eq!(avail_ports, req_data.avail_ports);
|
||||
assert_eq!(avail_ipv4, req_data.avail_ipv4);
|
||||
assert_eq!(avail_ipv6, req_data.avail_ipv6);
|
||||
assert_eq!(max_ports_per_vm, req_data.max_ports_per_vm);
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
accounts:
|
||||
DXXkYSnhP3ijsHYxkedcuMomEyc122WaAbkDX7SaGuUS:
|
||||
balance: 20293420000
|
||||
@ -300,7 +302,7 @@ vm_nodes:
|
||||
max_ports_per_vm: 10
|
||||
price: 24000
|
||||
reports: {}
|
||||
offline_minutes: 0
|
||||
offline_minutes: 1
|
||||
|
||||
vm_contracts:
|
||||
- uuid: 958165e3-dea8-407d-8c42-dd17002ef79c
|
||||
|
Loading…
Reference in New Issue
Block a user