added auth
This commit is contained in:
parent
7dfdf4844e
commit
795da62649
220
Cargo.lock
generated
220
Cargo.lock
generated
@ -209,18 +209,35 @@ version = "0.22.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
|
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "base64ct"
|
||||||
|
version = "1.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "2.6.0"
|
version = "2.6.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
|
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "block-buffer"
|
||||||
|
version = "0.10.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
|
||||||
|
dependencies = [
|
||||||
|
"generic-array",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "brain-mock"
|
name = "brain-mock"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"bs58",
|
||||||
"chrono",
|
"chrono",
|
||||||
"dashmap",
|
"dashmap",
|
||||||
|
"ed25519-dalek",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
"log",
|
"log",
|
||||||
"prost",
|
"prost",
|
||||||
@ -236,6 +253,15 @@ dependencies = [
|
|||||||
"uuid",
|
"uuid",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bs58"
|
||||||
|
version = "0.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4"
|
||||||
|
dependencies = [
|
||||||
|
"tinyvec",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bumpalo"
|
name = "bumpalo"
|
||||||
version = "3.16.0"
|
version = "3.16.0"
|
||||||
@ -289,6 +315,12 @@ version = "1.0.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
|
checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "const-oid"
|
||||||
|
version = "0.9.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "core-foundation"
|
name = "core-foundation"
|
||||||
version = "0.9.4"
|
version = "0.9.4"
|
||||||
@ -305,12 +337,58 @@ version = "0.8.7"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
|
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cpufeatures"
|
||||||
|
version = "0.2.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossbeam-utils"
|
name = "crossbeam-utils"
|
||||||
version = "0.8.21"
|
version = "0.8.21"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
|
checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crypto-common"
|
||||||
|
version = "0.1.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
|
||||||
|
dependencies = [
|
||||||
|
"generic-array",
|
||||||
|
"typenum",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "curve25519-dalek"
|
||||||
|
version = "4.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"cpufeatures",
|
||||||
|
"curve25519-dalek-derive",
|
||||||
|
"digest",
|
||||||
|
"fiat-crypto",
|
||||||
|
"rustc_version",
|
||||||
|
"subtle",
|
||||||
|
"zeroize",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "curve25519-dalek-derive"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dashmap"
|
name = "dashmap"
|
||||||
version = "6.1.0"
|
version = "6.1.0"
|
||||||
@ -325,6 +403,26 @@ dependencies = [
|
|||||||
"parking_lot_core",
|
"parking_lot_core",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "der"
|
||||||
|
version = "0.7.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0"
|
||||||
|
dependencies = [
|
||||||
|
"const-oid",
|
||||||
|
"zeroize",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "digest"
|
||||||
|
version = "0.10.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
|
||||||
|
dependencies = [
|
||||||
|
"block-buffer",
|
||||||
|
"crypto-common",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "displaydoc"
|
name = "displaydoc"
|
||||||
version = "0.2.5"
|
version = "0.2.5"
|
||||||
@ -336,6 +434,30 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ed25519"
|
||||||
|
version = "2.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53"
|
||||||
|
dependencies = [
|
||||||
|
"pkcs8",
|
||||||
|
"signature",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ed25519-dalek"
|
||||||
|
version = "2.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871"
|
||||||
|
dependencies = [
|
||||||
|
"curve25519-dalek",
|
||||||
|
"ed25519",
|
||||||
|
"serde",
|
||||||
|
"sha2",
|
||||||
|
"subtle",
|
||||||
|
"zeroize",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "either"
|
name = "either"
|
||||||
version = "1.13.0"
|
version = "1.13.0"
|
||||||
@ -396,6 +518,12 @@ version = "2.3.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
|
checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fiat-crypto"
|
||||||
|
version = "0.2.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fixedbitset"
|
name = "fixedbitset"
|
||||||
version = "0.4.2"
|
version = "0.4.2"
|
||||||
@ -471,6 +599,16 @@ dependencies = [
|
|||||||
"pin-utils",
|
"pin-utils",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "generic-array"
|
||||||
|
version = "0.14.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
|
||||||
|
dependencies = [
|
||||||
|
"typenum",
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "getrandom"
|
name = "getrandom"
|
||||||
version = "0.2.15"
|
version = "0.2.15"
|
||||||
@ -1112,6 +1250,16 @@ version = "0.1.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pkcs8"
|
||||||
|
version = "0.10.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7"
|
||||||
|
dependencies = [
|
||||||
|
"der",
|
||||||
|
"spki",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pkg-config"
|
name = "pkg-config"
|
||||||
version = "0.3.31"
|
version = "0.3.31"
|
||||||
@ -1340,6 +1488,15 @@ version = "0.1.24"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
|
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc_version"
|
||||||
|
version = "0.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92"
|
||||||
|
dependencies = [
|
||||||
|
"semver",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustix"
|
name = "rustix"
|
||||||
version = "0.38.42"
|
version = "0.38.42"
|
||||||
@ -1442,6 +1599,12 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "semver"
|
||||||
|
version = "1.0.25"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f79dfe2d285b0488816f30e700a7438c5a73d816b5b7d3ac72fbc48b0d185e03"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.216"
|
version = "1.0.216"
|
||||||
@ -1486,12 +1649,32 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sha2"
|
||||||
|
version = "0.10.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"cpufeatures",
|
||||||
|
"digest",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "shlex"
|
name = "shlex"
|
||||||
version = "1.3.0"
|
version = "1.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "signature"
|
||||||
|
version = "2.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de"
|
||||||
|
dependencies = [
|
||||||
|
"rand_core",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "slab"
|
name = "slab"
|
||||||
version = "0.4.9"
|
version = "0.4.9"
|
||||||
@ -1523,6 +1706,16 @@ version = "0.9.8"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
|
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "spki"
|
||||||
|
version = "0.7.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d"
|
||||||
|
dependencies = [
|
||||||
|
"base64ct",
|
||||||
|
"der",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "stable_deref_trait"
|
name = "stable_deref_trait"
|
||||||
version = "1.2.0"
|
version = "1.2.0"
|
||||||
@ -1630,6 +1823,21 @@ dependencies = [
|
|||||||
"zerovec",
|
"zerovec",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tinyvec"
|
||||||
|
version = "1.8.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "022db8904dfa342efe721985167e9fcd16c29b226db4397ed752a761cfce81e8"
|
||||||
|
dependencies = [
|
||||||
|
"tinyvec_macros",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tinyvec_macros"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio"
|
name = "tokio"
|
||||||
version = "1.42.0"
|
version = "1.42.0"
|
||||||
@ -1829,6 +2037,12 @@ version = "0.2.5"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
|
checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "typenum"
|
||||||
|
version = "1.17.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
version = "1.0.14"
|
version = "1.0.14"
|
||||||
@ -1885,6 +2099,12 @@ version = "0.2.15"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "version_check"
|
||||||
|
version = "0.9.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "want"
|
name = "want"
|
||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
|
@ -4,8 +4,10 @@ version = "0.1.0"
|
|||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
bs58 = "0.5.1"
|
||||||
chrono = "0.4.39"
|
chrono = "0.4.39"
|
||||||
dashmap = "6.1.0"
|
dashmap = "6.1.0"
|
||||||
|
ed25519-dalek = "2.1.1"
|
||||||
env_logger = "0.11.6"
|
env_logger = "0.11.6"
|
||||||
log = "0.4.22"
|
log = "0.4.22"
|
||||||
prost = "0.13.4"
|
prost = "0.13.4"
|
||||||
|
28
snp.proto
28
snp.proto
@ -52,6 +52,7 @@ message MeasurementIP {
|
|||||||
string gateway = 4;
|
string gateway = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This should also include a block hash or similar, for auth
|
||||||
message RegisterNodeReq {
|
message RegisterNodeReq {
|
||||||
string node_pubkey = 1;
|
string node_pubkey = 1;
|
||||||
string owner_pubkey = 2;
|
string owner_pubkey = 2;
|
||||||
@ -101,13 +102,14 @@ message NewVmResp {
|
|||||||
|
|
||||||
message UpdateVmReq {
|
message UpdateVmReq {
|
||||||
string uuid = 1;
|
string uuid = 1;
|
||||||
uint32 disk_size_gb = 2;
|
string admin_pubkey = 2;
|
||||||
uint32 vcpus = 3;
|
uint32 disk_size_gb = 3;
|
||||||
uint32 memory_mb = 4;
|
uint32 vcpus = 4;
|
||||||
string kernel_url = 5;
|
uint32 memory_mb = 5;
|
||||||
string kernel_sha = 6;
|
string kernel_url = 6;
|
||||||
string dtrfs_url = 7;
|
string kernel_sha = 7;
|
||||||
string dtrfs_sha = 8;
|
string dtrfs_url = 8;
|
||||||
|
string dtrfs_sha = 9;
|
||||||
}
|
}
|
||||||
|
|
||||||
message UpdateVmResp {
|
message UpdateVmResp {
|
||||||
@ -118,6 +120,7 @@ message UpdateVmResp {
|
|||||||
|
|
||||||
message DeleteVmReq {
|
message DeleteVmReq {
|
||||||
string uuid = 1;
|
string uuid = 1;
|
||||||
|
string admin_pubkey = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
message BrainMessage {
|
message BrainMessage {
|
||||||
@ -128,9 +131,16 @@ message BrainMessage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message DaemonStreamAuth {
|
||||||
|
string timestamp = 1;
|
||||||
|
string pubkey = 2;
|
||||||
|
repeated string contracts = 3;
|
||||||
|
string signature = 4;
|
||||||
|
}
|
||||||
|
|
||||||
message DaemonMessage {
|
message DaemonMessage {
|
||||||
oneof Msg {
|
oneof Msg {
|
||||||
Pubkey pubkey = 1;
|
DaemonStreamAuth auth = 1;
|
||||||
NewVmResp new_vm_resp = 2;
|
NewVmResp new_vm_resp = 2;
|
||||||
UpdateVmResp update_vm_resp = 3;
|
UpdateVmResp update_vm_resp = 3;
|
||||||
NodeResources node_resources = 4;
|
NodeResources node_resources = 4;
|
||||||
@ -139,7 +149,7 @@ message DaemonMessage {
|
|||||||
|
|
||||||
service BrainDaemon {
|
service BrainDaemon {
|
||||||
rpc RegisterNode (RegisterNodeReq) returns (stream Contract);
|
rpc RegisterNode (RegisterNodeReq) returns (stream Contract);
|
||||||
rpc BrainMessages (Pubkey) returns (stream BrainMessage);
|
rpc BrainMessages (DaemonStreamAuth) returns (stream BrainMessage);
|
||||||
rpc DaemonMessages (stream DaemonMessage) returns (Empty);
|
rpc DaemonMessages (stream DaemonMessage) returns (Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
44
src/data.rs
44
src/data.rs
@ -205,15 +205,11 @@ impl BrainData {
|
|||||||
let minutes_to_collect = (Utc::now() - c.collected_at).num_minutes() as u64;
|
let minutes_to_collect = (Utc::now() - c.collected_at).num_minutes() as u64;
|
||||||
c.collected_at = Utc::now();
|
c.collected_at = Utc::now();
|
||||||
log::debug!("{minutes_to_collect}");
|
log::debug!("{minutes_to_collect}");
|
||||||
let mut nanolp_to_collect =
|
let mut nanolp_to_collect = c.price_per_minute().saturating_mul(minutes_to_collect);
|
||||||
c.price_per_minute().saturating_mul(minutes_to_collect);
|
|
||||||
if nanolp_to_collect > c.locked_nano {
|
if nanolp_to_collect > c.locked_nano {
|
||||||
nanolp_to_collect = c.locked_nano;
|
nanolp_to_collect = c.locked_nano;
|
||||||
}
|
}
|
||||||
log::debug!(
|
log::debug!("Removing {nanolp_to_collect} nanoLP from {}", c.uuid);
|
||||||
"Removing {nanolp_to_collect} nanoLP from {}",
|
|
||||||
c.uuid
|
|
||||||
);
|
|
||||||
c.locked_nano -= nanolp_to_collect;
|
c.locked_nano -= nanolp_to_collect;
|
||||||
self.add_nano_to_wallet(&owner_key, nanolp_to_collect);
|
self.add_nano_to_wallet(&owner_key, nanolp_to_collect);
|
||||||
if c.locked_nano == 0 {
|
if c.locked_nano == 0 {
|
||||||
@ -228,6 +224,7 @@ impl BrainData {
|
|||||||
let msg = grpc::BrainMessage {
|
let msg = grpc::BrainMessage {
|
||||||
msg: Some(grpc::brain_message::Msg::DeleteVm(grpc::DeleteVmReq {
|
msg: Some(grpc::brain_message::Msg::DeleteVm(grpc::DeleteVmReq {
|
||||||
uuid: uuid.to_string(),
|
uuid: uuid.to_string(),
|
||||||
|
admin_pubkey: String::new(),
|
||||||
})),
|
})),
|
||||||
};
|
};
|
||||||
let daemon_tx = daemon_tx.clone();
|
let daemon_tx = daemon_tx.clone();
|
||||||
@ -282,13 +279,13 @@ impl BrainData {
|
|||||||
pub fn extend_contract_time(
|
pub fn extend_contract_time(
|
||||||
&self,
|
&self,
|
||||||
uuid: &str,
|
uuid: &str,
|
||||||
account: &str,
|
wallet: &str,
|
||||||
nano_lp: u64,
|
nano_lp: u64,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
if nano_lp > 100_000_000_000_000 {
|
if nano_lp > 100_000_000_000_000 {
|
||||||
return Err(Error::TxTooBig);
|
return Err(Error::TxTooBig);
|
||||||
}
|
}
|
||||||
let mut account = match self.accounts.get_mut(account) {
|
let mut account = match self.accounts.get_mut(wallet) {
|
||||||
Some(account) => account,
|
Some(account) => account,
|
||||||
None => return Err(Error::InsufficientFunds),
|
None => return Err(Error::InsufficientFunds),
|
||||||
};
|
};
|
||||||
@ -300,6 +297,9 @@ impl BrainData {
|
|||||||
.find(|c| c.uuid == uuid)
|
.find(|c| c.uuid == uuid)
|
||||||
{
|
{
|
||||||
Some(contract) => {
|
Some(contract) => {
|
||||||
|
if contract.admin_pubkey != wallet {
|
||||||
|
return Err(Error::ContractNotFound(uuid.to_string()));
|
||||||
|
}
|
||||||
if account.balance + contract.locked_nano < nano_lp {
|
if account.balance + contract.locked_nano < nano_lp {
|
||||||
return Err(Error::InsufficientFunds);
|
return Err(Error::InsufficientFunds);
|
||||||
}
|
}
|
||||||
@ -344,8 +344,18 @@ impl BrainData {
|
|||||||
self.daemon_tx.remove(node_pubkey);
|
self.daemon_tx.remove(node_pubkey);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn delete_vm(&self, delete_vm: grpc::DeleteVmReq) {
|
pub async fn delete_vm(&self, delete_vm: grpc::DeleteVmReq) -> Result<(), Error> {
|
||||||
if let Some(contract) = self.find_contract_by_uuid(&delete_vm.uuid) {
|
let contract = match self.find_contract_by_uuid(&delete_vm.uuid) {
|
||||||
|
Some(contract) => {
|
||||||
|
if contract.admin_pubkey != delete_vm.admin_pubkey {
|
||||||
|
return Err(Error::ContractNotFound(delete_vm.uuid));
|
||||||
|
}
|
||||||
|
contract
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
return Err(Error::ContractNotFound(delete_vm.uuid));
|
||||||
|
}
|
||||||
|
};
|
||||||
info!("Found vm {}. Deleting...", delete_vm.uuid);
|
info!("Found vm {}. Deleting...", delete_vm.uuid);
|
||||||
if let Some(daemon_tx) = self.daemon_tx.get(&contract.node_pubkey) {
|
if let Some(daemon_tx) = self.daemon_tx.get(&contract.node_pubkey) {
|
||||||
debug!(
|
debug!(
|
||||||
@ -368,7 +378,7 @@ impl BrainData {
|
|||||||
self.add_nano_to_wallet(&contract.admin_pubkey, contract.locked_nano);
|
self.add_nano_to_wallet(&contract.admin_pubkey, contract.locked_nano);
|
||||||
let mut contracts = self.contracts.write().unwrap();
|
let mut contracts = self.contracts.write().unwrap();
|
||||||
contracts.retain(|c| c.uuid != delete_vm.uuid);
|
contracts.retain(|c| c.uuid != delete_vm.uuid);
|
||||||
}
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn submit_newvm_resp(&self, new_vm_resp: grpc::NewVmResp) {
|
pub async fn submit_newvm_resp(&self, new_vm_resp: grpc::NewVmResp) {
|
||||||
@ -546,7 +556,17 @@ impl BrainData {
|
|||||||
let uuid = req.uuid.clone();
|
let uuid = req.uuid.clone();
|
||||||
info!("Inserting new vm update request in memory: {req:?}");
|
info!("Inserting new vm update request in memory: {req:?}");
|
||||||
let node_pubkey = match self.find_contract_by_uuid(&req.uuid) {
|
let node_pubkey = match self.find_contract_by_uuid(&req.uuid) {
|
||||||
Some(contract) => contract.node_pubkey,
|
Some(contract) => {
|
||||||
|
if contract.admin_pubkey != req.admin_pubkey {
|
||||||
|
let _ = tx.send(grpc::UpdateVmResp {
|
||||||
|
uuid,
|
||||||
|
error: "Contract does not exist.".to_string(),
|
||||||
|
args: None,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
contract.node_pubkey
|
||||||
|
}
|
||||||
None => {
|
None => {
|
||||||
log::warn!(
|
log::warn!(
|
||||||
"Received UpdateVMReq for a contract that does not exist: {}",
|
"Received UpdateVMReq for a contract that does not exist: {}",
|
||||||
|
228
src/grpc.rs
228
src/grpc.rs
@ -42,7 +42,7 @@ impl BrainDaemon for BrainDaemonMock {
|
|||||||
&self,
|
&self,
|
||||||
req: Request<RegisterNodeReq>,
|
req: Request<RegisterNodeReq>,
|
||||||
) -> Result<Response<Self::RegisterNodeStream>, Status> {
|
) -> Result<Response<Self::RegisterNodeStream>, Status> {
|
||||||
let req = req.into_inner();
|
let req = check_sig_from_req(req)?;
|
||||||
info!("Starting registration process for {:?}", req);
|
info!("Starting registration process for {:?}", req);
|
||||||
let node = crate::data::Node {
|
let node = crate::data::Node {
|
||||||
public_key: req.node_pubkey.clone(),
|
public_key: req.node_pubkey.clone(),
|
||||||
@ -73,12 +73,19 @@ impl BrainDaemon for BrainDaemonMock {
|
|||||||
type BrainMessagesStream = Pin<Box<dyn Stream<Item = Result<BrainMessage, Status>> + Send>>;
|
type BrainMessagesStream = Pin<Box<dyn Stream<Item = Result<BrainMessage, Status>> + Send>>;
|
||||||
async fn brain_messages(
|
async fn brain_messages(
|
||||||
&self,
|
&self,
|
||||||
req: Request<Pubkey>,
|
req: Request<DaemonStreamAuth>,
|
||||||
) -> Result<Response<Self::BrainMessagesStream>, Status> {
|
) -> Result<Response<Self::BrainMessagesStream>, Status> {
|
||||||
let req = req.into_inner();
|
let auth = req.into_inner();
|
||||||
info!("Daemon {} connected to receive brain messages", req.pubkey);
|
let pubkey = auth.pubkey.clone();
|
||||||
|
check_sig_from_parts(
|
||||||
|
&pubkey,
|
||||||
|
&auth.timestamp,
|
||||||
|
&format!("{:?}", auth.contracts),
|
||||||
|
&auth.signature,
|
||||||
|
)?;
|
||||||
|
info!("Daemon {} connected to receive brain messages", pubkey);
|
||||||
let (tx, rx) = mpsc::channel(6);
|
let (tx, rx) = mpsc::channel(6);
|
||||||
self.data.add_daemon_tx(&req.pubkey, tx);
|
self.data.add_daemon_tx(&pubkey, tx);
|
||||||
let output_stream = ReceiverStream::new(rx).map(|msg| Ok(msg));
|
let output_stream = ReceiverStream::new(rx).map(|msg| Ok(msg));
|
||||||
Ok(Response::new(
|
Ok(Response::new(
|
||||||
Box::pin(output_stream) as Self::BrainMessagesStream
|
Box::pin(output_stream) as Self::BrainMessagesStream
|
||||||
@ -90,14 +97,30 @@ impl BrainDaemon for BrainDaemonMock {
|
|||||||
req: Request<Streaming<DaemonMessage>>,
|
req: Request<Streaming<DaemonMessage>>,
|
||||||
) -> Result<Response<Empty>, Status> {
|
) -> Result<Response<Empty>, Status> {
|
||||||
let mut req_stream = req.into_inner();
|
let mut req_stream = req.into_inner();
|
||||||
let mut pubkey = String::new();
|
let pubkey: String;
|
||||||
|
if let Some(Ok(msg)) = req_stream.next().await {
|
||||||
|
log::debug!("demon_messages received the following auth message: {:?}", msg.msg);
|
||||||
|
if let Some(daemon_message::Msg::Auth(auth)) = msg.msg {
|
||||||
|
pubkey = auth.pubkey.clone();
|
||||||
|
check_sig_from_parts(
|
||||||
|
&pubkey,
|
||||||
|
&auth.timestamp,
|
||||||
|
&format!("{:?}", auth.contracts),
|
||||||
|
&auth.signature,
|
||||||
|
)?;
|
||||||
|
} else {
|
||||||
|
return Err(Status::unauthenticated(
|
||||||
|
"Could not authenticate the daemon: could not extract auth signature",
|
||||||
|
));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return Err(Status::unauthenticated("Could not authenticate the daemon"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// info!("Received a message from daemon {pubkey}: {daemon_message:?}");
|
||||||
while let Some(daemon_message) = req_stream.next().await {
|
while let Some(daemon_message) = req_stream.next().await {
|
||||||
info!("Received a message from daemon {pubkey}: {daemon_message:?}");
|
|
||||||
match daemon_message {
|
match daemon_message {
|
||||||
Ok(msg) => match msg.msg {
|
Ok(msg) => match msg.msg {
|
||||||
Some(daemon_message::Msg::Pubkey(p)) => {
|
|
||||||
pubkey = p.pubkey;
|
|
||||||
}
|
|
||||||
Some(daemon_message::Msg::NewVmResp(new_vm_resp)) => {
|
Some(daemon_message::Msg::NewVmResp(new_vm_resp)) => {
|
||||||
self.data.submit_newvm_resp(new_vm_resp).await;
|
self.data.submit_newvm_resp(new_vm_resp).await;
|
||||||
}
|
}
|
||||||
@ -107,7 +130,7 @@ impl BrainDaemon for BrainDaemonMock {
|
|||||||
Some(daemon_message::Msg::NodeResources(node_resources)) => {
|
Some(daemon_message::Msg::NodeResources(node_resources)) => {
|
||||||
self.data.submit_node_resources(node_resources);
|
self.data.submit_node_resources(node_resources);
|
||||||
}
|
}
|
||||||
None => {}
|
_ => {}
|
||||||
},
|
},
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::warn!("Daemon disconnected: {e:?}");
|
log::warn!("Daemon disconnected: {e:?}");
|
||||||
@ -122,18 +145,18 @@ impl BrainDaemon for BrainDaemonMock {
|
|||||||
#[tonic::async_trait]
|
#[tonic::async_trait]
|
||||||
impl BrainCli for BrainCliMock {
|
impl BrainCli for BrainCliMock {
|
||||||
async fn get_balance(&self, req: Request<Pubkey>) -> Result<Response<AccountBalance>, Status> {
|
async fn get_balance(&self, req: Request<Pubkey>) -> Result<Response<AccountBalance>, Status> {
|
||||||
Ok(Response::new(
|
let req = check_sig_from_req(req)?;
|
||||||
self.data.get_balance(&req.into_inner().pubkey).into(),
|
Ok(Response::new(self.data.get_balance(&req.pubkey).into()))
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_airdrop(&self, req: Request<Pubkey>) -> Result<Response<Empty>, Status> {
|
async fn get_airdrop(&self, req: Request<Pubkey>) -> Result<Response<Empty>, Status> {
|
||||||
self.data.get_airdrop(&req.into_inner().pubkey);
|
let req = check_sig_from_req(req)?;
|
||||||
|
self.data.get_airdrop(&req.pubkey);
|
||||||
Ok(Response::new(Empty {}))
|
Ok(Response::new(Empty {}))
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn new_vm(&self, req: Request<NewVmReq>) -> Result<Response<NewVmResp>, Status> {
|
async fn new_vm(&self, req: Request<NewVmReq>) -> Result<Response<NewVmResp>, Status> {
|
||||||
let req = req.into_inner();
|
let req = check_sig_from_req(req)?;
|
||||||
info!("New VM requested via CLI: {req:?}");
|
info!("New VM requested via CLI: {req:?}");
|
||||||
let admin_pubkey = req.admin_pubkey.clone();
|
let admin_pubkey = req.admin_pubkey.clone();
|
||||||
let (oneshot_tx, oneshot_rx) = tokio::sync::oneshot::channel();
|
let (oneshot_tx, oneshot_rx) = tokio::sync::oneshot::channel();
|
||||||
@ -153,7 +176,7 @@ impl BrainCli for BrainCliMock {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn update_vm(&self, req: Request<UpdateVmReq>) -> Result<Response<UpdateVmResp>, Status> {
|
async fn update_vm(&self, req: Request<UpdateVmReq>) -> Result<Response<UpdateVmResp>, Status> {
|
||||||
let req = req.into_inner();
|
let req = check_sig_from_req(req)?;
|
||||||
info!("Update VM requested via CLI: {req:?}");
|
info!("Update VM requested via CLI: {req:?}");
|
||||||
let (oneshot_tx, oneshot_rx) = tokio::sync::oneshot::channel();
|
let (oneshot_tx, oneshot_rx) = tokio::sync::oneshot::channel();
|
||||||
self.data.submit_updatevm_req(req, oneshot_tx).await;
|
self.data.submit_updatevm_req(req, oneshot_tx).await;
|
||||||
@ -169,7 +192,7 @@ impl BrainCli for BrainCliMock {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn extend_vm(&self, req: Request<ExtendVmReq>) -> Result<Response<Empty>, Status> {
|
async fn extend_vm(&self, req: Request<ExtendVmReq>) -> Result<Response<Empty>, Status> {
|
||||||
let req = req.into_inner();
|
let req = check_sig_from_req(req)?;
|
||||||
match self
|
match self
|
||||||
.data
|
.data
|
||||||
.extend_contract_time(&req.uuid, &req.admin_pubkey, req.locked_nano)
|
.extend_contract_time(&req.uuid, &req.admin_pubkey, req.locked_nano)
|
||||||
@ -184,7 +207,7 @@ impl BrainCli for BrainCliMock {
|
|||||||
&self,
|
&self,
|
||||||
req: Request<ListContractsReq>,
|
req: Request<ListContractsReq>,
|
||||||
) -> Result<Response<Self::ListContractsStream>, Status> {
|
) -> Result<Response<Self::ListContractsStream>, Status> {
|
||||||
let req = req.into_inner();
|
let req = check_sig_from_req(req)?;
|
||||||
info!("CLI {} requested ListVMContractsStream", req.admin_pubkey);
|
info!("CLI {} requested ListVMContractsStream", req.admin_pubkey);
|
||||||
let contracts = match req.uuid.is_empty() {
|
let contracts = match req.uuid.is_empty() {
|
||||||
false => match self.data.find_contract_by_uuid(&req.uuid) {
|
false => match self.data.find_contract_by_uuid(&req.uuid) {
|
||||||
@ -210,7 +233,7 @@ impl BrainCli for BrainCliMock {
|
|||||||
&self,
|
&self,
|
||||||
req: Request<NodeFilters>,
|
req: Request<NodeFilters>,
|
||||||
) -> Result<Response<Self::ListNodesStream>, tonic::Status> {
|
) -> Result<Response<Self::ListNodesStream>, tonic::Status> {
|
||||||
let req = req.into_inner();
|
let req = check_sig_from_req(req)?;
|
||||||
info!("Unknown CLI requested ListNodesStream: {req:?}");
|
info!("Unknown CLI requested ListNodesStream: {req:?}");
|
||||||
let nodes = self.data.find_nodes_by_filters(&req);
|
let nodes = self.data.find_nodes_by_filters(&req);
|
||||||
let (tx, rx) = mpsc::channel(6);
|
let (tx, rx) = mpsc::channel(6);
|
||||||
@ -229,7 +252,7 @@ impl BrainCli for BrainCliMock {
|
|||||||
&self,
|
&self,
|
||||||
req: Request<NodeFilters>,
|
req: Request<NodeFilters>,
|
||||||
) -> Result<Response<NodeListResp>, Status> {
|
) -> Result<Response<NodeListResp>, Status> {
|
||||||
let req = req.into_inner();
|
let req = check_sig_from_req(req)?;
|
||||||
info!("Unknown CLI requested ListNodesStream: {req:?}");
|
info!("Unknown CLI requested ListNodesStream: {req:?}");
|
||||||
match self.data.get_one_node_by_filters(&req) {
|
match self.data.get_one_node_by_filters(&req) {
|
||||||
Some(node) => Ok(Response::new(node.into())),
|
Some(node) => Ok(Response::new(node.into())),
|
||||||
@ -240,9 +263,166 @@ impl BrainCli for BrainCliMock {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn delete_vm(&self, req: Request<DeleteVmReq>) -> Result<Response<Empty>, Status> {
|
async fn delete_vm(&self, req: Request<DeleteVmReq>) -> Result<Response<Empty>, Status> {
|
||||||
let req = req.into_inner();
|
let req = check_sig_from_req(req)?;
|
||||||
info!("Unknown CLI requested to delete vm {}", req.uuid);
|
info!("Unknown CLI requested to delete vm {}", req.uuid);
|
||||||
self.data.delete_vm(req).await;
|
match self.data.delete_vm(req).await {
|
||||||
Ok(Response::new(Empty {}))
|
Ok(()) => Ok(Response::new(Empty {})),
|
||||||
|
Err(e) => Err(Status::not_found(e.to_string())),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trait PubkeyGetter {
|
||||||
|
fn get_pubkey(&self) -> Option<String>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PubkeyGetter for Pubkey {
|
||||||
|
fn get_pubkey(&self) -> Option<String> {
|
||||||
|
Some(self.pubkey.clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PubkeyGetter for NewVmReq {
|
||||||
|
fn get_pubkey(&self) -> Option<String> {
|
||||||
|
Some(self.admin_pubkey.clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PubkeyGetter for DeleteVmReq {
|
||||||
|
fn get_pubkey(&self) -> Option<String> {
|
||||||
|
Some(self.admin_pubkey.clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PubkeyGetter for UpdateVmReq {
|
||||||
|
fn get_pubkey(&self) -> Option<String> {
|
||||||
|
Some(self.admin_pubkey.clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PubkeyGetter for ExtendVmReq {
|
||||||
|
fn get_pubkey(&self) -> Option<String> {
|
||||||
|
Some(self.admin_pubkey.clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PubkeyGetter for ListContractsReq {
|
||||||
|
fn get_pubkey(&self) -> Option<String> {
|
||||||
|
Some(self.admin_pubkey.clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PubkeyGetter for NodeFilters {
|
||||||
|
fn get_pubkey(&self) -> Option<String> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PubkeyGetter for RegisterNodeReq {
|
||||||
|
fn get_pubkey(&self) -> Option<String> {
|
||||||
|
Some(self.node_pubkey.clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn check_sig_from_req<T: std::fmt::Debug + PubkeyGetter>(req: Request<T>) -> Result<T, Status> {
|
||||||
|
let time = match req.metadata().get("timestamp") {
|
||||||
|
Some(t) => t.clone(),
|
||||||
|
None => return Err(Status::unauthenticated("Timestamp not found in metadata.")),
|
||||||
|
};
|
||||||
|
let time = time
|
||||||
|
.to_str()
|
||||||
|
.map_err(|_| Status::unauthenticated("Timestamp in metadata is not a string"))?;
|
||||||
|
|
||||||
|
let now = chrono::Utc::now();
|
||||||
|
let parsed_time = chrono::DateTime::parse_from_rfc3339(time)
|
||||||
|
.map_err(|_| Status::unauthenticated("Coult not parse timestamp"))?;
|
||||||
|
let seconds_elapsed = now.signed_duration_since(parsed_time).num_seconds();
|
||||||
|
if seconds_elapsed > 1 || seconds_elapsed < -1 {
|
||||||
|
return Err(Status::unauthenticated(format!(
|
||||||
|
"Date is not within 1 sec of the time of the server: CLI {} vs Server {}",
|
||||||
|
parsed_time, now
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
|
||||||
|
let signature = match req.metadata().get("request-signature") {
|
||||||
|
Some(t) => t,
|
||||||
|
None => return Err(Status::unauthenticated("signature not found in metadata.")),
|
||||||
|
};
|
||||||
|
let signature = bs58::decode(signature)
|
||||||
|
.into_vec()
|
||||||
|
.map_err(|_| Status::unauthenticated("signature is not a bs58 string"))?;
|
||||||
|
let signature = ed25519_dalek::Signature::from_bytes(
|
||||||
|
signature
|
||||||
|
.as_slice()
|
||||||
|
.try_into()
|
||||||
|
.map_err(|_| Status::unauthenticated("could not parse ed25519 signature"))?,
|
||||||
|
);
|
||||||
|
|
||||||
|
let pubkey_value = match req.metadata().get("pubkey") {
|
||||||
|
Some(p) => p.clone(),
|
||||||
|
None => return Err(Status::unauthenticated("Signature not found in metadata.")),
|
||||||
|
};
|
||||||
|
let pubkey = ed25519_dalek::VerifyingKey::from_bytes(
|
||||||
|
&bs58::decode(&pubkey_value)
|
||||||
|
.into_vec()
|
||||||
|
.map_err(|_| Status::unauthenticated("pubkey is not a bs58 string"))?
|
||||||
|
.try_into()
|
||||||
|
.map_err(|_| Status::unauthenticated("pubkey does not have the correct size."))?,
|
||||||
|
)
|
||||||
|
.map_err(|_| Status::unauthenticated("could not parse ed25519 pubkey"))?;
|
||||||
|
|
||||||
|
let req = req.into_inner();
|
||||||
|
let message = format!("{time}{req:?}");
|
||||||
|
use ed25519_dalek::Verifier;
|
||||||
|
pubkey
|
||||||
|
.verify(message.as_bytes(), &signature)
|
||||||
|
.map_err(|_| Status::unauthenticated("the signature is not valid"))?;
|
||||||
|
if let Some(req_pubkey) = req.get_pubkey() {
|
||||||
|
if pubkey_value.to_str().unwrap().to_string() != req_pubkey {
|
||||||
|
return Err(Status::unauthenticated(
|
||||||
|
"pubkey of signature does not match pubkey of request",
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(req)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn check_sig_from_parts(pubkey: &str, time: &str, msg: &str, sig: &str) -> Result<(), Status> {
|
||||||
|
let now = chrono::Utc::now();
|
||||||
|
let parsed_time = chrono::DateTime::parse_from_rfc3339(time)
|
||||||
|
.map_err(|_| Status::unauthenticated("Coult not parse timestamp"))?;
|
||||||
|
let seconds_elapsed = now.signed_duration_since(parsed_time).num_seconds();
|
||||||
|
if seconds_elapsed > 1 || seconds_elapsed < -1 {
|
||||||
|
return Err(Status::unauthenticated(format!(
|
||||||
|
"Date is not within 1 sec of the time of the server: CLI {} vs Server {}",
|
||||||
|
parsed_time, now
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
|
||||||
|
let signature = bs58::decode(sig)
|
||||||
|
.into_vec()
|
||||||
|
.map_err(|_| Status::unauthenticated("signature is not a bs58 string"))?;
|
||||||
|
let signature = ed25519_dalek::Signature::from_bytes(
|
||||||
|
signature
|
||||||
|
.as_slice()
|
||||||
|
.try_into()
|
||||||
|
.map_err(|_| Status::unauthenticated("could not parse ed25519 signature"))?,
|
||||||
|
);
|
||||||
|
|
||||||
|
let pubkey = ed25519_dalek::VerifyingKey::from_bytes(
|
||||||
|
&bs58::decode(&pubkey)
|
||||||
|
.into_vec()
|
||||||
|
.map_err(|_| Status::unauthenticated("pubkey is not a bs58 string"))?
|
||||||
|
.try_into()
|
||||||
|
.map_err(|_| Status::unauthenticated("pubkey does not have the correct size."))?,
|
||||||
|
)
|
||||||
|
.map_err(|_| Status::unauthenticated("could not parse ed25519 pubkey"))?;
|
||||||
|
|
||||||
|
let msg = time.to_string() + msg;
|
||||||
|
use ed25519_dalek::Verifier;
|
||||||
|
pubkey
|
||||||
|
.verify(msg.as_bytes(), &signature)
|
||||||
|
.map_err(|_| Status::unauthenticated("the signature is not valid"))?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user