Compare commits
25 Commits
feature/in
...
feature/ez
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
546a45bb3a | ||
|
|
950a63c103 | ||
|
|
f9c4fce398 | ||
|
|
014462c187 | ||
|
|
b1daec3b84 | ||
|
|
e0c991d0f9 | ||
|
|
a53b5bd94c | ||
|
|
d13df41b82 | ||
|
|
4496a0916b | ||
|
|
f3bea8c62d | ||
|
|
443c4e1dac | ||
|
|
6077c3a519 | ||
|
|
91fbe7f9bd | ||
|
|
4717ffa7e8 | ||
|
|
c3f5b2890b | ||
|
|
9dc515fb78 | ||
|
|
6f756d4fb6 | ||
|
|
5d6a1e806a | ||
|
|
d91a631fdc | ||
|
|
a81d1f913a | ||
|
|
b1f5d2b75a | ||
|
|
95e3127903 | ||
|
|
3f4b4324e5 | ||
|
|
404a769259 | ||
|
|
ff9fbd49ec |
552
Cargo.lock
generated
552
Cargo.lock
generated
@@ -29,15 +29,6 @@ dependencies = [
|
||||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "1.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "android-tzdata"
|
||||
version = "0.1.1"
|
||||
@@ -219,6 +210,17 @@ dependencies = [
|
||||
"rand 0.8.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-channel"
|
||||
version = "1.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35"
|
||||
dependencies = [
|
||||
"concurrent-queue",
|
||||
"event-listener",
|
||||
"futures-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-trait"
|
||||
version = "0.1.80"
|
||||
@@ -230,6 +232,17 @@ dependencies = [
|
||||
"syn 2.0.66",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atomic_enum"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6227a8d6fdb862bcb100c4314d0d9579e5cd73fa6df31a2e6f6e1acd3c5f1207"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "auto_ops"
|
||||
version = "0.3.0"
|
||||
@@ -263,12 +276,6 @@ version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf"
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff"
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.13.1"
|
||||
@@ -500,6 +507,15 @@ dependencies = [
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "concurrent-queue"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973"
|
||||
dependencies = [
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "const-oid"
|
||||
version = "0.9.6"
|
||||
@@ -521,16 +537,6 @@ dependencies = [
|
||||
"unicode-segmentation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation"
|
||||
version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation-sys"
|
||||
version = "0.8.6"
|
||||
@@ -546,6 +552,12 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80"
|
||||
|
||||
[[package]]
|
||||
name = "crypto-bigint"
|
||||
version = "0.5.5"
|
||||
@@ -781,6 +793,20 @@ dependencies = [
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "enfync"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5ce8c1fbec15a38aced3838c4d7ea90a1403bd50364b5cfe8008e679df0c8dde"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"futures",
|
||||
"tokio",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures",
|
||||
"wasmtimer",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.1"
|
||||
@@ -788,14 +814,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.3.9"
|
||||
name = "event-listener"
|
||||
version = "2.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
|
||||
|
||||
[[package]]
|
||||
name = "eyre"
|
||||
@@ -807,6 +829,32 @@ dependencies = [
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ezsockets"
|
||||
version = "0.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "897108017392f356bd207aa417dfeee5e91d1184b81856ddd6850cfc01aa6839"
|
||||
dependencies = [
|
||||
"async-channel",
|
||||
"async-trait",
|
||||
"atomic_enum",
|
||||
"base64 0.21.7",
|
||||
"cfg-if",
|
||||
"enfync",
|
||||
"futures",
|
||||
"futures-util",
|
||||
"getrandom 0.2.15",
|
||||
"http",
|
||||
"tokio",
|
||||
"tokio-tungstenite",
|
||||
"tokio-tungstenite-wasm",
|
||||
"tracing",
|
||||
"tungstenite",
|
||||
"url",
|
||||
"wasm-bindgen-futures",
|
||||
"wasmtimer",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fastcrypto"
|
||||
version = "0.1.8"
|
||||
@@ -871,12 +919,6 @@ dependencies = [
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a"
|
||||
|
||||
[[package]]
|
||||
name = "ff"
|
||||
version = "0.13.0"
|
||||
@@ -887,40 +929,12 @@ dependencies = [
|
||||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "flume"
|
||||
version = "0.10.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1657b4441c3403d9f7b3409e47575237dac27b1b5726df654a6ecbf92f0f7577"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"nanorand",
|
||||
"pin-project",
|
||||
"spin 0.9.8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fnv"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||
|
||||
[[package]]
|
||||
name = "foreign-types"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
|
||||
dependencies = [
|
||||
"foreign-types-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "foreign-types-shared"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
|
||||
|
||||
[[package]]
|
||||
name = "form_urlencoded"
|
||||
version = "1.2.1"
|
||||
@@ -1270,7 +1284,7 @@ version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
dependencies = [
|
||||
"spin 0.5.2",
|
||||
"spin",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1295,12 +1309,6 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.4.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.12"
|
||||
@@ -1344,29 +1352,13 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nanorand"
|
||||
version = "0.7.0"
|
||||
name = "nu-ansi-term"
|
||||
version = "0.46.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3"
|
||||
checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84"
|
||||
dependencies = [
|
||||
"getrandom 0.2.15",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "native-tls"
|
||||
version = "0.2.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
"openssl",
|
||||
"openssl-probe",
|
||||
"openssl-sys",
|
||||
"schannel",
|
||||
"security-framework",
|
||||
"security-framework-sys",
|
||||
"tempfile",
|
||||
"overload",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1463,56 +1455,18 @@ version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381"
|
||||
|
||||
[[package]]
|
||||
name = "openssl"
|
||||
version = "0.10.64"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cfg-if",
|
||||
"foreign-types",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"openssl-macros",
|
||||
"openssl-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openssl-macros"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.66",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openssl-probe"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
|
||||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.9.102"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c597637d56fbc83893a35eb0dd04b2b8e7a50c91e64e9493e398b5df4fb45fa2"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "option-ext"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
|
||||
|
||||
[[package]]
|
||||
name = "overload"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
|
||||
|
||||
[[package]]
|
||||
name = "p256"
|
||||
version = "0.13.2"
|
||||
@@ -1578,26 +1532,6 @@ version = "2.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
|
||||
|
||||
[[package]]
|
||||
name = "pin-project"
|
||||
version = "1.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3"
|
||||
dependencies = [
|
||||
"pin-project-internal",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-internal"
|
||||
version = "1.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.66",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.14"
|
||||
@@ -1642,12 +1576,6 @@ dependencies = [
|
||||
"spki 0.7.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
|
||||
|
||||
[[package]]
|
||||
name = "powerfmt"
|
||||
version = "0.2.0"
|
||||
@@ -1818,35 +1746,6 @@ dependencies = [
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.10.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-automata",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56"
|
||||
|
||||
[[package]]
|
||||
name = "rfc6979"
|
||||
version = "0.4.0"
|
||||
@@ -1893,34 +1792,12 @@ dependencies = [
|
||||
"semver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.38.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
|
||||
|
||||
[[package]]
|
||||
name = "schannel"
|
||||
version = "0.1.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534"
|
||||
dependencies = [
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "schemars"
|
||||
version = "0.8.21"
|
||||
@@ -1985,29 +1862,6 @@ dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "security-framework"
|
||||
version = "2.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c627723fd09706bacdb5cf41499e95098555af3c3c29d014dc3c458ef6be11c0"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"core-foundation",
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
"security-framework-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "security-framework-sys"
|
||||
version = "2.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "317936bbbd05227752583946b9e66d7ce3b489f84e11a94a510b4437fef407d7"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "1.0.23"
|
||||
@@ -2123,19 +1977,6 @@ dependencies = [
|
||||
"syn 2.0.66",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha-1"
|
||||
version = "0.9.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6"
|
||||
dependencies = [
|
||||
"block-buffer 0.9.0",
|
||||
"cfg-if",
|
||||
"cpufeatures",
|
||||
"digest 0.9.0",
|
||||
"opaque-debug",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha1"
|
||||
version = "0.10.6"
|
||||
@@ -2194,15 +2035,26 @@ dependencies = [
|
||||
"keccak",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sharded-slab"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "side-node"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"base64 0.21.7",
|
||||
"bft-crdt-derive",
|
||||
"bft-json-crdt",
|
||||
"clap",
|
||||
"dirs",
|
||||
"ezsockets",
|
||||
"fastcrypto",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@@ -2210,14 +2062,20 @@ dependencies = [
|
||||
"sha256",
|
||||
"tokio",
|
||||
"toml",
|
||||
"websockets",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "side-watcher"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"simple-websockets",
|
||||
"async-trait",
|
||||
"ezsockets",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2239,18 +2097,6 @@ dependencies = [
|
||||
"rand_core 0.6.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "simple-websockets"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f38cc14717bb624d10e9bb4fff30344e8f540c0d2c0f876f8fb0111d808ee7c"
|
||||
dependencies = [
|
||||
"flume",
|
||||
"futures-util",
|
||||
"tokio",
|
||||
"tokio-tungstenite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "slab"
|
||||
version = "0.4.9"
|
||||
@@ -2282,15 +2128,6 @@ version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
version = "0.9.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
|
||||
dependencies = [
|
||||
"lock_api",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spki"
|
||||
version = "0.6.0"
|
||||
@@ -2357,18 +2194,6 @@ dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"fastrand",
|
||||
"rustix",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.61"
|
||||
@@ -2389,6 +2214,16 @@ dependencies = [
|
||||
"syn 2.0.66",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thread_local"
|
||||
version = "1.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "threadpool"
|
||||
version = "1.8.1"
|
||||
@@ -2485,21 +2320,11 @@ dependencies = [
|
||||
"syn 2.0.66",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-native-tls"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2"
|
||||
dependencies = [
|
||||
"native-tls",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-tungstenite"
|
||||
version = "0.19.0"
|
||||
version = "0.20.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec509ac96e9a0c43427c74f003127d953a265737636129424288d27cb5c4b12c"
|
||||
checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c"
|
||||
dependencies = [
|
||||
"futures-util",
|
||||
"log",
|
||||
@@ -2507,6 +2332,24 @@ dependencies = [
|
||||
"tungstenite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-tungstenite-wasm"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5ec8c7cf09b20184f946f114e3d8c0deca34368912c90100812861c14bb63b66"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-util",
|
||||
"http",
|
||||
"httparse",
|
||||
"js-sys",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"tokio-tungstenite",
|
||||
"wasm-bindgen",
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.8.14"
|
||||
@@ -2553,10 +2396,67 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tungstenite"
|
||||
version = "0.19.0"
|
||||
name = "tracing"
|
||||
version = "0.1.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "15fba1a6d6bb030745759a9a2a588bfe8490fc8b4751a277db3a0be1c9ebbf67"
|
||||
checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef"
|
||||
dependencies = [
|
||||
"pin-project-lite",
|
||||
"tracing-attributes",
|
||||
"tracing-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-attributes"
|
||||
version = "0.1.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.66",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-core"
|
||||
version = "0.1.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"valuable",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-log"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3"
|
||||
dependencies = [
|
||||
"log",
|
||||
"once_cell",
|
||||
"tracing-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-subscriber"
|
||||
version = "0.3.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b"
|
||||
dependencies = [
|
||||
"nu-ansi-term",
|
||||
"sharded-slab",
|
||||
"smallvec",
|
||||
"thread_local",
|
||||
"tracing-core",
|
||||
"tracing-log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tungstenite"
|
||||
version = "0.20.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9e3dac10fd62eaf6617d3a904ae222845979aec67c615d1c842b4002c7666fb9"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"bytes",
|
||||
@@ -2628,10 +2528,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
|
||||
|
||||
[[package]]
|
||||
name = "vcpkg"
|
||||
version = "0.2.15"
|
||||
name = "valuable"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
||||
checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
@@ -2682,6 +2582,18 @@ dependencies = [
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-futures"
|
||||
version = "0.4.42"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.92"
|
||||
@@ -2712,23 +2624,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96"
|
||||
|
||||
[[package]]
|
||||
name = "websockets"
|
||||
version = "0.3.0"
|
||||
name = "wasmtimer"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "67db5ecf42b65ca21f25689299cc05e216739bbc4fdeeaf598322a1aec34a8d7"
|
||||
checksum = "5f656cd8858a5164932d8a90f936700860976ec21eb00e0fe2aa8cab13f6b4cf"
|
||||
dependencies = [
|
||||
"base64 0.12.3",
|
||||
"flume",
|
||||
"futures",
|
||||
"native-tls",
|
||||
"rand 0.7.3",
|
||||
"rand_chacha 0.2.2",
|
||||
"regex",
|
||||
"sha-1",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"tokio-native-tls",
|
||||
"url",
|
||||
"js-sys",
|
||||
"parking_lot",
|
||||
"pin-utils",
|
||||
"slab",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.69"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
@@ -6,20 +6,25 @@ edition = "2021"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
async-trait = "0.1.52"
|
||||
base64 = "0.21.7"
|
||||
bft-json-crdt = { path = "../crates/bft-json-crdt" }
|
||||
bft-crdt-derive = { path = "../crates/bft-json-crdt/bft-crdt-derive" }
|
||||
clap = { version = "4.5.4", features = ["derive"] }
|
||||
dirs = "5.0.1"
|
||||
ezsockets = { version = "*", features = ["client"] }
|
||||
fastcrypto = "0.1.8"
|
||||
# serde_cbor = "0.11.2" # move to this once we need to pack things in CBOR
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0.117"
|
||||
serde_with = "3.8.1"
|
||||
sha256 = "1.5.0"
|
||||
tokio = { version = "1.37.0", features = ["full"] }
|
||||
websockets = "0.3.0"
|
||||
tracing = "0.1.32"
|
||||
tracing-subscriber = "0.3.9"
|
||||
toml = "0.8.14"
|
||||
fastcrypto = "0.1.8"
|
||||
url = "2.2.2"
|
||||
|
||||
|
||||
[features]
|
||||
default = ["bft", "logging-list", "logging-json"]
|
||||
|
||||
34
side-node/src/crdt.rs
Normal file
34
side-node/src/crdt.rs
Normal file
@@ -0,0 +1,34 @@
|
||||
use bft_crdt_derive::add_crdt_fields;
|
||||
use bft_json_crdt::{
|
||||
json_crdt::{CrdtNode, IntoCrdtNode},
|
||||
list_crdt::ListCrdt,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[add_crdt_fields]
|
||||
#[derive(Clone, CrdtNode, Serialize, Deserialize)]
|
||||
pub(crate) struct TransactionList {
|
||||
pub(crate) list: ListCrdt<Transaction>,
|
||||
}
|
||||
|
||||
/// A fake Transaction struct we can use as a simulated payload
|
||||
#[add_crdt_fields]
|
||||
#[derive(Clone, CrdtNode, Serialize, Deserialize)]
|
||||
pub(crate) struct Transaction {
|
||||
from: String,
|
||||
to: String,
|
||||
amount: f64,
|
||||
}
|
||||
|
||||
// impl TransactionList {
|
||||
// fn create(&mut self, keys: &Ed25519KeyPair) -> bft_json_crdt::json_crdt::SignedOp {
|
||||
// // generate a placeholder transaction
|
||||
// let transaction = _fake_transaction(keys.public().to_string());
|
||||
|
||||
// // next job is to keep adding to this guy
|
||||
// let last: &Op<Transaction>;
|
||||
// last = self.list.ops.last().expect("couldn't find last op");
|
||||
// let signed_op = self.list.insert(last.id, transaction.clone()).sign(&keys);
|
||||
// signed_op
|
||||
// }
|
||||
// }
|
||||
@@ -10,7 +10,7 @@ pub(crate) struct SideNodeConfig {
|
||||
pub(crate) name: String,
|
||||
}
|
||||
|
||||
pub(crate) fn write(
|
||||
pub(crate) fn write_toml(
|
||||
config: &SideNodeConfig,
|
||||
file_path: &PathBuf,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
|
||||
@@ -14,7 +14,7 @@ pub(crate) fn init(home: PathBuf, config: SideNodeConfig) -> Result<(), std::io:
|
||||
keys::write(key_path)?;
|
||||
|
||||
println!("Writing config to: {:?}", config_path);
|
||||
config::write(&config, &config_path).expect("unable to write config file");
|
||||
config::write_toml(&config, &config_path).expect("unable to write config file");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use bft_crdt_derive::add_crdt_fields;
|
||||
|
||||
use bft_json_crdt::{
|
||||
json_crdt::{BaseCrdt, CrdtNode, IntoCrdtNode},
|
||||
keypair::{Ed25519KeyPair, KeyPair},
|
||||
list_crdt::ListCrdt,
|
||||
};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::{json, Value};
|
||||
use websockets::WebSocket;
|
||||
|
||||
use crate::keys;
|
||||
|
||||
#[add_crdt_fields]
|
||||
#[derive(Clone, CrdtNode, Serialize, Deserialize)]
|
||||
pub(crate) struct CrdtList {
|
||||
pub(crate) list: ListCrdt<Transaction>, // switch to Transaction as soon as char is working
|
||||
}
|
||||
|
||||
/// A fake Transaction struct we can use as a simulated payload
|
||||
#[add_crdt_fields]
|
||||
#[derive(Clone, CrdtNode, Serialize, Deserialize)]
|
||||
pub(crate) struct Transaction {
|
||||
from: String,
|
||||
to: String,
|
||||
amount: f64,
|
||||
}
|
||||
|
||||
pub(crate) fn new(side_dir: PathBuf) -> (BaseCrdt<CrdtList>, Ed25519KeyPair) {
|
||||
let keys = keys::load_from_file(side_dir);
|
||||
let bft_crdt = BaseCrdt::<CrdtList>::new(&keys);
|
||||
println!("Author is {}", keys.public().to_string());
|
||||
(bft_crdt, keys)
|
||||
}
|
||||
|
||||
pub(crate) async fn send(
|
||||
count: u32,
|
||||
bft_crdt: &mut BaseCrdt<CrdtList>,
|
||||
ws: &mut WebSocket,
|
||||
keys: &Ed25519KeyPair,
|
||||
) -> Result<(), websockets::WebSocketError> {
|
||||
// generate a placeholder transaction
|
||||
let transaction = generate_transaction(count, keys.public().to_string());
|
||||
|
||||
// next job is to keep adding to this guy
|
||||
let next = bft_crdt.doc.list.ops.len();
|
||||
let signed_op = bft_crdt
|
||||
.doc
|
||||
.list
|
||||
.insert_idx(next - 1, transaction.clone())
|
||||
.sign(&keys);
|
||||
|
||||
Ok(ws
|
||||
.send_text(serde_json::to_string(&signed_op).unwrap())
|
||||
.await?)
|
||||
}
|
||||
|
||||
fn generate_transaction(count: u32, pubkey: String) -> Value {
|
||||
json!({
|
||||
"from": pubkey,
|
||||
"to": "Bob",
|
||||
"amount": count
|
||||
})
|
||||
}
|
||||
@@ -1,9 +1,16 @@
|
||||
use bft_json_crdt::json_crdt::{BaseCrdt, SignedOp};
|
||||
use cli::{parse_args, Commands};
|
||||
use crdt::TransactionList;
|
||||
use node::SideNode;
|
||||
use tokio::{sync::mpsc, task};
|
||||
use websocket::WebSocketClient;
|
||||
|
||||
pub(crate) mod cli;
|
||||
pub(crate) mod crdt;
|
||||
pub(crate) mod init;
|
||||
pub(crate) mod keys;
|
||||
pub(crate) mod list_transaction_crdt;
|
||||
pub(crate) mod node;
|
||||
pub(crate) mod stdin;
|
||||
pub(crate) mod utils;
|
||||
pub(crate) mod websocket;
|
||||
|
||||
@@ -17,20 +24,33 @@ async fn main() {
|
||||
name: name.to_string(),
|
||||
};
|
||||
|
||||
let _ = init::init(home(name), config);
|
||||
let _ = init::init(utils::home(name), config);
|
||||
}
|
||||
Some(Commands::Run { name }) => {
|
||||
let side_dir = home(name);
|
||||
let (mut bft_crdt, keys) = list_transaction_crdt::new(side_dir);
|
||||
websocket::start(keys, &mut bft_crdt).await.unwrap();
|
||||
let mut node = setup(name).await;
|
||||
node.start().await;
|
||||
}
|
||||
None => println!("No command provided. Exiting. See --help for more information."),
|
||||
}
|
||||
}
|
||||
|
||||
fn home(name: &String) -> std::path::PathBuf {
|
||||
let mut path = dirs::home_dir().unwrap();
|
||||
path.push(".side");
|
||||
path.push(name);
|
||||
path
|
||||
/// Wire everything up outside the application so we can test more easily later
|
||||
async fn setup(name: &String) -> SideNode {
|
||||
// First, load up the keys and create a bft-crdt
|
||||
let side_dir = utils::home(name);
|
||||
let keys = keys::load_from_file(side_dir);
|
||||
let crdt = BaseCrdt::<TransactionList>::new(&keys);
|
||||
|
||||
// Channels for internal communication, and a tokio task for stdin input
|
||||
let (incoming_sender, incoming_receiver) = mpsc::channel::<SignedOp>(32);
|
||||
let (stdin_sender, stdin_receiver) = std::sync::mpsc::channel();
|
||||
task::spawn(async move {
|
||||
stdin::input(stdin_sender);
|
||||
});
|
||||
|
||||
// Finally, create the node and return it
|
||||
let handle = WebSocketClient::new(incoming_sender).await;
|
||||
let node = SideNode::new(crdt, keys, incoming_receiver, stdin_receiver, handle);
|
||||
println!("Node setup complete.");
|
||||
node
|
||||
}
|
||||
|
||||
91
side-node/src/node.rs
Normal file
91
side-node/src/node.rs
Normal file
@@ -0,0 +1,91 @@
|
||||
use bft_json_crdt::json_crdt::{BaseCrdt, SignedOp};
|
||||
use fastcrypto::ed25519::Ed25519KeyPair;
|
||||
use tokio::sync::mpsc;
|
||||
|
||||
use crate::{crdt::TransactionList, utils, websocket::WebSocketClient};
|
||||
|
||||
pub(crate) struct SideNode {
|
||||
crdt: BaseCrdt<TransactionList>,
|
||||
keys: fastcrypto::ed25519::Ed25519KeyPair,
|
||||
incoming_receiver: mpsc::Receiver<SignedOp>,
|
||||
stdin_receiver: std::sync::mpsc::Receiver<String>,
|
||||
handle: ezsockets::Client<WebSocketClient>,
|
||||
}
|
||||
|
||||
impl SideNode {
|
||||
pub(crate) fn new(
|
||||
crdt: BaseCrdt<TransactionList>,
|
||||
keys: Ed25519KeyPair,
|
||||
incoming_receiver: mpsc::Receiver<SignedOp>,
|
||||
stdin_receiver: std::sync::mpsc::Receiver<String>,
|
||||
handle: ezsockets::Client<WebSocketClient>,
|
||||
) -> Self {
|
||||
let node = Self {
|
||||
crdt,
|
||||
keys,
|
||||
incoming_receiver,
|
||||
stdin_receiver,
|
||||
handle,
|
||||
};
|
||||
node
|
||||
}
|
||||
|
||||
pub(crate) async fn start(&mut self) {
|
||||
println!("Starting node...");
|
||||
|
||||
loop {
|
||||
match self.stdin_receiver.try_recv() {
|
||||
Ok(stdin) => {
|
||||
println!("Received stdin input: {:?}", stdin);
|
||||
let transaction = utils::fake_transaction(stdin);
|
||||
let json = serde_json::to_value(transaction).unwrap();
|
||||
let signed_op = self.add_transaction_local(json);
|
||||
self.send_to_network(signed_op).await;
|
||||
}
|
||||
Err(_) => {} // ignore empty channel errors in this PoC
|
||||
}
|
||||
match self.incoming_receiver.try_recv() {
|
||||
Ok(incoming) => {
|
||||
self.handle_incoming(&incoming);
|
||||
}
|
||||
Err(_) => {} // ignore empty channel errors in this PoC
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn send_to_network(&self, signed_op: SignedOp) {
|
||||
println!("sending to network: {:?}", signed_op);
|
||||
let to_send = serde_json::to_string(&signed_op).unwrap();
|
||||
self.handle.call(to_send).unwrap();
|
||||
}
|
||||
|
||||
fn handle_incoming(&mut self, incoming: &SignedOp) {
|
||||
println!("WINNNINGINGINGINGINGIGNIGN");
|
||||
self.crdt.apply(incoming.clone());
|
||||
}
|
||||
|
||||
pub(crate) fn add_transaction_local(
|
||||
&mut self,
|
||||
transaction: serde_json::Value,
|
||||
) -> bft_json_crdt::json_crdt::SignedOp {
|
||||
let last = self
|
||||
.crdt
|
||||
.doc
|
||||
.list
|
||||
.ops
|
||||
.last()
|
||||
.expect("couldn't find last op");
|
||||
let signed_op = self
|
||||
.crdt
|
||||
.doc
|
||||
.list
|
||||
.insert(last.id, transaction)
|
||||
.sign(&self.keys);
|
||||
signed_op
|
||||
}
|
||||
|
||||
/// Print the current state of the CRDT, can be used to debug
|
||||
pub(crate) fn _trace_crdt(&self) {
|
||||
println!("{:?}", self.crdt.doc.list);
|
||||
}
|
||||
}
|
||||
12
side-node/src/stdin.rs
Normal file
12
side-node/src/stdin.rs
Normal file
@@ -0,0 +1,12 @@
|
||||
use std::io::BufRead;
|
||||
|
||||
/// Wait for stdin terminal input and send it to the node if any arrives
|
||||
pub(crate) fn input(stdin_sender: std::sync::mpsc::Sender<String>) {
|
||||
let stdin = std::io::stdin();
|
||||
let lines = stdin.lock().lines();
|
||||
for line in lines {
|
||||
println!("We're in stdin_input");
|
||||
let line = line.unwrap();
|
||||
stdin_sender.send(line).unwrap();
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,11 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use serde_json::{json, Value};
|
||||
|
||||
pub(crate) const KEY_FILE: &str = "keys.pem";
|
||||
pub(crate) const CONFIG_FILE: &str = "config.toml";
|
||||
|
||||
/// Returns the path to the key file for this host OS.
|
||||
/// Returns the path to the key file and config for this host OS.
|
||||
pub(crate) fn side_paths(prefix: PathBuf) -> (PathBuf, PathBuf) {
|
||||
let mut key_path = prefix.clone();
|
||||
key_path.push(KEY_FILE);
|
||||
@@ -13,3 +15,19 @@ pub(crate) fn side_paths(prefix: PathBuf) -> (PathBuf, PathBuf) {
|
||||
|
||||
(key_path, config_path)
|
||||
}
|
||||
|
||||
pub(crate) fn home(name: &String) -> std::path::PathBuf {
|
||||
let mut path = dirs::home_dir().unwrap();
|
||||
path.push(".side");
|
||||
path.push(name);
|
||||
path
|
||||
}
|
||||
|
||||
/// Generate a fake transaction with customizable from_pubkey String
|
||||
pub(crate) fn fake_transaction(from_pubkey: String) -> Value {
|
||||
json!({
|
||||
"from": from_pubkey,
|
||||
"to": "Bob",
|
||||
"amount": 1
|
||||
})
|
||||
}
|
||||
|
||||
57
side-node/src/websocket.rs
Normal file
57
side-node/src/websocket.rs
Normal file
@@ -0,0 +1,57 @@
|
||||
use async_trait::async_trait;
|
||||
use bft_json_crdt::json_crdt::SignedOp;
|
||||
use ezsockets::ClientConfig;
|
||||
use tokio::sync::mpsc;
|
||||
|
||||
pub(crate) struct WebSocketClient {
|
||||
incoming_sender: mpsc::Sender<SignedOp>,
|
||||
handle: ezsockets::Client<WebSocketClient>,
|
||||
}
|
||||
|
||||
impl WebSocketClient {
|
||||
/// Start the websocket client
|
||||
pub(crate) async fn new(
|
||||
incoming_sender: mpsc::Sender<SignedOp>,
|
||||
) -> ezsockets::Client<WebSocketClient> {
|
||||
tracing_subscriber::fmt::init();
|
||||
let config = ClientConfig::new("ws://localhost:8080/websocket");
|
||||
let (handle, future) = ezsockets::connect(
|
||||
|client| WebSocketClient {
|
||||
incoming_sender,
|
||||
handle: client,
|
||||
},
|
||||
config,
|
||||
)
|
||||
.await;
|
||||
tokio::spawn(async move {
|
||||
future.await.unwrap();
|
||||
});
|
||||
handle
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl ezsockets::ClientExt for WebSocketClient {
|
||||
// Right now we're only using the Call type for sending signed ops
|
||||
// change this to an enum if we need to send other types of calls, and
|
||||
// match on it.
|
||||
type Call = String;
|
||||
|
||||
async fn on_text(&mut self, text: String) -> Result<(), ezsockets::Error> {
|
||||
tracing::info!("received text: {text:?}");
|
||||
let incoming: bft_json_crdt::json_crdt::SignedOp = serde_json::from_str(&text).unwrap();
|
||||
self.incoming_sender.send(incoming).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn on_binary(&mut self, bytes: Vec<u8>) -> Result<(), ezsockets::Error> {
|
||||
tracing::info!("received bytes: {bytes:?}");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn on_call(&mut self, call: Self::Call) -> Result<(), ezsockets::Error> {
|
||||
tracing::info!("sending signed op: {call:?}");
|
||||
self.handle.text(call)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
use crate::list_transaction_crdt::{self, CrdtList};
|
||||
use base64::{engine::general_purpose, Engine as _};
|
||||
use bft_json_crdt::json_crdt::BaseCrdt;
|
||||
use bft_json_crdt::json_crdt::SignedOp;
|
||||
use bft_json_crdt::keypair::Ed25519KeyPair;
|
||||
use tokio::time;
|
||||
use websockets::WebSocket;
|
||||
/// Starts a websocket and periodically sends a BFT-CRDT message to the websocket server
|
||||
pub(crate) async fn start(
|
||||
keys: Ed25519KeyPair,
|
||||
bft_crdt: &mut BaseCrdt<CrdtList>,
|
||||
) -> Result<(), websockets::WebSocketError> {
|
||||
println!("connecting to websocket at ws://127.0.0.1:8080/");
|
||||
let mut ws = WebSocket::connect("ws://127.0.0.1:8080/").await?;
|
||||
|
||||
let mut interval = every_ten_seconds();
|
||||
let mut count = 0;
|
||||
loop {
|
||||
let _ = list_transaction_crdt::send(count, bft_crdt, &mut ws, &keys).await;
|
||||
|
||||
let msg = ws.receive().await?;
|
||||
|
||||
// deserialize the received websocket Frame into a string
|
||||
let msg = msg.into_text().unwrap().0;
|
||||
|
||||
// deserialize the message into a Transaction struct
|
||||
let incoming_operation: SignedOp = serde_json::from_str(&msg).unwrap();
|
||||
|
||||
let author = general_purpose::STANDARD.encode(&incoming_operation.author());
|
||||
println!("Received from {:?}", author);
|
||||
|
||||
bft_crdt.apply(incoming_operation.clone());
|
||||
|
||||
count = count + 1;
|
||||
interval.tick().await;
|
||||
}
|
||||
}
|
||||
|
||||
fn every_ten_seconds() -> time::Interval {
|
||||
time::interval(time::Duration::from_secs(10))
|
||||
}
|
||||
@@ -6,4 +6,8 @@ edition = "2021"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
simple-websockets = "0.1.6"
|
||||
async-trait = "0.1.52"
|
||||
ezsockets = { version = "*", features = ["tungstenite"] }
|
||||
tokio = { version = "1.17.0", features = ["full"] }
|
||||
tracing = "0.1.32"
|
||||
tracing-subscriber = "0.3.9"
|
||||
|
||||
@@ -1,34 +1,197 @@
|
||||
use simple_websockets::{Event, Responder};
|
||||
use async_trait::async_trait;
|
||||
use ezsockets::CloseFrame;
|
||||
use ezsockets::Error;
|
||||
use ezsockets::Server;
|
||||
use std::collections::HashMap;
|
||||
use std::net::SocketAddr;
|
||||
|
||||
fn main() {
|
||||
let event_hub = simple_websockets::launch(8080).expect("failed to listen on port 8080");
|
||||
let mut clients: HashMap<u64, Responder> = HashMap::new();
|
||||
println!("Listening for websocket connection...");
|
||||
loop {
|
||||
match event_hub.poll_event() {
|
||||
Event::Connect(client_id, responder) => {
|
||||
println!("A client connected with id #{}", client_id);
|
||||
// add their Responder to our `clients` map:
|
||||
clients.insert(client_id, responder);
|
||||
}
|
||||
Event::Disconnect(client_id) => {
|
||||
println!("Client #{} disconnected.", client_id);
|
||||
// remove the disconnected client from the clients map:
|
||||
clients.remove(&client_id);
|
||||
}
|
||||
Event::Message(client_id, message) => {
|
||||
println!("\nReceived a message from client #{}", client_id);
|
||||
const DEFAULT_ROOM: &str = "main";
|
||||
|
||||
let all_clients = clients.keys().collect::<Vec<_>>();
|
||||
for client in all_clients {
|
||||
if *client != client_id {
|
||||
println!("Sending message to client #{}", client);
|
||||
let responder = clients.get(client).unwrap();
|
||||
responder.send(message.clone());
|
||||
}
|
||||
type SessionID = u8;
|
||||
type Session = ezsockets::Session<SessionID, ()>;
|
||||
|
||||
#[derive(Debug)]
|
||||
enum Message {
|
||||
Join {
|
||||
id: SessionID,
|
||||
room: String,
|
||||
},
|
||||
Send {
|
||||
from: SessionID,
|
||||
room: String,
|
||||
text: String,
|
||||
},
|
||||
}
|
||||
|
||||
struct ChatServer {
|
||||
sessions: HashMap<SessionID, Session>,
|
||||
rooms: HashMap<String, Vec<SessionID>>,
|
||||
handle: Server<Self>,
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl ezsockets::ServerExt for ChatServer {
|
||||
type Call = Message;
|
||||
type Session = SessionActor;
|
||||
|
||||
async fn on_connect(
|
||||
&mut self,
|
||||
socket: ezsockets::Socket,
|
||||
_request: ezsockets::Request,
|
||||
_address: SocketAddr,
|
||||
) -> Result<Session, Option<CloseFrame>> {
|
||||
let id = (0..).find(|i| !self.sessions.contains_key(i)).unwrap_or(0);
|
||||
let session = Session::create(
|
||||
|session_handle| SessionActor {
|
||||
id,
|
||||
server: self.handle.clone(),
|
||||
session: session_handle,
|
||||
room: DEFAULT_ROOM.to_string(),
|
||||
},
|
||||
id,
|
||||
socket,
|
||||
);
|
||||
self.sessions.insert(id, session.clone());
|
||||
self.rooms.get_mut(DEFAULT_ROOM).unwrap().push(id);
|
||||
Ok(session)
|
||||
}
|
||||
|
||||
async fn on_disconnect(
|
||||
&mut self,
|
||||
id: <Self::Session as ezsockets::SessionExt>::ID,
|
||||
_reason: Result<Option<CloseFrame>, Error>,
|
||||
) -> Result<(), Error> {
|
||||
assert!(self.sessions.remove(&id).is_some());
|
||||
|
||||
let (ids, n) = self
|
||||
.rooms
|
||||
.values_mut()
|
||||
.find_map(|ids| ids.iter().position(|v| id == *v).map(|n| (ids, n)))
|
||||
.expect("could not find session in any room");
|
||||
ids.remove(n);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn on_call(&mut self, call: Self::Call) -> Result<(), Error> {
|
||||
match call {
|
||||
Message::Send { from, room, text } => {
|
||||
let (ids, sessions): (Vec<SessionID>, Vec<&Session>) = self
|
||||
.rooms
|
||||
.get(&room)
|
||||
.unwrap()
|
||||
.iter()
|
||||
.filter(|id| **id != from)
|
||||
.map(|id| (id, self.sessions.get(id).unwrap()))
|
||||
.unzip();
|
||||
|
||||
tracing::info!(
|
||||
"sending {text} to [{sessions}] at `{room}`",
|
||||
sessions = ids
|
||||
.iter()
|
||||
.map(|id| id.to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join(",")
|
||||
);
|
||||
for session in sessions {
|
||||
session.text(text.clone()).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
Message::Join { id, room } => {
|
||||
let (ids, n) = self
|
||||
.rooms
|
||||
.values_mut()
|
||||
.find_map(|ids| ids.iter().position(|v| id == *v).map(|n| (ids, n)))
|
||||
.expect("could not find session in any room");
|
||||
ids.remove(n);
|
||||
if let Some(ids) = self.rooms.get_mut(&room) {
|
||||
ids.push(id);
|
||||
} else {
|
||||
self.rooms.insert(room.clone(), vec![id]);
|
||||
}
|
||||
|
||||
let sessions = self
|
||||
.rooms
|
||||
.get(&room)
|
||||
.unwrap()
|
||||
.iter()
|
||||
.map(|id| self.sessions.get(id).unwrap());
|
||||
|
||||
for session in sessions {
|
||||
session
|
||||
.text(format!("User with ID: {id} just joined {room} room"))
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
};
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
struct SessionActor {
|
||||
id: SessionID,
|
||||
server: Server<ChatServer>,
|
||||
session: Session,
|
||||
room: String,
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl ezsockets::SessionExt for SessionActor {
|
||||
type ID = SessionID;
|
||||
type Call = ();
|
||||
|
||||
fn id(&self) -> &Self::ID {
|
||||
&self.id
|
||||
}
|
||||
|
||||
async fn on_text(&mut self, text: String) -> Result<(), Error> {
|
||||
tracing::info!("received: {text}");
|
||||
if text.starts_with('/') {
|
||||
let mut args = text.split_whitespace();
|
||||
let command = args.next().unwrap();
|
||||
if command == "/join" {
|
||||
let room = args.next().expect("missing <room> argument").to_string();
|
||||
tracing::info!("moving {} to {room}", self.id);
|
||||
self.room = room.clone();
|
||||
self.server
|
||||
.call(Message::Join { id: self.id, room })
|
||||
.unwrap();
|
||||
} else {
|
||||
tracing::error!("unrecognized command: {text}");
|
||||
}
|
||||
} else {
|
||||
self.server
|
||||
.call(Message::Send {
|
||||
text,
|
||||
from: self.id,
|
||||
room: self.room.clone(),
|
||||
})
|
||||
.unwrap();
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn on_binary(&mut self, bytes: Vec<u8>) -> Result<(), Error> {
|
||||
// echo bytes back (we use this for a hacky ping/pong protocol for the wasm client demo)
|
||||
tracing::info!("echoing bytes: {bytes:?}");
|
||||
self.session.binary("pong".as_bytes())?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn on_call(&mut self, call: Self::Call) -> Result<(), Error> {
|
||||
let () = call;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
tracing_subscriber::fmt::init();
|
||||
let (server, _) = Server::create(|handle| ChatServer {
|
||||
sessions: HashMap::new(),
|
||||
rooms: HashMap::from_iter([(DEFAULT_ROOM.to_string(), vec![])]),
|
||||
handle,
|
||||
});
|
||||
ezsockets::tungstenite::run(server, "127.0.0.1:8080")
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user