bless
This commit is contained in:
parent
3a8440c2cd
commit
82ca86f03d
6
TODO
Normal file
6
TODO
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
Non Exaustive list of ideas:
|
||||||
|
|
||||||
|
- Scripting with rhai []
|
||||||
|
- Mouse Input []
|
||||||
|
- Http server []
|
||||||
|
- RCI []
|
||||||
310
node/Cargo.lock
generated
310
node/Cargo.lock
generated
@ -105,12 +105,6 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "atomic-waker"
|
|
||||||
version = "1.1.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "autocfg"
|
name = "autocfg"
|
||||||
version = "1.5.0"
|
version = "1.5.0"
|
||||||
@ -132,12 +126,6 @@ dependencies = [
|
|||||||
"windows-targets 0.52.6",
|
"windows-targets 0.52.6",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "base64"
|
|
||||||
version = "0.22.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "2.9.3"
|
version = "2.9.3"
|
||||||
@ -171,12 +159,12 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"sha2",
|
"sha2",
|
||||||
|
"textwrap",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-tungstenite",
|
"tokio-tungstenite",
|
||||||
"uuid",
|
"uuid",
|
||||||
"vlogger",
|
"vlogger",
|
||||||
"warp",
|
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
"web-sys",
|
"web-sys",
|
||||||
]
|
]
|
||||||
@ -498,24 +486,6 @@ version = "0.1.5"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
|
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "form_urlencoded"
|
|
||||||
version = "1.2.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf"
|
|
||||||
dependencies = [
|
|
||||||
"percent-encoding",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "futures-channel"
|
|
||||||
version = "0.3.31"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10"
|
|
||||||
dependencies = [
|
|
||||||
"futures-core",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-core"
|
name = "futures-core"
|
||||||
version = "0.3.31"
|
version = "0.3.31"
|
||||||
@ -576,25 +546,6 @@ version = "0.31.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
|
checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "h2"
|
|
||||||
version = "0.4.12"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f3c0b69cfcb4e1b9f1bf2f53f95f766e4661169728ec61cd3fe5a0166f2d1386"
|
|
||||||
dependencies = [
|
|
||||||
"atomic-waker",
|
|
||||||
"bytes",
|
|
||||||
"fnv",
|
|
||||||
"futures-core",
|
|
||||||
"futures-sink",
|
|
||||||
"http",
|
|
||||||
"indexmap",
|
|
||||||
"slab",
|
|
||||||
"tokio",
|
|
||||||
"tokio-util",
|
|
||||||
"tracing",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashbrown"
|
name = "hashbrown"
|
||||||
version = "0.15.5"
|
version = "0.15.5"
|
||||||
@ -606,30 +557,6 @@ dependencies = [
|
|||||||
"foldhash",
|
"foldhash",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "headers"
|
|
||||||
version = "0.4.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b3314d5adb5d94bcdf56771f2e50dbbc80bb4bdf88967526706205ac9eff24eb"
|
|
||||||
dependencies = [
|
|
||||||
"base64",
|
|
||||||
"bytes",
|
|
||||||
"headers-core",
|
|
||||||
"http",
|
|
||||||
"httpdate",
|
|
||||||
"mime",
|
|
||||||
"sha1",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "headers-core"
|
|
||||||
version = "0.3.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "54b4a22553d4242c49fddb9ba998a99962b5cc6f22cb5a3482bec22522403ce4"
|
|
||||||
dependencies = [
|
|
||||||
"http",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "heck"
|
name = "heck"
|
||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
@ -653,79 +580,12 @@ dependencies = [
|
|||||||
"itoa",
|
"itoa",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "http-body"
|
|
||||||
version = "1.0.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184"
|
|
||||||
dependencies = [
|
|
||||||
"bytes",
|
|
||||||
"http",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "http-body-util"
|
|
||||||
version = "0.1.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a"
|
|
||||||
dependencies = [
|
|
||||||
"bytes",
|
|
||||||
"futures-core",
|
|
||||||
"http",
|
|
||||||
"http-body",
|
|
||||||
"pin-project-lite",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "httparse"
|
name = "httparse"
|
||||||
version = "1.10.1"
|
version = "1.10.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87"
|
checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "httpdate"
|
|
||||||
version = "1.0.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "hyper"
|
|
||||||
version = "1.7.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "eb3aa54a13a0dfe7fbe3a59e0c76093041720fdc77b110cc0fc260fafb4dc51e"
|
|
||||||
dependencies = [
|
|
||||||
"atomic-waker",
|
|
||||||
"bytes",
|
|
||||||
"futures-channel",
|
|
||||||
"futures-core",
|
|
||||||
"h2",
|
|
||||||
"http",
|
|
||||||
"http-body",
|
|
||||||
"httparse",
|
|
||||||
"httpdate",
|
|
||||||
"itoa",
|
|
||||||
"pin-project-lite",
|
|
||||||
"pin-utils",
|
|
||||||
"smallvec",
|
|
||||||
"tokio",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "hyper-util"
|
|
||||||
version = "0.1.16"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8d9b05277c7e8da2c93a568989bb6207bef0112e8d17df7a6eda4a3cf143bc5e"
|
|
||||||
dependencies = [
|
|
||||||
"bytes",
|
|
||||||
"futures-core",
|
|
||||||
"http",
|
|
||||||
"http-body",
|
|
||||||
"hyper",
|
|
||||||
"pin-project-lite",
|
|
||||||
"tokio",
|
|
||||||
"tower-service",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iana-time-zone"
|
name = "iana-time-zone"
|
||||||
version = "0.1.63"
|
version = "0.1.63"
|
||||||
@ -756,16 +616,6 @@ version = "1.0.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
|
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "indexmap"
|
|
||||||
version = "2.11.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f2481980430f9f78649238835720ddccc57e52df14ffce1c6f37391d61b563e9"
|
|
||||||
dependencies = [
|
|
||||||
"equivalent",
|
|
||||||
"hashbrown",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "indoc"
|
name = "indoc"
|
||||||
version = "2.0.6"
|
version = "2.0.6"
|
||||||
@ -930,22 +780,6 @@ dependencies = [
|
|||||||
"windows-sys 0.52.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "mime"
|
|
||||||
version = "0.3.17"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "mime_guess"
|
|
||||||
version = "2.0.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e"
|
|
||||||
dependencies = [
|
|
||||||
"mime",
|
|
||||||
"unicase",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "miniz_oxide"
|
name = "miniz_oxide"
|
||||||
version = "0.8.9"
|
version = "0.8.9"
|
||||||
@ -1026,32 +860,6 @@ version = "1.0.15"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
|
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "percent-encoding"
|
|
||||||
version = "2.3.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pin-project"
|
|
||||||
version = "1.1.10"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a"
|
|
||||||
dependencies = [
|
|
||||||
"pin-project-internal",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pin-project-internal"
|
|
||||||
version = "1.1.10"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pin-project-lite"
|
name = "pin-project-lite"
|
||||||
version = "0.2.16"
|
version = "0.2.16"
|
||||||
@ -1206,12 +1014,6 @@ version = "1.0.20"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
|
checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "scoped-tls"
|
|
||||||
version = "1.0.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "scopeguard"
|
name = "scopeguard"
|
||||||
version = "1.2.0"
|
version = "1.2.0"
|
||||||
@ -1250,18 +1052,6 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "serde_urlencoded"
|
|
||||||
version = "0.7.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
|
|
||||||
dependencies = [
|
|
||||||
"form_urlencoded",
|
|
||||||
"itoa",
|
|
||||||
"ryu",
|
|
||||||
"serde",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sha1"
|
name = "sha1"
|
||||||
version = "0.10.6"
|
version = "0.10.6"
|
||||||
@ -1332,6 +1122,12 @@ version = "1.15.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
|
checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "smawk"
|
||||||
|
version = "0.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "socket2"
|
name = "socket2"
|
||||||
version = "0.6.0"
|
version = "0.6.0"
|
||||||
@ -1387,6 +1183,17 @@ dependencies = [
|
|||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "textwrap"
|
||||||
|
version = "0.16.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c13547615a44dc9c452a8a534638acdf07120d4b6847c8178705da06306a3057"
|
||||||
|
dependencies = [
|
||||||
|
"smawk",
|
||||||
|
"unicode-linebreak",
|
||||||
|
"unicode-width 0.2.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror"
|
name = "thiserror"
|
||||||
version = "2.0.16"
|
version = "2.0.16"
|
||||||
@ -1450,45 +1257,6 @@ dependencies = [
|
|||||||
"tungstenite",
|
"tungstenite",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "tokio-util"
|
|
||||||
version = "0.7.16"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "14307c986784f72ef81c89db7d9e28d6ac26d16213b109ea501696195e6e3ce5"
|
|
||||||
dependencies = [
|
|
||||||
"bytes",
|
|
||||||
"futures-core",
|
|
||||||
"futures-sink",
|
|
||||||
"pin-project-lite",
|
|
||||||
"tokio",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "tower-service"
|
|
||||||
version = "0.3.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "tracing"
|
|
||||||
version = "0.1.41"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0"
|
|
||||||
dependencies = [
|
|
||||||
"log",
|
|
||||||
"pin-project-lite",
|
|
||||||
"tracing-core",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "tracing-core"
|
|
||||||
version = "0.1.34"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678"
|
|
||||||
dependencies = [
|
|
||||||
"once_cell",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tungstenite"
|
name = "tungstenite"
|
||||||
version = "0.27.0"
|
version = "0.27.0"
|
||||||
@ -1512,18 +1280,18 @@ version = "1.18.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f"
|
checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "unicase"
|
|
||||||
version = "2.8.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
version = "1.0.18"
|
version = "1.0.18"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
|
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-linebreak"
|
||||||
|
version = "0.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-segmentation"
|
name = "unicode-segmentation"
|
||||||
version = "1.12.0"
|
version = "1.12.0"
|
||||||
@ -1590,36 +1358,6 @@ dependencies = [
|
|||||||
"colored",
|
"colored",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "warp"
|
|
||||||
version = "0.4.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "51d06d9202adc1f15d709c4f4a2069be5428aa912cc025d6f268ac441ab066b0"
|
|
||||||
dependencies = [
|
|
||||||
"bytes",
|
|
||||||
"futures-util",
|
|
||||||
"headers",
|
|
||||||
"http",
|
|
||||||
"http-body",
|
|
||||||
"http-body-util",
|
|
||||||
"hyper",
|
|
||||||
"hyper-util",
|
|
||||||
"log",
|
|
||||||
"mime",
|
|
||||||
"mime_guess",
|
|
||||||
"percent-encoding",
|
|
||||||
"pin-project",
|
|
||||||
"scoped-tls",
|
|
||||||
"serde",
|
|
||||||
"serde_json",
|
|
||||||
"serde_urlencoded",
|
|
||||||
"tokio",
|
|
||||||
"tokio-tungstenite",
|
|
||||||
"tokio-util",
|
|
||||||
"tower-service",
|
|
||||||
"tracing",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasi"
|
name = "wasi"
|
||||||
version = "0.11.1+wasi-snapshot-preview1"
|
version = "0.11.1+wasi-snapshot-preview1"
|
||||||
|
|||||||
@ -14,7 +14,6 @@ thiserror = "2.0.16"
|
|||||||
tokio = { version = "1.47.1", features = ["full"] }
|
tokio = { version = "1.47.1", features = ["full"] }
|
||||||
tokio-tungstenite = "0.27.0"
|
tokio-tungstenite = "0.27.0"
|
||||||
uuid = { version = "1.18.0", features = ["v4", "serde"] }
|
uuid = { version = "1.18.0", features = ["v4", "serde"] }
|
||||||
warp = { version = "0.4.2", features = ["server", "websocket"] }
|
|
||||||
wasm-bindgen = "0.2.100"
|
wasm-bindgen = "0.2.100"
|
||||||
web-sys = { version = "0.3.77", features = ["WebSocket"] }
|
web-sys = { version = "0.3.77", features = ["WebSocket"] }
|
||||||
vlogger = { path = "./lib/logger-rs" }
|
vlogger = { path = "./lib/logger-rs" }
|
||||||
@ -26,3 +25,4 @@ anyhow = "1.0.99"
|
|||||||
memory-stats = "1.2.0"
|
memory-stats = "1.2.0"
|
||||||
jemalloc = "0.3.0"
|
jemalloc = "0.3.0"
|
||||||
jemallocator = "0.5.4"
|
jemallocator = "0.5.4"
|
||||||
|
textwrap = "0.16.2"
|
||||||
|
|||||||
@ -2,18 +2,30 @@
|
|||||||
{
|
{
|
||||||
"head": {
|
"head": {
|
||||||
"previous_hash": "",
|
"previous_hash": "",
|
||||||
"timestamp": 1756157257,
|
"timestamp": 1756502951,
|
||||||
"merkle_root": "3f99805580f3b4bbd1a903180d2057cfd7dace97d820d7170ffd83c95ce3852c",
|
"merkle_root": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
||||||
"block_hash": "06af1aabb570a702dfd2ee7654200890c26e1fdc380589ae76825976524d5d09",
|
"block_hash": "04e5cdf592f6ab35dccdc41add80568c0de8be60609f5f9053cbe0d156fb8ea0",
|
||||||
"nonce": 9
|
"nonce": 6
|
||||||
|
},
|
||||||
|
"data": []
|
||||||
},
|
},
|
||||||
"tx": [
|
|
||||||
{
|
{
|
||||||
|
"head": {
|
||||||
|
"previous_hash": "04e5cdf592f6ab35dccdc41add80568c0de8be60609f5f9053cbe0d156fb8ea0",
|
||||||
|
"timestamp": 1756503577,
|
||||||
|
"merkle_root": "3f99805580f3b4bbd1a903180d2057cfd7dace97d820d7170ffd83c95ce3852c",
|
||||||
|
"block_hash": "0655c8ab80aeda9ed1db6e72ec48cdf9d9c7799356b11519979f3d7dbce57677",
|
||||||
|
"nonce": 7
|
||||||
|
},
|
||||||
|
"data": [
|
||||||
|
{
|
||||||
|
"Transaction": {
|
||||||
"from": "victor",
|
"from": "victor",
|
||||||
"to": "pia",
|
"to": "pia",
|
||||||
"value": 500,
|
"value": 500,
|
||||||
"data": "almosen"
|
"data": "almosen"
|
||||||
}
|
}
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -2,7 +2,7 @@ use std::net::SocketAddr;
|
|||||||
|
|
||||||
use clap::{Parser, Subcommand};
|
use clap::{Parser, Subcommand};
|
||||||
use crate::core;
|
use crate::core;
|
||||||
use crate::watcher::RenderPane;
|
use crate::watcher::{RenderLayoutKind, RenderPane};
|
||||||
|
|
||||||
|
|
||||||
use clap::*;
|
use clap::*;
|
||||||
@ -59,6 +59,11 @@ pub enum CliCommand{
|
|||||||
#[command(name = "clear", aliases = ["c"])]
|
#[command(name = "clear", aliases = ["c"])]
|
||||||
Clear{
|
Clear{
|
||||||
pane: RenderPane
|
pane: RenderPane
|
||||||
|
},
|
||||||
|
|
||||||
|
#[command(name = "layout", aliases = ["lay"])]
|
||||||
|
Layout {
|
||||||
|
mode: RenderLayoutKind
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,8 +1,9 @@
|
|||||||
use crate::args::*;
|
use crate::args::*;
|
||||||
use crate::core::NetworkData;
|
use crate::core::NetworkData;
|
||||||
|
use crate::event_bus::publish_render_event;
|
||||||
use crate::native_node::node::*;
|
use crate::native_node::node::*;
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use crate::watcher::ExecutorCommand;
|
use crate::watcher::{ExecutorCommand, RenderCommand};
|
||||||
|
|
||||||
pub fn handle_peer_command(cmd: CliPeerCommand) -> NodeCommand {
|
pub fn handle_peer_command(cmd: CliPeerCommand) -> NodeCommand {
|
||||||
match cmd {
|
match cmd {
|
||||||
@ -36,7 +37,8 @@ fn handle_ping(cmd: CliPingCommand) -> NodeCommand {
|
|||||||
pub fn cli(input: &[&str]) -> ExecutorCommand {
|
pub fn cli(input: &[&str]) -> ExecutorCommand {
|
||||||
match Cli::try_parse_from(input) {
|
match Cli::try_parse_from(input) {
|
||||||
Ok(cmd) => match cmd.command {
|
Ok(cmd) => match cmd.command {
|
||||||
CliCommand::Clear { pane } => ExecutorCommand::Clear(pane),
|
CliCommand::Layout { mode } => ExecutorCommand::Render(RenderCommand::ChangeLayout(mode)),
|
||||||
|
CliCommand::Clear { pane } => ExecutorCommand::Render(RenderCommand::ClearPane(pane)),
|
||||||
CliCommand::Peer { peer_cmd } => ExecutorCommand::Node(handle_peer_command(peer_cmd)),
|
CliCommand::Peer { peer_cmd } => ExecutorCommand::Node(handle_peer_command(peer_cmd)),
|
||||||
CliCommand::Block { block_cmd } => ExecutorCommand::Node(handle_block_command(block_cmd)),
|
CliCommand::Block { block_cmd } => ExecutorCommand::Node(handle_block_command(block_cmd)),
|
||||||
CliCommand::Transaction(tx)=> ExecutorCommand::Node(NodeCommand::ProcessNetworkData(NetworkData::Transaction(tx))),
|
CliCommand::Transaction(tx)=> ExecutorCommand::Node(NodeCommand::ProcessNetworkData(NetworkData::Transaction(tx))),
|
||||||
|
|||||||
@ -12,7 +12,7 @@ pub struct BlockHeader {
|
|||||||
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize, Default)]
|
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize, Default)]
|
||||||
pub struct Block {
|
pub struct Block {
|
||||||
pub head: BlockHeader,
|
pub head: BlockHeader,
|
||||||
pub tx: Vec<NetworkData>
|
pub data: Vec<NetworkData>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BlockHeader {
|
impl BlockHeader {
|
||||||
@ -34,13 +34,13 @@ impl BlockHeader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Block {
|
impl Block {
|
||||||
pub fn new(head: BlockHeader, tx: Vec<NetworkData>) -> Self {
|
pub fn new(head: BlockHeader, data: Vec<NetworkData>) -> Self {
|
||||||
Self { head, tx }
|
Self { head, data }
|
||||||
}
|
}
|
||||||
pub fn head(&self) -> &BlockHeader {
|
pub fn head(&self) -> &BlockHeader {
|
||||||
&self.head
|
&self.head
|
||||||
}
|
}
|
||||||
pub fn tx(&self) -> &[NetworkData] {
|
pub fn data(&self) -> &[NetworkData] {
|
||||||
&self.tx
|
&self.data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,7 @@ use sha2::Sha256;
|
|||||||
|
|
||||||
use vlogger::*;
|
use vlogger::*;
|
||||||
use crate::core::NetworkData;
|
use crate::core::NetworkData;
|
||||||
|
use crate::error::print_error_chain;
|
||||||
use crate::log;
|
use crate::log;
|
||||||
|
|
||||||
use crate::core;
|
use crate::core;
|
||||||
@ -15,11 +16,14 @@ const BLOCKCHAIN_ID: &str = "watch-chain";
|
|||||||
|
|
||||||
pub type Account = String;
|
pub type Account = String;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, thiserror::Error)]
|
||||||
pub enum ValidationError {
|
pub enum ValidationError {
|
||||||
|
#[error("Invalid Block Hash Detected")]
|
||||||
InvalidBlockHash,
|
InvalidBlockHash,
|
||||||
|
#[error("Previous Block Hash doesn't match")]
|
||||||
InvalidPreviousBlockHash,
|
InvalidPreviousBlockHash,
|
||||||
InvalidBlockJson
|
#[error("Invalid Block JSON: {0}")]
|
||||||
|
InvalidBlockJson(#[from] serde_json::Error)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
@ -34,7 +38,7 @@ pub struct Blockchain {
|
|||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
impl Blockchain {
|
impl Blockchain {
|
||||||
pub fn add(&mut self, data: NetworkData) -> Result<(), BlockchainError> {
|
pub fn add(&mut self, data: NetworkData) -> Result<(), BlockchainError> {
|
||||||
self.apply(&data)?;
|
self.apply(data.clone())?;
|
||||||
self.mempool.push(data);
|
self.mempool.push(data);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -147,6 +151,7 @@ impl Blockchain {
|
|||||||
|
|
||||||
fn apply_transaction(&mut self, tx: &core::Tx) -> Result<(), BlockchainError> {
|
fn apply_transaction(&mut self, tx: &core::Tx) -> Result<(), BlockchainError> {
|
||||||
tx.validate()?;
|
tx.validate()?;
|
||||||
|
return Ok(());
|
||||||
if let Some(from_balance) = self.balances.get_mut(tx.from()) {
|
if let Some(from_balance) = self.balances.get_mut(tx.from()) {
|
||||||
if *from_balance > tx.value() {
|
if *from_balance > tx.value() {
|
||||||
*from_balance -= tx.value();
|
*from_balance -= tx.value();
|
||||||
@ -169,10 +174,11 @@ impl Blockchain {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn apply(&mut self, data: &NetworkData) -> Result<(), BlockchainError> {
|
pub fn apply(&mut self, data: NetworkData) -> Result<(), BlockchainError> {
|
||||||
match &data {
|
match &data {
|
||||||
NetworkData::Transaction(tx) => {
|
NetworkData::Transaction(tx) => {
|
||||||
self.apply_transaction(tx)?;
|
self.apply_transaction(tx)?;
|
||||||
|
self.mempool.push(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -203,7 +209,7 @@ pub fn calculate_block_hash(head: &core::BlockHeader) -> String {
|
|||||||
|
|
||||||
impl Blockchain {
|
impl Blockchain {
|
||||||
pub fn list_blocks(&self) -> String {
|
pub fn list_blocks(&self) -> String {
|
||||||
let mut ret = String::from("Blocks List\n-------------------");
|
let mut ret = String::from("Blocks List\n-------------------\n");
|
||||||
for (i, b) in self.blocks.iter().enumerate() {
|
for (i, b) in self.blocks.iter().enumerate() {
|
||||||
ret.push_str(format!("Block Hash #{i}: {}\n", b.head.block_hash()).as_str())
|
ret.push_str(format!("Block Hash #{i}: {}\n", b.head.block_hash()).as_str())
|
||||||
}
|
}
|
||||||
@ -224,7 +230,7 @@ impl Blockchain {
|
|||||||
Err(e) => match e {
|
Err(e) => match e {
|
||||||
ValidationError::InvalidBlockHash => log(msg!(ERROR, "Invalid Block Hash")),
|
ValidationError::InvalidBlockHash => log(msg!(ERROR, "Invalid Block Hash")),
|
||||||
ValidationError::InvalidPreviousBlockHash => log(msg!(ERROR, "Invalid Previos Block Hash")),
|
ValidationError::InvalidPreviousBlockHash => log(msg!(ERROR, "Invalid Previos Block Hash")),
|
||||||
ValidationError::InvalidBlockJson => log(msg!(ERROR, "Invalid Block JSON"))
|
ValidationError::InvalidBlockJson(e) => print_error_chain(e.into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -257,17 +263,20 @@ impl Blockchain {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn build(blocks: &str) -> Result<Blockchain, ValidationError> {
|
pub fn build(blocks: &str) -> Result<Blockchain, ValidationError> {
|
||||||
if let Ok(blocks) = serde_json::from_str::<Vec<core::Block>>(&blocks) {
|
match serde_json::from_str::<Vec<core::Block>>(&blocks) {
|
||||||
|
Ok(blocks) => {
|
||||||
let chain = Blockchain {
|
let chain = Blockchain {
|
||||||
blocks,
|
blocks,
|
||||||
balances: HashMap::new(),
|
balances: HashMap::new(),
|
||||||
mempool: vec![],
|
mempool: vec![],
|
||||||
id: BLOCKCHAIN_ID.to_string(),
|
id: BLOCKCHAIN_ID.to_string(),
|
||||||
};
|
};
|
||||||
|
|
||||||
chain.validate_chain()?;
|
chain.validate_chain()?;
|
||||||
return Ok(chain)
|
Ok(chain)
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
Err(ValidationError::InvalidBlockJson(e))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Err(ValidationError::InvalidBlockJson)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
6
node/src/core/data.rs
Normal file
6
node/src/core/data.rs
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
use super::Tx;
|
||||||
|
|
||||||
|
#[derive(serde::Deserialize, serde::Serialize, Debug, Clone)]
|
||||||
|
pub enum NetworkData {
|
||||||
|
Transaction(Tx)
|
||||||
|
}
|
||||||
@ -1,11 +1,6 @@
|
|||||||
use crate::core::Account;
|
use crate::core::Account;
|
||||||
use crate::error::TxError;
|
use crate::error::TxError;
|
||||||
|
|
||||||
#[derive(serde::Deserialize, serde::Serialize, Debug, Clone)]
|
|
||||||
pub enum NetworkData {
|
|
||||||
Transaction(Tx)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(serde::Deserialize, serde::Serialize, Debug, clap::Args, Clone)]
|
#[derive(serde::Deserialize, serde::Serialize, Debug, clap::Args, Clone)]
|
||||||
pub struct Tx {
|
pub struct Tx {
|
||||||
from: Account,
|
from: Account,
|
||||||
|
|||||||
@ -62,7 +62,10 @@ impl<T: Clone + std::fmt::Debug> EventBus<T> {
|
|||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum SystemEvent {
|
pub enum SystemEvent {
|
||||||
Exit
|
ExecutorStarted,
|
||||||
|
RendererStarted,
|
||||||
|
NodeStarted,
|
||||||
|
Exit,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
|
|||||||
@ -47,6 +47,10 @@ pub mod core {
|
|||||||
|
|
||||||
pub mod tx;
|
pub mod tx;
|
||||||
pub use tx::*;
|
pub use tx::*;
|
||||||
|
|
||||||
|
pub mod data;
|
||||||
|
pub use data::*;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod seeds_constants;
|
pub mod seeds_constants;
|
||||||
|
|||||||
@ -2,14 +2,14 @@ use blockchain::watcher::Watcher;
|
|||||||
use blockchain::args;
|
use blockchain::args;
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
|
|
||||||
// src/main.rs
|
// // src/main.rs
|
||||||
use jemallocator::Jemalloc;
|
// use jemallocator::Jemalloc;
|
||||||
|
//
|
||||||
#[global_allocator]
|
// #[global_allocator]
|
||||||
static GLOBAL: Jemalloc = Jemalloc;
|
// static GLOBAL: Jemalloc = Jemalloc;
|
||||||
|
//
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() {
|
async fn main() -> Result<(), std::io::Error> {
|
||||||
|
|
||||||
let args = args::CliArgs::parse();
|
let args = args::CliArgs::parse();
|
||||||
|
|
||||||
@ -21,6 +21,12 @@ async fn main() {
|
|||||||
.bootstrap(args.bootstrap)
|
.bootstrap(args.bootstrap)
|
||||||
.start().await;
|
.start().await;
|
||||||
|
|
||||||
|
crossterm::execute!(
|
||||||
|
std::io::stdout(),
|
||||||
|
crossterm::event::EnableBracketedPaste,
|
||||||
|
crossterm::event::EnableFocusChange,
|
||||||
|
crossterm::event::EnableMouseCapture,
|
||||||
|
)?;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
if !watcher.poll().await.is_ok_and(|b| b) {
|
if !watcher.poll().await.is_ok_and(|b| b) {
|
||||||
@ -28,6 +34,13 @@ async fn main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
crossterm::execute!(
|
||||||
|
std::io::stdout(),
|
||||||
|
crossterm::event::DisableBracketedPaste,
|
||||||
|
crossterm::event::DisableFocusChange,
|
||||||
|
crossterm::event::DisableMouseCapture
|
||||||
|
)?;
|
||||||
ratatui::restore();
|
ratatui::restore();
|
||||||
println!("Hello, world!");
|
println!("Hello, world!");
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
use crate::core::{self, Blockchain, NetworkData, ValidationError};
|
use crate::core::{self, Blockchain, NetworkData, ValidationError};
|
||||||
use crate::error::print_error_chain;
|
use crate::error::print_error_chain;
|
||||||
|
use crate::event_bus::{publish_system_event, SystemEvent};
|
||||||
use crate::protocol::ProtocolMessage;
|
use crate::protocol::ProtocolMessage;
|
||||||
|
|
||||||
use crate::seeds_constants::SEED_NODES;
|
use crate::seeds_constants::SEED_NODES;
|
||||||
@ -125,10 +126,15 @@ impl NativeNode {
|
|||||||
exec_tx: mpsc::Sender<ExecutorCommand>,
|
exec_tx: mpsc::Sender<ExecutorCommand>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let (tx, rx) = mpsc::channel::<NodeCommand>(100);
|
let (tx, rx) = mpsc::channel::<NodeCommand>(100);
|
||||||
|
let chain = Blockchain::build(blocks_json)
|
||||||
|
.unwrap_or_else(|e| {
|
||||||
|
print_error_chain(e.into());
|
||||||
|
Default::default()
|
||||||
|
});
|
||||||
Self {
|
Self {
|
||||||
id: Uuid::new_v4(),
|
id: Uuid::new_v4(),
|
||||||
tcp_peers: HashMap::new(),
|
tcp_peers: HashMap::new(),
|
||||||
chain: Blockchain::build(blocks_json).unwrap_or(Default::default()),
|
chain,
|
||||||
addr,
|
addr,
|
||||||
exec_tx,
|
exec_tx,
|
||||||
listner_handle: None,
|
listner_handle: None,
|
||||||
@ -138,7 +144,7 @@ impl NativeNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn process_message(&mut self, peer_id: uuid::Uuid, message: &ProtocolMessage) {
|
pub async fn process_message(&mut self, peer_id: uuid::Uuid, message: ProtocolMessage) {
|
||||||
|
|
||||||
match message {
|
match message {
|
||||||
ProtocolMessage::BootstrapRequest { .. } => {
|
ProtocolMessage::BootstrapRequest { .. } => {
|
||||||
@ -155,19 +161,19 @@ impl NativeNode {
|
|||||||
},
|
},
|
||||||
ProtocolMessage::BootstrapResponse { blocks } => {
|
ProtocolMessage::BootstrapResponse { blocks } => {
|
||||||
log(msg!(DEBUG, "Received BootstrapResponse from seed"));
|
log(msg!(DEBUG, "Received BootstrapResponse from seed"));
|
||||||
self.chain = core::Blockchain::build(blocks).unwrap();
|
self.chain = core::Blockchain::build(&blocks).unwrap();
|
||||||
},
|
},
|
||||||
ProtocolMessage::Ping {peer_id} => {
|
ProtocolMessage::Ping {peer_id} => {
|
||||||
log(msg!(DEBUG, "Received Ping from {peer_id}"));
|
log(msg!(DEBUG, "Received Ping from {peer_id}"));
|
||||||
let resp = ProtocolMessage::Pong { peer_id: self.id.clone() };
|
let resp = ProtocolMessage::Pong { peer_id: self.id.clone() };
|
||||||
let peer = &self.tcp_peers[peer_id];
|
let peer = &self.tcp_peers[&peer_id];
|
||||||
peer.sender.send(resp).await.unwrap();
|
peer.sender.send(resp).await.unwrap();
|
||||||
},
|
},
|
||||||
ProtocolMessage::GetPeersRequest { peer_id } => {
|
ProtocolMessage::GetPeersRequest { peer_id } => {
|
||||||
log(msg!(DEBUG, "Received GetPeersRequest from {peer_id}"));
|
log(msg!(DEBUG, "Received GetPeersRequest from {peer_id}"));
|
||||||
let peers = self.peer_addresses();
|
let peers = self.peer_addresses();
|
||||||
let resp = ProtocolMessage::GetPeersResponse { peer_addresses: peers };
|
let resp = ProtocolMessage::GetPeersResponse { peer_addresses: peers };
|
||||||
let peer = &self.tcp_peers[peer_id];
|
let peer = &self.tcp_peers[&peer_id];
|
||||||
peer.sender.send(resp).await.unwrap();
|
peer.sender.send(resp).await.unwrap();
|
||||||
}
|
}
|
||||||
ProtocolMessage::Block { block, ..} => {
|
ProtocolMessage::Block { block, ..} => {
|
||||||
@ -225,7 +231,7 @@ impl NativeNode {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn broadcast_network_data(&self, data: &NetworkData) {
|
async fn broadcast_network_data(&self, data: NetworkData) {
|
||||||
for (id, peer) in &self.tcp_peers {
|
for (id, peer) in &self.tcp_peers {
|
||||||
let message = ProtocolMessage::NetworkData{peer_id: self.id, data: data.clone()};
|
let message = ProtocolMessage::NetworkData{peer_id: self.id, data: data.clone()};
|
||||||
peer.sender.send(message).await.unwrap();
|
peer.sender.send(message).await.unwrap();
|
||||||
@ -253,7 +259,7 @@ impl NativeNode {
|
|||||||
return self.exec_tx.clone()
|
return self.exec_tx.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn network_data(&mut self, data: &NetworkData) {
|
async fn network_data(&mut self, data: NetworkData) {
|
||||||
match self.chain.apply(data) {
|
match self.chain.apply(data) {
|
||||||
Ok(_) => log(msg!(DEBUG, "NetworkData Applied")),
|
Ok(_) => log(msg!(DEBUG, "NetworkData Applied")),
|
||||||
Err(e) => print_error_chain(e.into())
|
Err(e) => print_error_chain(e.into())
|
||||||
@ -301,7 +307,7 @@ impl NativeNode {
|
|||||||
self.start_connection_listner(SocketAddr::new(std::net::IpAddr::V4(std::net::Ipv4Addr::new(0,0,0,0)), 8080)).await;
|
self.start_connection_listner(SocketAddr::new(std::net::IpAddr::V4(std::net::Ipv4Addr::new(0,0,0,0)), 8080)).await;
|
||||||
};
|
};
|
||||||
|
|
||||||
log(msg!(INFO, "Started Node"));
|
publish_system_event(SystemEvent::NodeStarted);
|
||||||
|
|
||||||
while let Some(command) = self.rx.recv().await {
|
while let Some(command) = self.rx.recv().await {
|
||||||
match command {
|
match command {
|
||||||
@ -347,11 +353,11 @@ impl NativeNode {
|
|||||||
self.remove_tcp_peer(peer_id).await;
|
self.remove_tcp_peer(peer_id).await;
|
||||||
}
|
}
|
||||||
NodeCommand::ProcessMessage { peer_id, message } => {
|
NodeCommand::ProcessMessage { peer_id, message } => {
|
||||||
self.process_message(peer_id, &message).await;
|
self.process_message(peer_id, message).await;
|
||||||
},
|
},
|
||||||
NodeCommand::ProcessNetworkData(data) => {
|
NodeCommand::ProcessNetworkData(data) => {
|
||||||
self.network_data(&data).await;
|
self.network_data(data.clone()).await;
|
||||||
self.broadcast_network_data(&data).await;
|
self.broadcast_network_data(data).await;
|
||||||
},
|
},
|
||||||
NodeCommand::CreateBlock => {
|
NodeCommand::CreateBlock => {
|
||||||
log(msg!(DEBUG, "Received CreateBlock Command"));
|
log(msg!(DEBUG, "Received CreateBlock Command"));
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
use crate::{event_bus::publish_render_event, log, native_node::node::NodeCommand, watcher::renderer::*};
|
use crate::{event_bus::{publish_render_event, publish_system_event, SystemEvent}, log, native_node::node::NodeCommand, watcher::renderer::*};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use tokio::sync::mpsc;
|
use tokio::sync::mpsc;
|
||||||
use vlogger::*;
|
use vlogger::*;
|
||||||
@ -10,7 +10,7 @@ pub enum ExecutorCommand {
|
|||||||
Print(String),
|
Print(String),
|
||||||
InvalidCommand(String),
|
InvalidCommand(String),
|
||||||
Node(NodeCommand),
|
Node(NodeCommand),
|
||||||
Clear(RenderPane),
|
Render(RenderCommand),
|
||||||
Exit
|
Exit
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -36,6 +36,7 @@ impl Executor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn run(&mut self) {
|
pub async fn run(&mut self) {
|
||||||
|
publish_system_event(SystemEvent::ExecutorStarted);
|
||||||
while !self.exit {
|
while !self.exit {
|
||||||
self.listen().await;
|
self.listen().await;
|
||||||
}
|
}
|
||||||
@ -70,11 +71,6 @@ impl Executor {
|
|||||||
publish_render_event(rd_cmd);
|
publish_render_event(rd_cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn clear(&self, p: RenderPane) {
|
|
||||||
let rd_cmd = RenderCommand::ClearPane(p);
|
|
||||||
publish_render_event(rd_cmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn invalid_command(&self, str: String) {
|
async fn invalid_command(&self, str: String) {
|
||||||
let rd_cmd = RenderCommand::RenderStringToPane{
|
let rd_cmd = RenderCommand::RenderStringToPane{
|
||||||
str,
|
str,
|
||||||
@ -87,7 +83,7 @@ impl Executor {
|
|||||||
match cmd {
|
match cmd {
|
||||||
ExecutorCommand::NodeResponse(resp) => log(resp),
|
ExecutorCommand::NodeResponse(resp) => log(resp),
|
||||||
ExecutorCommand::Node(n) => self.handle_node_cmd(n).await,
|
ExecutorCommand::Node(n) => self.handle_node_cmd(n).await,
|
||||||
ExecutorCommand::Clear(p) => self.clear(p).await,
|
ExecutorCommand::Render(p) => publish_render_event(p),
|
||||||
ExecutorCommand::Echo(s) => self.echo(s).await,
|
ExecutorCommand::Echo(s) => self.echo(s).await,
|
||||||
ExecutorCommand::Print(s) => log(s),
|
ExecutorCommand::Print(s) => log(s),
|
||||||
ExecutorCommand::InvalidCommand(str) => self.invalid_command(str).await,
|
ExecutorCommand::InvalidCommand(str) => self.invalid_command(str).await,
|
||||||
|
|||||||
@ -11,8 +11,8 @@ use ratatui::{
|
|||||||
|
|
||||||
use vlogger::*;
|
use vlogger::*;
|
||||||
|
|
||||||
use crate::event_bus::subscribe_render_event;
|
use crate::event_bus::{publish_system_event, subscribe_render_event, SystemEvent};
|
||||||
use tokio::time::{timeout, Duration};
|
use tokio::time::{interval, timeout, Duration};
|
||||||
use std::io;
|
use std::io;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -27,6 +27,9 @@ pub struct Pane {
|
|||||||
title: Option<String>,
|
title: Option<String>,
|
||||||
target: RenderPane,
|
target: RenderPane,
|
||||||
buffer: RenderBuffer,
|
buffer: RenderBuffer,
|
||||||
|
focused: bool,
|
||||||
|
scroll: i16,
|
||||||
|
max_scroll: i16,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone, clap::ValueEnum)]
|
#[derive(Debug, PartialEq, Clone, clap::ValueEnum)]
|
||||||
@ -46,7 +49,7 @@ enum RenderBuffer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Pane {
|
impl Pane {
|
||||||
fn render(&self, area: Rect, buf: &mut Buffer) {
|
fn render(&mut self, area: Rect, buf: &mut Buffer) {
|
||||||
let block = Block::bordered()
|
let block = Block::bordered()
|
||||||
.title({
|
.title({
|
||||||
if let Some(t) = &self.title {
|
if let Some(t) = &self.title {
|
||||||
@ -55,27 +58,38 @@ impl Pane {
|
|||||||
Default::default()
|
Default::default()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.border_set(border::PLAIN);
|
.border_set(border::PLAIN)
|
||||||
match &self.buffer {
|
.border_style({
|
||||||
RenderBuffer::String(s) => {
|
if self.focused {
|
||||||
|
Style::new().green()
|
||||||
|
} else {
|
||||||
|
Style::new().white()
|
||||||
|
}
|
||||||
|
});
|
||||||
let inner_area = block.inner(area);
|
let inner_area = block.inner(area);
|
||||||
let content_width = inner_area.width as usize;
|
let content_width = inner_area.width as usize;
|
||||||
let content_height = inner_area.height as usize;
|
let content_height = inner_area.height as usize;
|
||||||
|
match &self.buffer {
|
||||||
|
RenderBuffer::String(s) => {
|
||||||
let wrapped_lines = s
|
let wrapped_lines = s
|
||||||
.lines()
|
.lines()
|
||||||
.map(|line| {
|
.map(|line| {
|
||||||
if line.is_empty() {
|
if line.is_empty() {
|
||||||
1
|
1
|
||||||
} else {
|
} else {
|
||||||
(line.len() + content_width - 1) / content_width
|
(line.len() + content_width - 1) / { content_width + (content_width == 0) as usize }
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.sum::<usize>();
|
.sum::<usize>();
|
||||||
let scroll_offset = if wrapped_lines > content_height {
|
|
||||||
wrapped_lines - content_height
|
self.max_scroll = if wrapped_lines > content_height {
|
||||||
|
(wrapped_lines - content_height) as i16
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let scroll_offset = self.max_scroll.saturating_sub(self.scroll) as u16;
|
||||||
|
|
||||||
Paragraph::new(s.clone())
|
Paragraph::new(s.clone())
|
||||||
.wrap(Wrap::default())
|
.wrap(Wrap::default())
|
||||||
.left_aligned()
|
.left_aligned()
|
||||||
@ -84,13 +98,12 @@ impl Pane {
|
|||||||
.render(area, buf);
|
.render(area, buf);
|
||||||
}
|
}
|
||||||
RenderBuffer::List { list, .. } => {
|
RenderBuffer::List { list, .. } => {
|
||||||
let items: Vec<String> = list
|
let list_w = List::new(list
|
||||||
.iter()
|
.iter()
|
||||||
.map(|s| {
|
.map(|s| {
|
||||||
format!("> {s}")
|
format!("> {}", textwrap::fill(s, content_width.saturating_sub(2)))
|
||||||
})
|
})).block(block);
|
||||||
.collect();
|
Widget::render(list_w, area, buf);
|
||||||
Widget::render(List::new(items).block(block), area, buf);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -109,12 +122,21 @@ pub enum RenderCommand {
|
|||||||
},
|
},
|
||||||
ChangeLayout(RenderLayoutKind),
|
ChangeLayout(RenderLayoutKind),
|
||||||
ClearPane(RenderPane),
|
ClearPane(RenderPane),
|
||||||
|
|
||||||
|
|
||||||
|
/// Mouse Events
|
||||||
|
MouseClickLeft(u16, u16),
|
||||||
|
MouseScrollUp,
|
||||||
|
MouseScrollDown,
|
||||||
Exit,
|
Exit,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone, clap::ValueEnum)]
|
||||||
pub enum RenderLayoutKind {
|
pub enum RenderLayoutKind {
|
||||||
Cli,
|
#[value(name = "horizontal", aliases = ["h"])]
|
||||||
|
CliHorizontal,
|
||||||
|
#[value(name = "vertical", aliases = ["v"])]
|
||||||
|
CliVertical
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -126,12 +148,21 @@ pub struct RenderLayout {
|
|||||||
impl RenderLayoutKind {
|
impl RenderLayoutKind {
|
||||||
pub fn rects(&self, area: Rect) -> std::rc::Rc<[Rect]> {
|
pub fn rects(&self, area: Rect) -> std::rc::Rc<[Rect]> {
|
||||||
match self {
|
match self {
|
||||||
Self::Cli => {
|
Self::CliHorizontal => {
|
||||||
|
Layout::default()
|
||||||
|
.direction(Direction::Vertical)
|
||||||
|
.constraints(vec![
|
||||||
|
Constraint::Percentage(70),
|
||||||
|
Constraint::Percentage(30),
|
||||||
|
])
|
||||||
|
.split(area)
|
||||||
|
}
|
||||||
|
Self::CliVertical => {
|
||||||
Layout::default()
|
Layout::default()
|
||||||
.direction(Direction::Horizontal)
|
.direction(Direction::Horizontal)
|
||||||
.constraints(vec![
|
.constraints(vec![
|
||||||
Constraint::Percentage(30),
|
Constraint::Percentage(30),
|
||||||
Constraint::Percentage(70)
|
Constraint::Percentage(70),
|
||||||
])
|
])
|
||||||
.split(area)
|
.split(area)
|
||||||
}
|
}
|
||||||
@ -139,6 +170,8 @@ impl RenderLayoutKind {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn generate(&self) -> RenderLayout {
|
pub fn generate(&self) -> RenderLayout {
|
||||||
|
match self {
|
||||||
|
RenderLayoutKind::CliVertical => {
|
||||||
RenderLayout {
|
RenderLayout {
|
||||||
kind: self.clone(),
|
kind: self.clone(),
|
||||||
panes: vec![
|
panes: vec![
|
||||||
@ -148,16 +181,50 @@ impl RenderLayoutKind {
|
|||||||
buffer: RenderBuffer::List{
|
buffer: RenderBuffer::List{
|
||||||
list: vec![String::new()],
|
list: vec![String::new()],
|
||||||
index: 0
|
index: 0
|
||||||
}
|
},
|
||||||
|
focused: true,
|
||||||
|
scroll: 0,
|
||||||
|
max_scroll: 0,
|
||||||
},
|
},
|
||||||
Pane {
|
Pane {
|
||||||
title: Some(" Output Pane ".to_string()),
|
title: Some(" Output Pane ".to_string()),
|
||||||
target: RenderPane::CliOutput,
|
target: RenderPane::CliOutput,
|
||||||
buffer: RenderBuffer::String(String::new()),
|
buffer: RenderBuffer::String(String::new()),
|
||||||
}
|
focused: false,
|
||||||
|
scroll: 0,
|
||||||
|
max_scroll: 0,
|
||||||
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
RenderLayoutKind::CliHorizontal => {
|
||||||
|
RenderLayout {
|
||||||
|
kind: self.clone(),
|
||||||
|
panes: vec![
|
||||||
|
Pane {
|
||||||
|
title: Some(" Output Pane ".to_string()),
|
||||||
|
target: RenderPane::CliOutput,
|
||||||
|
buffer: RenderBuffer::String(String::new()),
|
||||||
|
focused: false,
|
||||||
|
scroll: 0,
|
||||||
|
max_scroll: 0,
|
||||||
|
},
|
||||||
|
Pane {
|
||||||
|
title: Some(" Input Pane ".to_string()),
|
||||||
|
target: RenderPane::CliInput,
|
||||||
|
buffer: RenderBuffer::List{
|
||||||
|
list: vec![String::new()],
|
||||||
|
index: 0
|
||||||
|
},
|
||||||
|
focused: true,
|
||||||
|
scroll: 0,
|
||||||
|
max_scroll: 0,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
@ -174,10 +241,22 @@ impl Renderer {
|
|||||||
self.log(msg!(INFO, "Started Renderer"));
|
self.log(msg!(INFO, "Started Renderer"));
|
||||||
let mut rx = subscribe_render_event();
|
let mut rx = subscribe_render_event();
|
||||||
let mut terminal = ratatui::init();
|
let mut terminal = ratatui::init();
|
||||||
|
publish_system_event(SystemEvent::RendererStarted);
|
||||||
|
|
||||||
|
let mut render_interval = interval(Duration::from_millis(32)); // 60 FPS
|
||||||
|
|
||||||
while !self.exit {
|
while !self.exit {
|
||||||
|
tokio::select! {
|
||||||
|
_ = render_interval.tick() => {
|
||||||
terminal.draw(|frame| self.draw(frame))?;
|
terminal.draw(|frame| self.draw(frame))?;
|
||||||
if let Ok(mes) = self.listen(&mut rx).await {
|
}
|
||||||
self.apply(mes);
|
mes = rx.recv() => {
|
||||||
|
if let Ok(mes) = mes {
|
||||||
|
let frame = terminal.get_frame();
|
||||||
|
let rects = self.layout.kind.rects(frame.area());
|
||||||
|
self.apply(mes, rects);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ratatui::restore();
|
ratatui::restore();
|
||||||
@ -188,7 +267,7 @@ impl Renderer {
|
|||||||
self.buffer.push_str(&msg)
|
self.buffer.push_str(&msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw(&self, frame: &mut Frame) {
|
pub fn draw(&mut self, frame: &mut Frame) {
|
||||||
frame.render_widget(self, frame.area());
|
frame.render_widget(self, frame.area());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,10 +284,41 @@ impl Renderer {
|
|||||||
self.layout.panes.iter_mut().find(|p| p.target == RenderPane::CliInput)
|
self.layout.panes.iter_mut().find(|p| p.target == RenderPane::CliInput)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn apply(&mut self, mes: RenderCommand) {
|
fn focused(&mut self) -> Option<&mut Pane> {
|
||||||
|
self.layout.panes.iter_mut().find(|p| p.focused == true)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_mouse_click_left(&mut self, x: u16, y: u16, rects: std::rc::Rc<[Rect]>) {
|
||||||
|
for (i, r) in rects.iter().enumerate() {
|
||||||
|
if r.contains(layout::Position{x, y}) {
|
||||||
|
self.layout.panes[i].focused = true;
|
||||||
|
} else {
|
||||||
|
self.layout.panes[i].focused = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn apply(&mut self, mes: RenderCommand, rects: std::rc::Rc<[Rect]>) {
|
||||||
match mes {
|
match mes {
|
||||||
|
RenderCommand::MouseClickLeft(x, y) => {
|
||||||
|
self.handle_mouse_click_left(x, y, rects);
|
||||||
|
}
|
||||||
|
RenderCommand::MouseScrollUp => {
|
||||||
|
if let Some(p) = self.focused() {
|
||||||
|
if p.scroll < p.max_scroll {
|
||||||
|
p.scroll += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RenderCommand::MouseScrollDown => {
|
||||||
|
if let Some(p) = self.focused() {
|
||||||
|
if p.scroll > i16::MIN {
|
||||||
|
p.scroll -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
RenderCommand::RenderInput(k) => {
|
RenderCommand::RenderInput(k) => {
|
||||||
if let Some(p) = self.input_pane() {
|
if let Some(p) = self.layout.panes.iter_mut().find(|p| p.focused) {
|
||||||
match k {
|
match k {
|
||||||
KeyCode::Char(c) => {
|
KeyCode::Char(c) => {
|
||||||
if let RenderBuffer::List{list, index} = &mut p.buffer {
|
if let RenderBuffer::List{list, index} = &mut p.buffer {
|
||||||
@ -258,12 +368,8 @@ impl Renderer {
|
|||||||
self.exit();
|
self.exit();
|
||||||
}
|
}
|
||||||
RenderCommand::ChangeLayout(l) => {
|
RenderCommand::ChangeLayout(l) => {
|
||||||
match l {
|
|
||||||
RenderLayoutKind::Cli => {
|
|
||||||
self.layout = l.generate();
|
self.layout = l.generate();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
RenderCommand::ClearPane(pane) => {
|
RenderCommand::ClearPane(pane) => {
|
||||||
if matches!(pane, RenderPane::All) {
|
if matches!(pane, RenderPane::All) {
|
||||||
for p in self.layout.panes.iter_mut() {
|
for p in self.layout.panes.iter_mut() {
|
||||||
@ -298,13 +404,12 @@ impl Renderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Widget for &Renderer {
|
impl Widget for &mut Renderer {
|
||||||
fn render(self, area: Rect, buf: &mut Buffer) {
|
fn render(self, area: Rect, buf: &mut Buffer) {
|
||||||
|
|
||||||
let layout = self.layout.kind.rects(area);
|
let rects = self.layout.kind.rects(area);
|
||||||
|
for (i, p) in self.layout.panes.iter_mut().enumerate() {
|
||||||
for (i, p) in self.layout.panes.iter().enumerate() {
|
p.render(rects[i], buf)
|
||||||
p.render(layout[i], buf)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
use crossterm::event::{self, Event, KeyCode, KeyEventKind};
|
use crossterm::event::{self, Event, KeyCode, KeyEventKind, MouseButton, MouseEventKind};
|
||||||
use memory_stats::memory_stats;
|
use memory_stats::memory_stats;
|
||||||
use tokio::sync::mpsc;
|
use tokio::sync::mpsc;
|
||||||
use std::{io::{self, Write}, net::SocketAddr, time::Duration};
|
use std::{io::{self, Write}, net::SocketAddr, time::Duration};
|
||||||
|
|
||||||
use crate::{event_bus::NetworkEvent, native_node::node::{NativeNode, NodeCommand}};
|
use crate::{error::print_error_chain, event_bus::{subscribe_system_event, NetworkEvent, SystemEvent}, native_node::node::{NativeNode, NodeCommand}};
|
||||||
use vlogger::*;
|
use vlogger::*;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
@ -67,6 +67,21 @@ impl Watcher {
|
|||||||
|
|
||||||
pub async fn poll(&mut self) -> io::Result<bool> {
|
pub async fn poll(&mut self) -> io::Result<bool> {
|
||||||
match event::read()? {
|
match event::read()? {
|
||||||
|
Event::Mouse(event) => {
|
||||||
|
match event.kind {
|
||||||
|
MouseEventKind::ScrollUp => { publish_render_event(RenderCommand::MouseScrollUp); }
|
||||||
|
MouseEventKind::ScrollDown => { publish_render_event(RenderCommand::MouseScrollDown); }
|
||||||
|
MouseEventKind::Down(b) => {
|
||||||
|
match b {
|
||||||
|
MouseButton::Left => {
|
||||||
|
publish_render_event(RenderCommand::MouseClickLeft(event.column, event.row));
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
Event::Key(k) if k.kind == KeyEventKind::Press => {
|
Event::Key(k) if k.kind == KeyEventKind::Press => {
|
||||||
match k.code {
|
match k.code {
|
||||||
KeyCode::Char(c) => {
|
KeyCode::Char(c) => {
|
||||||
@ -167,31 +182,34 @@ impl WatcherBuilder {
|
|||||||
pub async fn start(mut self) -> Watcher {
|
pub async fn start(mut self) -> Watcher {
|
||||||
let (parser_tx, parser_rx) = mpsc::channel::<ParserCommand>(100);
|
let (parser_tx, parser_rx) = mpsc::channel::<ParserCommand>(100);
|
||||||
let (exec_tx, exec_rx) = mpsc::channel::<ExecutorCommand>(100);
|
let (exec_tx, exec_rx) = mpsc::channel::<ExecutorCommand>(100);
|
||||||
|
let mut sys_event = subscribe_system_event();
|
||||||
|
|
||||||
if self.debug {
|
if self.debug {
|
||||||
Watcher::log_memory().await;
|
Watcher::log_memory().await;
|
||||||
}
|
}
|
||||||
|
|
||||||
let render_handle = if self.render {
|
let render_handle = if self.render {
|
||||||
Some(tokio::spawn({
|
Some(tokio::spawn({
|
||||||
async move {
|
async move {
|
||||||
let _ = Renderer::new(RenderLayoutKind::Cli).run().await;
|
let _ = Renderer::new(RenderLayoutKind::CliHorizontal).run().await;
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
let blocks = self.seed_file
|
|
||||||
.as_ref()
|
|
||||||
.and_then(|path| std::fs::read_to_string(path).ok())
|
|
||||||
.unwrap_or_default();
|
|
||||||
|
|
||||||
if self.seed {
|
for i in 0..3 {
|
||||||
self.addr = Some(crate::seeds_constants::SEED_NODES[0]);
|
if let Ok(ev) = sys_event.recv().await {
|
||||||
|
match ev {
|
||||||
|
SystemEvent::RendererStarted => {
|
||||||
|
log(msg!(INFO, "Renderer Started"));
|
||||||
|
break;
|
||||||
|
},
|
||||||
|
_ => { log(msg!(WARNING, "Wrong Event: {ev:?}! Retrying... (try {i})")) }
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut node = NativeNode::new(self.addr.clone(), &blocks, exec_tx.clone()).await;
|
|
||||||
log(msg!(INFO, "Build Node"));
|
|
||||||
|
|
||||||
let parser_handle = tokio::spawn({
|
let parser_handle = tokio::spawn({
|
||||||
let exec_tx = exec_tx.clone();
|
let exec_tx = exec_tx.clone();
|
||||||
@ -200,6 +218,28 @@ impl WatcherBuilder {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
log(msg!(DEBUG, "Seed File: {:?}", self.seed_file));
|
||||||
|
let blocks = self.seed_file
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|path| {
|
||||||
|
log(msg!(INFO, "Reading chain data from {path}"));
|
||||||
|
match std::fs::read_to_string(path) {
|
||||||
|
Ok(s) => Some(s),
|
||||||
|
Err(e) => {
|
||||||
|
print_error_chain(e.into());
|
||||||
|
None
|
||||||
|
},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.unwrap_or_default();
|
||||||
|
|
||||||
|
if self.seed {
|
||||||
|
self.addr = Some(crate::seeds_constants::SEED_NODES[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut node = NativeNode::new(self.addr.clone(), &blocks, exec_tx.clone()).await;
|
||||||
|
log(msg!(INFO, "Built Node"));
|
||||||
|
|
||||||
let executor_handle = tokio::spawn({
|
let executor_handle = tokio::spawn({
|
||||||
let node_tx = node.tx();
|
let node_tx = node.tx();
|
||||||
async move {
|
async move {
|
||||||
@ -207,14 +247,37 @@ impl WatcherBuilder {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let node_tx = node.tx();
|
for i in 0..3 {
|
||||||
|
if let Ok(ev) = sys_event.recv().await {
|
||||||
|
match ev {
|
||||||
|
SystemEvent::ExecutorStarted => {
|
||||||
|
log(msg!(INFO, "Executor Started"));
|
||||||
|
break;
|
||||||
|
},
|
||||||
|
_ => { log(msg!(WARNING, "Wrong Event: {ev:?}! Retrying... (try {i})")) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let node_tx = node.tx();
|
||||||
let node_handle = tokio::spawn({
|
let node_handle = tokio::spawn({
|
||||||
async move {
|
async move {
|
||||||
node.run().await;
|
node.run().await;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
for i in 0..3 {
|
||||||
|
if let Ok(ev) = sys_event.recv().await {
|
||||||
|
match ev {
|
||||||
|
SystemEvent::NodeStarted => {
|
||||||
|
log(msg!(INFO, "Executor Started"));
|
||||||
|
break;
|
||||||
|
},
|
||||||
|
_ => { log(msg!(WARNING, "Wrong Event: {ev:?}! Retrying... (try {i})")) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if self.bootstrap {
|
if self.bootstrap {
|
||||||
let exec_tx = exec_tx.clone();
|
let exec_tx = exec_tx.clone();
|
||||||
|
|
||||||
@ -234,7 +297,6 @@ impl WatcherBuilder {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Watcher {
|
Watcher {
|
||||||
node_tx,
|
node_tx,
|
||||||
cmd_history: Vec::new(),
|
cmd_history: Vec::new(),
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user