25 Commits

Author SHA1 Message Date
Dave Hrycyszyn
546a45bb3a Deleting unused mod 2024-06-11 18:37:16 +01:00
Dave Hrycyszyn
950a63c103 Moved stdin_input to stdin::input module, pulling it out of main 2024-06-11 18:35:33 +01:00
Dave Hrycyszyn
f9c4fce398 Stopped double-encoding the SignedOp 2024-06-11 18:33:08 +01:00
Dave Hrycyszyn
014462c187 Using the ezsockets call methods to shoot text at the websocket. 2024-06-11 18:29:02 +01:00
Dave Hrycyszyn
b1daec3b84 Figured out what on_call is for 2024-06-11 18:13:51 +01:00
Dave Hrycyszyn
e0c991d0f9 Getting ready for network broadcast 2024-06-11 17:06:49 +01:00
Dave Hrycyszyn
a53b5bd94c Tidy 2024-06-11 16:52:40 +01:00
Dave Hrycyszyn
d13df41b82 Variable rename 2024-06-11 16:52:15 +01:00
Dave Hrycyszyn
4496a0916b Removing period send code 2024-06-11 16:51:13 +01:00
Dave Hrycyszyn
f3bea8c62d Restructuring tokio tasks and stdin receiver 2024-06-11 16:50:21 +01:00
Dave Hrycyszyn
443c4e1dac Simplifying 2024-06-10 16:43:45 +01:00
Dave Hrycyszyn
6077c3a519 Pinpointing blocking point 2024-06-10 16:33:03 +01:00
Dave Hrycyszyn
91fbe7f9bd Going back to blocking, need a new thread here 2024-06-10 14:26:00 +01:00
Dave Hrycyszyn
4717ffa7e8 Almost working, I've got a blocking I/O problem with stdin now :) 2024-06-10 14:25:05 +01:00
Dave Hrycyszyn
c3f5b2890b More pushing code around 2024-06-07 18:42:28 +01:00
Dave Hrycyszyn
9dc515fb78 Renamed write to write_toml in the config 2024-06-07 18:22:07 +01:00
Dave Hrycyszyn
6f756d4fb6 Minor cleanup 2024-06-07 18:20:02 +01:00
Dave Hrycyszyn
5d6a1e806a Nearly there 2024-06-07 17:35:38 +01:00
Dave Hrycyszyn
d91a631fdc More re-jigging 2024-06-07 17:18:46 +01:00
Dave Hrycyszyn
a81d1f913a Starting to modify things into container structs 2024-06-07 17:03:05 +01:00
Dave Hrycyszyn
b1f5d2b75a User serde_json for SignedOp serialization 2024-06-07 14:58:41 +01:00
Dave Hrycyszyn
95e3127903 Giving nodes the ability to send transactions in a more controlled fashion 2024-06-06 19:50:24 +01:00
Dave Hrycyszyn
3f4b4324e5 Implementing Display for SignedOp 2024-06-06 19:49:53 +01:00
Dave Hrycyszyn
404a769259 ezsockets integrated with cli startup 2024-06-06 19:32:29 +01:00
Dave Hrycyszyn
ff9fbd49ec Starting a move towards ezsockets 2024-06-06 19:25:54 +01:00
15 changed files with 681 additions and 469 deletions

552
Cargo.lock generated
View File

@@ -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]]

View File

@@ -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
View 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
// }
// }

View File

@@ -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>> {

View File

@@ -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(())
}

View File

@@ -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
})
}

View File

@@ -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
View 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
View 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();
}
}

View File

@@ -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
})
}

View 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(())
}
}

View File

@@ -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))
}

View File

@@ -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"

View File

@@ -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();
}