From bac0b23318a2d9592e466ba175c0e5e8150bb61f Mon Sep 17 00:00:00 2001 From: gRoussac Date: Tue, 17 Sep 2024 13:51:41 +0200 Subject: [PATCH 01/32] start WIP rustSDK-feat-2.0 branch --- Cargo.lock | 394 +++++++++++++----------- Cargo.toml | 8 +- binary_port_access/Cargo.toml | 25 +- binary_port_access/src/communication.rs | 272 ++++++++++++++-- binary_port_access/src/error.rs | 52 +++- binary_port_access/src/lib.rs | 107 ++++--- binary_port_access/src/utils.rs | 1 + 7 files changed, 586 insertions(+), 273 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5d9d0fb..ef35f65 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,18 +4,18 @@ version = 3 [[package]] name = "addr2line" -version = "0.22.0" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" +checksum = "f5fb1d8e4442bd405fdfd1dacb42792696b0cf9cb15882e5d097b742a676d375" dependencies = [ "gimli", ] [[package]] -name = "adler" -version = "1.0.2" +name = "adler2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" [[package]] name = "aho-corasick" @@ -28,9 +28,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.14" +version = "0.6.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" +checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" dependencies = [ "anstyle", "anstyle-parse", @@ -43,33 +43,33 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.7" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" +checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" [[package]] name = "anstyle-parse" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" +checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad186efb764318d35165f1758e7dcef3b10628e26d41a44bc5550652e6804391" +checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" dependencies = [ "windows-sys 0.52.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.3" +version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" +checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" dependencies = [ "anstyle", "windows-sys 0.52.0", @@ -83,17 +83,17 @@ checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "backtrace" -version = "0.3.72" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17c6a35df3749d2e8bb1b7b21a976d82b15548788d2735b9d82f329268f71a11" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" dependencies = [ "addr2line", - "cc", "cfg-if", "libc", "miniz_oxide", "object", "rustc-demangle", + "windows-targets 0.52.6", ] [[package]] @@ -137,9 +137,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "blake2" @@ -175,14 +175,14 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.6.0" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" +checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" [[package]] name = "casper-binary-port" version = "1.0.0" -source = "git+https://github.com/casper-network/casper-node.git?branch=feat-2.0#ee4691553ddf0a977b532edd93af817de523e840" +source = "git+https://github.com/casper-network/casper-node?branch=rustSDK-feat-2.0#45bd9e57ce71b0bbd82d8e05455466cd3fc867f3" dependencies = [ "bincode", "bytes", @@ -203,9 +203,13 @@ dependencies = [ "casper-binary-port", "casper-types", "futures", + "js-sys", + "rand", "thiserror", "tokio", - "tokio-util", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", ] [[package]] @@ -227,7 +231,7 @@ dependencies = [ [[package]] name = "casper-types" version = "5.0.0" -source = "git+https://github.com/casper-network/casper-node.git?branch=feat-2.0#ee4691553ddf0a977b532edd93af817de523e840" +source = "git+https://github.com/casper-network/casper-node?branch=rustSDK-feat-2.0#45bd9e57ce71b0bbd82d8e05455466cd3fc867f3" dependencies = [ "base16", "base64", @@ -263,12 +267,6 @@ dependencies = [ "untrusted", ] -[[package]] -name = "cc" -version = "1.0.99" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96c51067fd44124faa7f870b4b1c969379ad32b2ba805aa959430ceaa384f695" - [[package]] name = "cfg-if" version = "1.0.0" @@ -277,9 +275,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.5.7" +version = "4.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5db83dced34638ad474f39f250d7fea9598bdd239eaced1bdf45d597da0f433f" +checksum = "3e5a21b8495e732f1b3c364c9949b201ca7bae518c502c80256c96ad79eaf6ac" dependencies = [ "clap_builder", "clap_derive", @@ -287,9 +285,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.7" +version = "4.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7e204572485eb3fbf28f871612191521df159bc3e15a9f5064c66dba3a8c05f" +checksum = "8cf2dd12af7a047ad9d6da2b6b249759a22a7abc0f474c1dae1777afa4b21a73" dependencies = [ "anstream", "anstyle", @@ -300,27 +298,27 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.5" +version = "4.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c780290ccf4fb26629baa7a1081e68ced113f1d3ec302fa5948f1c381ebf06c6" +checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0" dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.77", ] [[package]] name = "clap_lex" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70" +checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" [[package]] name = "colorchoice" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" +checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" [[package]] name = "const-oid" @@ -336,9 +334,9 @@ checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" [[package]] name = "cpufeatures" -version = "0.2.12" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" dependencies = [ "libc", ] @@ -383,16 +381,15 @@ dependencies = [ [[package]] name = "curve25519-dalek" -version = "4.1.2" +version = "4.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a677b8922c94e01bdbb12126b0bc852f00447528dee1782229af9c720c3f348" +checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" dependencies = [ "cfg-if", "cpufeatures", "curve25519-dalek-derive", "digest 0.10.7", "fiat-crypto", - "platforms", "rustc_version", "subtle", "zeroize", @@ -406,7 +403,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.77", ] [[package]] @@ -441,15 +438,15 @@ dependencies = [ [[package]] name = "derive_more" -version = "0.99.17" +version = "0.99.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" dependencies = [ "convert_case", "proc-macro2", "quote", "rustc_version", - "syn 1.0.109", + "syn 2.0.77", ] [[package]] @@ -527,9 +524,9 @@ dependencies = [ [[package]] name = "either" -version = "1.12.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "elliptic-curve" @@ -647,7 +644,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.77", ] [[package]] @@ -706,9 +703,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.29.0" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" +checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64" [[package]] name = "group" @@ -785,9 +782,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.2.6" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5" dependencies = [ "equivalent", "hashbrown 0.14.5", @@ -795,9 +792,9 @@ dependencies = [ [[package]] name = "is_terminal_polyfill" -version = "1.70.0" +version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" [[package]] name = "itertools" @@ -816,9 +813,9 @@ checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "js-sys" -version = "0.3.69" +version = "0.3.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" dependencies = [ "wasm-bindgen", ] @@ -837,9 +834,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.155" +version = "0.2.158" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" [[package]] name = "linux-raw-sys" @@ -849,34 +846,35 @@ checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "log" -version = "0.4.21" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "memchr" -version = "2.7.2" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "miniz_oxide" -version = "0.7.3" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87dfd01fe195c66b572b37921ad8803d010623c0aca821bea2302239d155cdae" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" dependencies = [ - "adler", + "adler2", ] [[package]] name = "mio" -version = "0.8.11" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" dependencies = [ + "hermit-abi", "libc", "wasi", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -895,9 +893,9 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c165a9ab64cf766f73521c0dd2cfdff64f488b8f0b3e621face3462d3db536d7" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" dependencies = [ "num-integer", "num-traits", @@ -914,13 +912,13 @@ dependencies = [ [[package]] name = "num-derive" -version = "0.3.3" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.77", ] [[package]] @@ -964,21 +962,11 @@ dependencies = [ "autocfg", ] -[[package]] -name = "num_cpus" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" -dependencies = [ - "hermit-abi", - "libc", -] - [[package]] name = "object" -version = "0.35.0" +version = "0.36.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8ec7ab813848ba4522158d5517a6093db1ded27575b070f4177b8d12b41db5e" +checksum = "084f1a5821ac4c651660a94a7153d27ac9d8a53736203f58b31945ded098070a" dependencies = [ "memchr", ] @@ -1028,32 +1016,29 @@ dependencies = [ "spki", ] -[[package]] -name = "platforms" -version = "3.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db23d408679286588f4d4644f965003d056e3dd5abcaaa938116871d7ce2fee7" - [[package]] name = "ppv-lite86" -version = "0.2.17" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] [[package]] name = "proc-macro2" -version = "1.0.85" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.36" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -1090,9 +1075,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.5" +version = "1.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" +checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" dependencies = [ "aho-corasick", "memchr", @@ -1135,20 +1120,20 @@ checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustc_version" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ "semver", ] [[package]] name = "rustix" -version = "0.38.34" +version = "0.38.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "errno", "libc", "linux-raw-sys", @@ -1183,7 +1168,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn 2.0.66", + "syn 2.0.77", ] [[package]] @@ -1207,9 +1192,9 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.203" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" dependencies = [ "serde_derive", ] @@ -1226,22 +1211,22 @@ dependencies = [ [[package]] name = "serde_bytes" -version = "0.11.14" +version = "0.11.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b8497c313fd43ab992087548117643f6fcd935cbf36f176ffda0aacf9591734" +checksum = "387cc504cb06bb40a96c8e04e951fe01854cf6bc921053c954e4a606d9675c6a" dependencies = [ "serde", ] [[package]] name = "serde_derive" -version = "1.0.203" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.77", ] [[package]] @@ -1252,17 +1237,18 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.77", ] [[package]] name = "serde_json" -version = "1.0.117" +version = "1.0.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" +checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" dependencies = [ - "indexmap 2.2.6", + "indexmap 2.5.0", "itoa", + "memchr", "ryu", "serde", ] @@ -1331,9 +1317,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "subtle" -version = "2.5.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" @@ -1348,9 +1334,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.66" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -1369,49 +1355,49 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.61" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" +checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.61" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" +checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.77", ] [[package]] name = "tokio" -version = "1.38.0" +version = "1.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a" +checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" dependencies = [ "backtrace", + "bytes", "libc", "mio", - "num_cpus", "pin-project-lite", "socket2", "tokio-macros", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "tokio-macros" -version = "2.3.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" +checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.77", ] [[package]] @@ -1446,9 +1432,9 @@ checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" [[package]] name = "typeid" -version = "1.0.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "059d83cc991e7a42fc37bd50941885db0888e34209f8cfd9aab07ddec03bc9cf" +checksum = "0e13db2e0ccd5e14a544e8a246ba2312cd25223f616442d7f2cb0e3db614236e" [[package]] name = "typenum" @@ -1470,9 +1456,9 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" [[package]] name = "untrusted" @@ -1488,9 +1474,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "version_check" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "wasi" @@ -1500,34 +1486,47 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" dependencies = [ "cfg-if", + "once_cell", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.77", "wasm-bindgen-shared", ] +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61e9300f63a621e96ed275155c108eb6f843b6a26d053f122ab69724559dc8ed" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "wasm-bindgen-macro" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1535,22 +1534,32 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.77", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" +checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" + +[[package]] +name = "web-sys" +version = "0.3.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0" +dependencies = [ + "js-sys", + "wasm-bindgen", +] [[package]] name = "windows-sys" @@ -1567,7 +1576,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] @@ -1587,18 +1596,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.5", - "windows_aarch64_msvc 0.52.5", - "windows_i686_gnu 0.52.5", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", "windows_i686_gnullvm", - "windows_i686_msvc 0.52.5", - "windows_x86_64_gnu 0.52.5", - "windows_x86_64_gnullvm 0.52.5", - "windows_x86_64_msvc 0.52.5", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] @@ -1609,9 +1618,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" @@ -1621,9 +1630,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" @@ -1633,15 +1642,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" @@ -1651,9 +1660,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" @@ -1663,9 +1672,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" @@ -1675,9 +1684,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" @@ -1687,9 +1696,30 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.77", +] [[package]] name = "zeroize" diff --git a/Cargo.toml b/Cargo.toml index c8d8900..74986b6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,14 +11,14 @@ description = "CLI for Casper binary port." license = "Apache-2.0" [dependencies] -casper-types = { git = "https://github.com/casper-network/casper-node.git", branch = "feat-2.0", features = [ +casper-types = { git = "https://github.com/casper-network/casper-node.git", branch = "rustSDK-feat-2.0", features = [ "std-fs-io", ] } -casper-binary-port = { git = "https://github.com/casper-network/casper-node.git", branch = "feat-2.0" } +casper-binary-port = { version = "1.0.0", git = "https://github.com/casper-network/casper-node", branch = "rustSDK-feat-2.0" } casper-binary-port-access = { path = "./binary_port_access" } clap = { version = "4.5.3", features = ["derive", "wrap_help"] } -thiserror = "1.0.58" -tokio = { version = "1.36.0", features = ["macros", "rt-multi-thread", "net"] } +thiserror = "1" +tokio = { version = "1.40.0", features = ["macros", "rt", "net"] } hex = "0.4.3" serde = { version = "1.0.203", features = ["derive"] } serde_json = "1.0.117" diff --git a/binary_port_access/Cargo.toml b/binary_port_access/Cargo.toml index e27a94e..2edb2f0 100644 --- a/binary_port_access/Cargo.toml +++ b/binary_port_access/Cargo.toml @@ -6,10 +6,23 @@ authors = ["RafaƂ Chabowski "] description = "Library for accessing Casper binary port." license = "Apache-2.0" +[lib] +crate-type = ["cdylib", "rlib"] +name = "casper_binary_port_access" +path = "src/lib.rs" + [dependencies] -casper-types = { git = "https://github.com/casper-network/casper-node.git", branch = "feat-2.0" } -casper-binary-port = { git = "https://github.com/casper-network/casper-node.git", branch = "feat-2.0" } -thiserror = "1.0.58" -tokio = { version = "1.36.0", features = ["macros", "rt-multi-thread", "net"] } -tokio-util = { version = "0.6.4", features = ["codec"] } -futures = "0" \ No newline at end of file +casper-types = { git = "https://github.com/casper-network/casper-node.git", default-features = false, branch = "rustSDK-feat-2.0" } +casper-binary-port = { git = "https://github.com/casper-network/casper-node.git", branch = "rustSDK-feat-2.0" } +thiserror = "1" +futures = "0" +rand = { version = "0.8.5", default-features = false } + +[target.'cfg(target_arch = "wasm32")'.dependencies] +wasm-bindgen = "*" +wasm-bindgen-futures = "*" +js-sys = "*" +web-sys = { version = "0.3", features = ["WebSocket", "MessageEvent"] } + +[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +tokio = { version = "1.40.0", features = ["macros", "io-util", "time", "net"] } diff --git a/binary_port_access/src/communication.rs b/binary_port_access/src/communication.rs index ebe9ac8..0429197 100644 --- a/binary_port_access/src/communication.rs +++ b/binary_port_access/src/communication.rs @@ -1,63 +1,250 @@ +use crate::Error; +#[cfg(not(target_arch = "wasm32"))] +use casper_binary_port::BinaryMessage; use casper_binary_port::{ - BinaryMessage, BinaryMessageCodec, BinaryRequest, BinaryRequestHeader, BinaryResponse, - BinaryResponseAndRequest, PayloadEntity, + BinaryRequest, BinaryRequestHeader, BinaryResponse, BinaryResponseAndRequest, PayloadEntity, }; use casper_types::{ bytesrepr::{self, FromBytes, ToBytes}, ProtocolVersion, }; -use futures::{SinkExt, StreamExt}; -use tokio::net::TcpStream; -use tokio_util::codec::Framed; +use rand::Rng; +#[cfg(not(target_arch = "wasm32"))] +use std::time::Duration; +#[cfg(not(target_arch = "wasm32"))] +use tokio::{ + io::{AsyncReadExt, AsyncWriteExt}, + net::TcpStream, + time::timeout, +}; +#[cfg(target_arch = "wasm32")] +pub use wasm_bindgen::JsCast; +#[cfg(target_arch = "wasm32")] +mod wasm_config { + pub use js_sys::Promise; + pub use wasm_bindgen::prelude::Closure; -use crate::Error; + pub use wasm_bindgen::JsValue; + pub use wasm_bindgen_futures::JsFuture; + pub use web_sys::{MessageEvent, WebSocket}; +} // TODO[RC]: Do not hardcode this. pub(crate) const SUPPORTED_PROTOCOL_VERSION: ProtocolVersion = ProtocolVersion::from_parts(2, 0, 0); +const REQUEST_ID_START: usize = 0; +const REQUEST_ID_END: usize = REQUEST_ID_START + 2; +const LENGTH_OF_REQUEST_START: usize = REQUEST_ID_END; +const LENGTH_OF_REQUEST_END: usize = LENGTH_OF_REQUEST_START + 4; -async fn connect_to_node( - node_address: &str, -) -> Result, Error> { +#[cfg(not(target_arch = "wasm32"))] +const TIMEOUT_DURATION: Duration = Duration::from_secs(5); +#[cfg(not(target_arch = "wasm32"))] +const LENGTH_FIELD_SIZE: usize = 4; + +// TODO[RC]: Into "communication" module + +#[cfg(not(target_arch = "wasm32"))] +async fn connect_to_node(node_address: &str) -> Result { let stream = TcpStream::connect(node_address).await?; - Ok(Framed::new(stream, BinaryMessageCodec::new(4_194_304))) + Ok(stream) } -fn encode_request(req: &BinaryRequest) -> Result, bytesrepr::Error> { - let header = BinaryRequestHeader::new(SUPPORTED_PROTOCOL_VERSION, req.tag(), 0); +fn encode_request( + req: &BinaryRequest, + request_id: Option, +) -> Result, bytesrepr::Error> { + let header = BinaryRequestHeader::new( + SUPPORTED_PROTOCOL_VERSION, + req.tag(), + request_id.unwrap_or_default(), + ); let mut bytes = Vec::with_capacity(header.serialized_length() + req.serialized_length()); header.write_bytes(&mut bytes)?; req.write_bytes(&mut bytes)?; Ok(bytes) } -// TODO[RC]: Into "communication" module +#[cfg(not(target_arch = "wasm32"))] pub(crate) async fn send_request( node_address: &str, request: BinaryRequest, ) -> Result { + let request_id = rand::thread_rng().gen::(); let payload = - BinaryMessage::new(encode_request(&request).expect("should always serialize a request")); - + encode_request(&request, Some(request_id)).expect("should always serialize a request"); let mut client = connect_to_node(node_address).await?; - client.send(payload).await?; - let maybe_response = client.next().await; + let message = BinaryMessage::new(payload); + + // Send the payload length and data + send_payload(&mut client, &message).await?; + + // Read and process the response + let response_buf = read_response(&mut client).await?; + process_response(response_buf, request_id).await +} - let Some(response) = maybe_response else { - return Err(Error::Response("empty response".to_string())); +#[cfg(target_arch = "wasm32")] +pub(crate) async fn send_request( + node_address: &str, + request: BinaryRequest, +) -> Result { + let request_id = rand::thread_rng().gen::(); + let payload = encode_request(&request, Some(request_id)) + .map_err(|e| Error::Serialization(format!("Failed to serialize request: {}", e)))?; + + // Ensure the WebSocket URL is correct + let ws_url = if node_address.starts_with("ws://") || node_address.starts_with("wss://") { + node_address.to_string() + } else { + format!("ws://{}", node_address) }; - let response = response?; - let payload = response.payload(); - Ok(bytesrepr::deserialize_from_slice(payload)?) + // Create a new WebSocket connection + let ws = wasm_config::WebSocket::new(&ws_url) + .map_err(|e| Error::WebSocketCreation(format!("Failed to create WebSocket: {:?}", e)))?; + + // Create a promise to handle incoming WebSocket messages + let promise = wasm_config::Promise::new(&mut |resolve, reject| { + // Clone ws and payload to avoid moving them into the closure + let ws_clone = ws.clone(); + let payload_clone = payload.clone(); + + // Clone resolve and reject so they aren't moved into the closure + let resolve_clone = resolve.clone(); + let reject_clone = reject.clone(); + + let onopen = wasm_config::Closure::wrap(Box::new(move || { + // Send the payload once the connection is open + if let Err(e) = ws_clone.send_with_u8_array(&payload_clone) { + reject_clone + .call1( + &wasm_config::JsValue::NULL, + &wasm_config::JsValue::from_str(&format!( + "Failed to send message: {:?}", + e + )), + ) + .unwrap(); + } else { + // Set up onmessage and onerror handlers + + // Clone resolve again for the onmessage closure + let resolve_clone_for_message = resolve_clone.clone(); + + let onmessage = + wasm_config::Closure::wrap(Box::new(move |event: wasm_config::MessageEvent| { + let data = event.data().as_string().unwrap_or_default(); + resolve_clone_for_message + .call1( + &wasm_config::JsValue::NULL, + &wasm_config::JsValue::from_str(&data), + ) + .unwrap(); + }) + as Box); + + ws_clone.set_onmessage(Some(onmessage.as_ref().unchecked_ref())); + onmessage.forget(); + + // Clone reject again for the onerror closure + let reject_clone_for_error = reject_clone.clone(); + + let onerror = + wasm_config::Closure::wrap(Box::new(move |event: wasm_config::JsValue| { + let error_msg = event + .as_string() + .unwrap_or_else(|| "WebSocket error".to_string()); + reject_clone_for_error + .call1( + &wasm_config::JsValue::NULL, + &wasm_config::JsValue::from_str(&error_msg), + ) + .unwrap(); + }) + as Box); + + ws_clone.set_onerror(Some(onerror.as_ref().unchecked_ref())); + onerror.forget(); + } + }) as Box); + + ws.set_onopen(Some(onopen.as_ref().unchecked_ref())); + onopen.forget(); + }); + + let js_future = wasm_config::JsFuture::from(wasm_config::Promise::resolve(&promise)); + let onmessage = js_future + .await + .map_err(|e| Error::Response(format!("Failed to receive message: {:?}", e)))?; + + // Cast the result to a MessageEvent + let message_event = onmessage + .dyn_into::() + .map_err(|_| Error::Response("Failed to cast to MessageEvent".to_string()))?; + + // Extract the response data as a string + let data = message_event + .data() + .as_string() + .ok_or_else(|| Error::Response("Failed to parse response data".to_string()))?; + + // Process the response + let response = process_response(data.as_bytes().to_vec(), request_id).await?; + + Ok(response) +} + +/// Sends the payload length and data to the client. +#[cfg(not(target_arch = "wasm32"))] +async fn send_payload(client: &mut TcpStream, message: &BinaryMessage) -> Result<(), Error> { + let payload_length = message.payload().len() as u32; + let length_bytes = payload_length.to_le_bytes(); + + let _ = timeout(TIMEOUT_DURATION, client.write_all(&length_bytes)) + .await + .map_err(|e| Error::TimeoutError(e.to_string()))?; + + let _ = timeout(TIMEOUT_DURATION, client.write_all(message.payload())) + .await + .map_err(|e| Error::TimeoutError(e.to_string()))?; + + let _ = timeout(TIMEOUT_DURATION, client.flush()) + .await + .map_err(|e| Error::TimeoutError(e.to_string()))?; + + Ok(()) } +/// Reads the response from the client and returns the response buffer. +#[cfg(not(target_arch = "wasm32"))] +async fn read_response(client: &mut TcpStream) -> Result, Error> { + let mut length_buf = [0u8; LENGTH_FIELD_SIZE]; + let _ = timeout(TIMEOUT_DURATION, client.read_exact(&mut length_buf)) + .await + .map_err(|e| Error::TimeoutError(e.to_string()))?; + + let response_length = u32::from_le_bytes(length_buf) as usize; + let mut response_buf = vec![0u8; response_length]; + let _ = timeout(TIMEOUT_DURATION, client.read_exact(&mut response_buf)) + .await + .map_err(|e| Error::TimeoutError(e.to_string()))?; + + Ok(response_buf) +} + +/// Parse response pub(crate) fn parse_response( response: &BinaryResponse, ) -> Result, Error> { match response.returned_data_type_tag() { - Some(found) if found == u8::from(A::PAYLOAD_TYPE) => { - // TODO: Verbose: print length of payload - Ok(Some(bytesrepr::deserialize_from_slice(response.payload())?)) + Some(found) if found == u8::from(A::RESPONSE_TYPE) => { + // Verbose: Print length of payload + let payload = response.payload(); + let _payload_length = payload.len(); + // TODO[GR] use tracing::info! instead of dbg! + // dbg!(_payload_length); + + Ok(Some(bytesrepr::deserialize_from_slice(payload)?)) } Some(other) => Err(Error::Response(format!( "unsupported response type: {other}" @@ -65,3 +252,38 @@ pub(crate) fn parse_response( _ => Ok(None), } } + +/// Processes the response buffer and checks for request ID mismatch. +async fn process_response( + response_buf: Vec, + request_id: u16, +) -> Result { + // Extract Request ID from the response + let _request_id = u16::from_le_bytes( + response_buf[REQUEST_ID_START..REQUEST_ID_END] + .try_into() + .expect("Failed to extract Request ID"), + ); + + // Check if request_id matches _request_id and return an error if not + if request_id != _request_id { + return Err(Error::Response(format!( + "Request ID mismatch: expected {}, got {}", + request_id, _request_id + ))); + } + + // Extract LengthOfRequest from the response + let length_of_request = u32::from_le_bytes( + response_buf[LENGTH_OF_REQUEST_START..LENGTH_OF_REQUEST_END] + .try_into() + .expect("Failed to extract LengthOfRequest"), + ) as usize; + + // Extract remaining bytes from the response + let remaining_response = &response_buf[length_of_request..]; + + // Deserialize the remaining response data + let response: BinaryResponseAndRequest = bytesrepr::deserialize_from_slice(remaining_response)?; + Ok(response) +} diff --git a/binary_port_access/src/error.rs b/binary_port_access/src/error.rs index 0d71bf5..0935dc5 100644 --- a/binary_port_access/src/error.rs +++ b/binary_port_access/src/error.rs @@ -1,19 +1,67 @@ use casper_types::bytesrepr; use thiserror::Error; +#[cfg(target_arch = "wasm32")] +use wasm_bindgen::JsValue; -/// Possible errors that can occur when interacting with the binary port. #[derive(Error, Debug)] +/// Errors pub enum Error { /// Bytesrepr serialization error. #[error(transparent)] Bytesrepr(#[from] bytesrepr::Error), + /// IO error. #[error(transparent)] Io(#[from] std::io::Error), + /// Error in the binary port. #[error(transparent)] BinaryPort(#[from] casper_binary_port::Error), + /// Error when handling the response from the binary port. - #[error("failed to handle response: {0}")] + #[error("Failed to handle response: {0}")] Response(String), + + /// Error related to network timeout. + #[error("Failed to handle network response: {0}")] + TimeoutError(String), + + /// Error related to http request. + #[error("Failed to send http request: {0}")] + HttpRequest(String), + + /// Error related to http response. + #[error("Failed to handle http response: {0}")] + HttpResponse(String), + + /// WebSocket creation error. + #[error("Failed to create WebSocket: {0}")] + WebSocketCreation(String), + + /// WebSocket send error. + #[error("Failed to send WebSocket message: {0}")] + WebSocketSend(String), + + /// JavaScript-related error. + #[error("JavaScript error: {0}")] + JsError(String), + + /// General serialization error. + #[error("Serialization error: {0}")] + Serialization(String), + + /// Generic error for other cases. + #[error("Other error: {0}")] + Other(String), +} + +#[cfg(target_arch = "wasm32")] +impl From for Error { + fn from(js_value: JsValue) -> Self { + Error::JsError( + js_value + .as_string() + .unwrap_or_else(|| "Unknown JavaScript error".to_string()), + ) + } } diff --git a/binary_port_access/src/lib.rs b/binary_port_access/src/lib.rs index 3c00027..51b294f 100644 --- a/binary_port_access/src/lib.rs +++ b/binary_port_access/src/lib.rs @@ -1,8 +1,11 @@ #![deny(missing_docs)] //! This crate provides a high-level API for interacting with a Casper node's binary port interface. -use communication::parse_response; -use thiserror::Error; +/// Expose communication methods +pub mod communication; +mod error; +/// Expose utils methods +pub mod utils; use casper_binary_port::{ BinaryRequest, ConsensusStatus, ConsensusValidatorChanges, EraIdentifier, @@ -15,22 +18,20 @@ use casper_types::{ BlockSynchronizerStatus, ChainspecRawBytes, Digest, EraId, GlobalStateIdentifier, Key, NextUpgrade, Peers, ProtocolVersion, PublicKey, SignedBlock, Transaction, TransactionHash, }; - -mod communication; -mod error; -pub(crate) mod utils; +use communication::{parse_response, send_request}; pub use error::Error; +use thiserror::Error; use utils::{ check_error_code, delegator_reward_by_era_identifier, global_state_item_by_state_identifier, - validator_reward_by_era_identifier, + make_information_get_request, validator_reward_by_era_identifier, }; /// Returns the latest switch block header. pub async fn latest_switch_block_header(node_address: &str) -> Result, Error> { let request = - utils::make_information_get_request(InformationRequestTag::LatestSwitchBlockHeader, &[])?; - let response = communication::send_request(node_address, request).await?; + make_information_get_request(InformationRequestTag::LatestSwitchBlockHeader, &[])?; + let response = send_request(node_address, request).await?; check_error_code(&response)?; parse_response::(response.response()) } @@ -38,11 +39,11 @@ pub async fn latest_switch_block_header(node_address: &str) -> Result Result, Error> { let block_id: Option = None; - let request = utils::make_information_get_request( + let request = make_information_get_request( InformationRequestTag::BlockHeader, block_id.to_bytes()?.as_slice(), )?; - let response = communication::send_request(node_address, request).await?; + let response = send_request(node_address, request).await?; check_error_code(&response)?; parse_response::(response.response()) } @@ -53,11 +54,11 @@ pub async fn block_header_by_height( height: u64, ) -> Result, Error> { let block_id = Some(BlockIdentifier::Height(height)); - let request = utils::make_information_get_request( + let request = make_information_get_request( InformationRequestTag::BlockHeader, block_id.to_bytes()?.as_slice(), )?; - let response = communication::send_request(node_address, request).await?; + let response = send_request(node_address, request).await?; check_error_code(&response)?; parse_response::(response.response()) } @@ -68,11 +69,11 @@ pub async fn block_header_by_hash( hash: BlockHash, ) -> Result, Error> { let block_id = Some(BlockIdentifier::Hash(hash)); - let request = utils::make_information_get_request( + let request = make_information_get_request( InformationRequestTag::BlockHeader, block_id.to_bytes()?.as_slice(), )?; - let response = communication::send_request(node_address, request).await?; + let response = send_request(node_address, request).await?; check_error_code(&response)?; parse_response::(response.response()) } @@ -80,11 +81,11 @@ pub async fn block_header_by_hash( /// Returns the latest block along with signatures. pub async fn latest_signed_block(node_address: &str) -> Result, Error> { let block_id: Option = None; - let request = utils::make_information_get_request( + let request = make_information_get_request( InformationRequestTag::SignedBlock, block_id.to_bytes()?.as_slice(), )?; - let response = communication::send_request(node_address, request).await?; + let response = send_request(node_address, request).await?; check_error_code(&response)?; parse_response::(response.response()) } @@ -95,11 +96,11 @@ pub async fn signed_block_by_height( height: u64, ) -> Result, Error> { let block_id = Some(BlockIdentifier::Height(height)); - let request = utils::make_information_get_request( + let request = make_information_get_request( InformationRequestTag::SignedBlock, block_id.to_bytes()?.as_slice(), )?; - let response = communication::send_request(node_address, request).await?; + let response = send_request(node_address, request).await?; check_error_code(&response)?; parse_response::(response.response()) } @@ -110,11 +111,11 @@ pub async fn signed_block_by_hash( hash: BlockHash, ) -> Result, Error> { let block_id = Some(BlockIdentifier::Hash(hash)); - let request = utils::make_information_get_request( + let request = make_information_get_request( InformationRequestTag::SignedBlock, block_id.to_bytes()?.as_slice(), )?; - let response = communication::send_request(node_address, request).await?; + let response = send_request(node_address, request).await?; check_error_code(&response)?; parse_response::(response.response()) } @@ -127,7 +128,7 @@ pub async fn transaction_by_hash( hash: TransactionHash, with_finalized_approvals: bool, ) -> Result, Error> { - let request = utils::make_information_get_request( + let request = make_information_get_request( InformationRequestTag::Transaction, hash.to_bytes()? .into_iter() @@ -135,15 +136,15 @@ pub async fn transaction_by_hash( .collect::>() .as_slice(), )?; - let response = communication::send_request(node_address, request).await?; + let response = send_request(node_address, request).await?; check_error_code(&response)?; parse_response::(response.response()) } /// Returns the peer list. pub async fn peers(node_address: &str) -> Result { - let request = utils::make_information_get_request(InformationRequestTag::Peers, &[])?; - let response = communication::send_request(node_address, request).await?; + let request = make_information_get_request(InformationRequestTag::Peers, &[])?; + let response = send_request(node_address, request).await?; check_error_code(&response)?; let peers = parse_response::(response.response())?; peers.ok_or_else(|| Error::Response("unable to read peers".to_string())) @@ -151,8 +152,8 @@ pub async fn peers(node_address: &str) -> Result { /// Returns the node uptime. pub async fn uptime(node_address: &str) -> Result { - let request = utils::make_information_get_request(InformationRequestTag::Uptime, &[])?; - let response = communication::send_request(node_address, request).await?; + let request = make_information_get_request(InformationRequestTag::Uptime, &[])?; + let response = send_request(node_address, request).await?; check_error_code(&response)?; let uptime = parse_response::(response.response())?; uptime.ok_or_else(|| Error::Response("unable to read uptime".to_string())) @@ -160,8 +161,8 @@ pub async fn uptime(node_address: &str) -> Result { /// Returns the last progress as recorded by the node. pub async fn last_progress(node_address: &str) -> Result { - let request = utils::make_information_get_request(InformationRequestTag::LastProgress, &[])?; - let response = communication::send_request(node_address, request).await?; + let request = make_information_get_request(InformationRequestTag::LastProgress, &[])?; + let response = send_request(node_address, request).await?; check_error_code(&response)?; let last_progress = parse_response::(response.response())?; last_progress.ok_or_else(|| Error::Response("unable to read last progress".to_string())) @@ -169,8 +170,8 @@ pub async fn last_progress(node_address: &str) -> Result { /// Returns the current reactor state. pub async fn reactor_state(node_address: &str) -> Result { - let request = utils::make_information_get_request(InformationRequestTag::ReactorState, &[])?; - let response = communication::send_request(node_address, request).await?; + let request = make_information_get_request(InformationRequestTag::ReactorState, &[])?; + let response = send_request(node_address, request).await?; check_error_code(&response)?; let reactor_state = parse_response::(response.response())?; reactor_state.ok_or_else(|| Error::Response("unable to read last reactor state".to_string())) @@ -178,8 +179,8 @@ pub async fn reactor_state(node_address: &str) -> Result Result { - let request = utils::make_information_get_request(InformationRequestTag::NetworkName, &[])?; - let response = communication::send_request(node_address, request).await?; + let request = make_information_get_request(InformationRequestTag::NetworkName, &[])?; + let response = send_request(node_address, request).await?; check_error_code(&response)?; let network_name = parse_response::(response.response())?; network_name.ok_or_else(|| Error::Response("unable to read last network name".to_string())) @@ -190,8 +191,8 @@ pub async fn consensus_validator_changes( node_address: &str, ) -> Result { let request = - utils::make_information_get_request(InformationRequestTag::ConsensusValidatorChanges, &[])?; - let response = communication::send_request(node_address, request).await?; + make_information_get_request(InformationRequestTag::ConsensusValidatorChanges, &[])?; + let response = send_request(node_address, request).await?; check_error_code(&response)?; let consensus_validator_changes = parse_response::(response.response())?; @@ -205,8 +206,8 @@ pub async fn block_synchronizer_status( node_address: &str, ) -> Result { let request = - utils::make_information_get_request(InformationRequestTag::BlockSynchronizerStatus, &[])?; - let response = communication::send_request(node_address, request).await?; + make_information_get_request(InformationRequestTag::BlockSynchronizerStatus, &[])?; + let response = send_request(node_address, request).await?; check_error_code(&response)?; let block_synchronizer_status = parse_response::(response.response())?; block_synchronizer_status @@ -215,9 +216,8 @@ pub async fn block_synchronizer_status( /// Returns the available block range. pub async fn available_block_range(node_address: &str) -> Result { - let request = - utils::make_information_get_request(InformationRequestTag::AvailableBlockRange, &[])?; - let response = communication::send_request(node_address, request).await?; + let request = make_information_get_request(InformationRequestTag::AvailableBlockRange, &[])?; + let response = send_request(node_address, request).await?; check_error_code(&response)?; let available_block_range = parse_response::(response.response())?; available_block_range @@ -226,16 +226,16 @@ pub async fn available_block_range(node_address: &str) -> Result Result, Error> { - let request = utils::make_information_get_request(InformationRequestTag::NextUpgrade, &[])?; - let response = communication::send_request(node_address, request).await?; + let request = make_information_get_request(InformationRequestTag::NextUpgrade, &[])?; + let response = send_request(node_address, request).await?; check_error_code(&response)?; parse_response::(response.response()) } /// Returns the current status of the consensus. pub async fn consensus_status(node_address: &str) -> Result { - let request = utils::make_information_get_request(InformationRequestTag::ConsensusStatus, &[])?; - let response = communication::send_request(node_address, request).await?; + let request = make_information_get_request(InformationRequestTag::ConsensusStatus, &[])?; + let response = send_request(node_address, request).await?; check_error_code(&response)?; let consensus_status = parse_response::(response.response())?; consensus_status @@ -245,9 +245,8 @@ pub async fn consensus_status(node_address: &str) -> Result Result { - let request = - utils::make_information_get_request(InformationRequestTag::ChainspecRawBytes, &[])?; - let response = communication::send_request(node_address, request).await?; + let request = make_information_get_request(InformationRequestTag::ChainspecRawBytes, &[])?; + let response = send_request(node_address, request).await?; check_error_code(&response)?; let chainspec_raw_bytes = parse_response::(response.response())?; chainspec_raw_bytes @@ -256,8 +255,8 @@ pub async fn chainspec_raw_bytes(node_address: &str) -> Result Result { - let request = utils::make_information_get_request(InformationRequestTag::NodeStatus, &[])?; - let response = communication::send_request(node_address, request).await?; + let request = make_information_get_request(InformationRequestTag::NodeStatus, &[])?; + let response = send_request(node_address, request).await?; check_error_code(&response)?; let node_status = parse_response::(response.response())?; node_status.ok_or_else(|| Error::Response("unable to read last node status".to_string())) @@ -351,7 +350,7 @@ pub async fn read_record( key: &[u8], ) -> Result, Error> { let request = utils::make_record_request(record_id, key); - let response = communication::send_request(node_address, request).await?; + let response = send_request(node_address, request).await?; check_error_code(&response)?; Ok(response.response().payload().into()) } @@ -407,7 +406,7 @@ pub async fn try_accept_transaction( transaction: Transaction, ) -> Result<(), Error> { let request = BinaryRequest::TryAcceptTransaction { transaction }; - let response = communication::send_request(node_address, request).await?; + let response = send_request(node_address, request).await?; check_error_code(&response) } @@ -417,7 +416,7 @@ pub async fn try_speculative_execution( transaction: Transaction, ) -> Result { let request = BinaryRequest::TrySpeculativeExec { transaction }; - let response = communication::send_request(node_address, request).await?; + let response = send_request(node_address, request).await?; check_error_code(&response)?; @@ -429,8 +428,8 @@ pub async fn try_speculative_execution( /// Returns the protocol version. pub async fn protocol_version(node_address: &str) -> Result { - let request = utils::make_information_get_request(InformationRequestTag::ProtocolVersion, &[])?; - let response = communication::send_request(node_address, request).await?; + let request = make_information_get_request(InformationRequestTag::ProtocolVersion, &[])?; + let response = send_request(node_address, request).await?; check_error_code(&response)?; let protocol_version = parse_response::(response.response())?; protocol_version.ok_or_else(|| Error::Response("unable to read protocol version".to_string())) diff --git a/binary_port_access/src/utils.rs b/binary_port_access/src/utils.rs index a3408a9..c8c67e9 100644 --- a/binary_port_access/src/utils.rs +++ b/binary_port_access/src/utils.rs @@ -9,6 +9,7 @@ use crate::{ Error, }; +/// Expose make_information_get_request pub(crate) fn make_information_get_request( tag: InformationRequestTag, key: &[u8], From 8e304927b92b2a0d53523b654297134d0477e598 Mon Sep 17 00:00:00 2001 From: gRoussac Date: Wed, 18 Sep 2024 22:26:21 +0200 Subject: [PATCH 02/32] Fix deser bug --- binary_port_access/src/communication.rs | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/binary_port_access/src/communication.rs b/binary_port_access/src/communication.rs index 0429197..9fe8547 100644 --- a/binary_port_access/src/communication.rs +++ b/binary_port_access/src/communication.rs @@ -31,10 +31,6 @@ mod wasm_config { // TODO[RC]: Do not hardcode this. pub(crate) const SUPPORTED_PROTOCOL_VERSION: ProtocolVersion = ProtocolVersion::from_parts(2, 0, 0); -const REQUEST_ID_START: usize = 0; -const REQUEST_ID_END: usize = REQUEST_ID_START + 2; -const LENGTH_OF_REQUEST_START: usize = REQUEST_ID_END; -const LENGTH_OF_REQUEST_END: usize = LENGTH_OF_REQUEST_START + 4; #[cfg(not(target_arch = "wasm32"))] const TIMEOUT_DURATION: Duration = Duration::from_secs(5); @@ -258,6 +254,9 @@ async fn process_response( response_buf: Vec, request_id: u16, ) -> Result { + const REQUEST_ID_START: usize = 0; + const REQUEST_ID_END: usize = REQUEST_ID_START + 2; + // Extract Request ID from the response let _request_id = u16::from_le_bytes( response_buf[REQUEST_ID_START..REQUEST_ID_END] @@ -273,17 +272,7 @@ async fn process_response( ))); } - // Extract LengthOfRequest from the response - let length_of_request = u32::from_le_bytes( - response_buf[LENGTH_OF_REQUEST_START..LENGTH_OF_REQUEST_END] - .try_into() - .expect("Failed to extract LengthOfRequest"), - ) as usize; - - // Extract remaining bytes from the response - let remaining_response = &response_buf[length_of_request..]; - // Deserialize the remaining response data - let response: BinaryResponseAndRequest = bytesrepr::deserialize_from_slice(remaining_response)?; + let response: BinaryResponseAndRequest = bytesrepr::deserialize_from_slice(response_buf)?; Ok(response) } From 6915cc94b12315d282af55ac5af878ffd6a618e9 Mon Sep 17 00:00:00 2001 From: gRoussac Date: Sat, 5 Oct 2024 20:38:38 +0200 Subject: [PATCH 03/32] stash --- Cargo.lock | 14 ++ binary_port_access/Cargo.toml | 1 + binary_port_access/src/communication.rs | 288 +++++++++++++++--------- 3 files changed, 199 insertions(+), 104 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ef35f65..e3b6faf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -203,6 +203,7 @@ dependencies = [ "casper-binary-port", "casper-types", "futures", + "gloo-utils", "js-sys", "rand", "thiserror", @@ -707,6 +708,19 @@ version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64" +[[package]] +name = "gloo-utils" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b5555354113b18c547c1d3a98fbf7fb32a9ff4f6fa112ce823a21641a0ba3aa" +dependencies = [ + "js-sys", + "serde", + "serde_json", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "group" version = "0.13.0" diff --git a/binary_port_access/Cargo.toml b/binary_port_access/Cargo.toml index 2edb2f0..a9c2b6a 100644 --- a/binary_port_access/Cargo.toml +++ b/binary_port_access/Cargo.toml @@ -23,6 +23,7 @@ wasm-bindgen = "*" wasm-bindgen-futures = "*" js-sys = "*" web-sys = { version = "0.3", features = ["WebSocket", "MessageEvent"] } +gloo-utils = { version = "0.2", default-features = false, features = ["serde"] } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] tokio = { version = "1.40.0", features = ["macros", "io-util", "time", "net"] } diff --git a/binary_port_access/src/communication.rs b/binary_port_access/src/communication.rs index 9fe8547..e64ed97 100644 --- a/binary_port_access/src/communication.rs +++ b/binary_port_access/src/communication.rs @@ -24,10 +24,30 @@ mod wasm_config { pub use js_sys::Promise; pub use wasm_bindgen::prelude::Closure; + pub use js_sys::JsString; + pub use js_sys::Reflect; + + pub use gloo_utils::format::JsValueSerdeExt; pub use wasm_bindgen::JsValue; pub use wasm_bindgen_futures::JsFuture; pub use web_sys::{MessageEvent, WebSocket}; } +#[cfg(target_arch = "wasm32")] +use wasm_bindgen::prelude::*; + +#[cfg(target_arch = "wasm32")] +#[wasm_bindgen] +extern "C" { + #[wasm_bindgen(js_namespace = console, js_name = log)] + fn log_with_prefix(s: &str); +} +/// Logs an error message, prefixing it with "error wasm" and sends it to the console in JavaScript when running in a WebAssembly environment. +/// When running outside WebAssembly, it prints the error message to the standard output. +pub fn log(s: &str) { + let prefixed_s = format!("log wasm {}", s); + #[cfg(target_arch = "wasm32")] + log_with_prefix(&prefixed_s); +} // TODO[RC]: Do not hardcode this. pub(crate) const SUPPORTED_PROTOCOL_VERSION: ProtocolVersion = ProtocolVersion::from_parts(2, 0, 0); @@ -79,6 +99,51 @@ pub(crate) async fn send_request( process_response(response_buf, request_id).await } +#[cfg(target_arch = "wasm32")] +#[wasm_bindgen] +fn is_node() -> bool { + // Check if 'process' exists and if it has 'versions' property (which is present in Node.js) + let is_node = js_sys::global() + .dyn_into::() + .map(|global| { + wasm_config::Reflect::has(&global, &wasm_config::JsString::from("process")) + .unwrap_or(false) + && wasm_config::Reflect::get(&global, &wasm_config::JsString::from("process")) + .map(|process| { + wasm_config::Reflect::has( + &process, + &wasm_config::JsString::from("versions"), + ) + .unwrap_or(false) + }) + .unwrap_or(false) + }) + .unwrap_or(false); + + is_node +} + +#[cfg(target_arch = "wasm32")] +#[wasm_bindgen] +pub async fn load_ws_module() -> Result { + // Dynamically import the 'ws' module using JavaScript's import() function + let import_script = "import('ws')"; + + // Evaluate the `import` script in the JavaScript environment + let import_promise: Promise = js_sys::eval(import_script) + .map_err(|_| JsError::new("Failed to execute import for 'ws'").into())? + .dyn_into() + .map_err(|_| JsError::new("Failed to convert eval result to Promise").into())?; + + // Wait for the Promise to resolve and load the WebSocket module + let ws_module = JsFuture::from(import_promise) + .await + .map_err(|_| JsError::new("Failed to load ws module via import").into())?; + + // Return the WebSocket module + Ok(ws_module) +} + #[cfg(target_arch = "wasm32")] pub(crate) async fn send_request( node_address: &str, @@ -88,104 +153,119 @@ pub(crate) async fn send_request( let payload = encode_request(&request, Some(request_id)) .map_err(|e| Error::Serialization(format!("Failed to serialize request: {}", e)))?; - // Ensure the WebSocket URL is correct let ws_url = if node_address.starts_with("ws://") || node_address.starts_with("wss://") { node_address.to_string() } else { format!("ws://{}", node_address) }; - // Create a new WebSocket connection - let ws = wasm_config::WebSocket::new(&ws_url) - .map_err(|e| Error::WebSocketCreation(format!("Failed to create WebSocket: {:?}", e)))?; - - // Create a promise to handle incoming WebSocket messages - let promise = wasm_config::Promise::new(&mut |resolve, reject| { - // Clone ws and payload to avoid moving them into the closure - let ws_clone = ws.clone(); - let payload_clone = payload.clone(); - - // Clone resolve and reject so they aren't moved into the closure - let resolve_clone = resolve.clone(); - let reject_clone = reject.clone(); - - let onopen = wasm_config::Closure::wrap(Box::new(move || { - // Send the payload once the connection is open - if let Err(e) = ws_clone.send_with_u8_array(&payload_clone) { - reject_clone - .call1( - &wasm_config::JsValue::NULL, - &wasm_config::JsValue::from_str(&format!( - "Failed to send message: {:?}", - e - )), - ) - .unwrap(); - } else { - // Set up onmessage and onerror handlers - - // Clone resolve again for the onmessage closure - let resolve_clone_for_message = resolve_clone.clone(); - - let onmessage = - wasm_config::Closure::wrap(Box::new(move |event: wasm_config::MessageEvent| { - let data = event.data().as_string().unwrap_or_default(); - resolve_clone_for_message - .call1( - &wasm_config::JsValue::NULL, - &wasm_config::JsValue::from_str(&data), - ) - .unwrap(); - }) - as Box); - - ws_clone.set_onmessage(Some(onmessage.as_ref().unchecked_ref())); - onmessage.forget(); - - // Clone reject again for the onerror closure - let reject_clone_for_error = reject_clone.clone(); - - let onerror = - wasm_config::Closure::wrap(Box::new(move |event: wasm_config::JsValue| { - let error_msg = event - .as_string() - .unwrap_or_else(|| "WebSocket error".to_string()); - reject_clone_for_error - .call1( - &wasm_config::JsValue::NULL, - &wasm_config::JsValue::from_str(&error_msg), - ) - .unwrap(); - }) - as Box); - - ws_clone.set_onerror(Some(onerror.as_ref().unchecked_ref())); - onerror.forget(); - } - }) as Box); - - ws.set_onopen(Some(onopen.as_ref().unchecked_ref())); - onopen.forget(); - }); - - let js_future = wasm_config::JsFuture::from(wasm_config::Promise::resolve(&promise)); - let onmessage = js_future - .await - .map_err(|e| Error::Response(format!("Failed to receive message: {:?}", e)))?; - - // Cast the result to a MessageEvent - let message_event = onmessage - .dyn_into::() - .map_err(|_| Error::Response("Failed to cast to MessageEvent".to_string()))?; - - // Extract the response data as a string - let data = message_event - .data() - .as_string() - .ok_or_else(|| Error::Response("Failed to parse response data".to_string()))?; + // let ws: wasm_config::JsValue = if is_node() { + // In Node.js, use the 'ws' WebSocket library via require + let ws_module = load_ws_module(); + // log(&format!("{:?}", ws_module.uwnrap())); + + // ws_module + // .dyn_into::() + // .map_err(|_| { + // Error::WebSocketCreation("Failed to cast ws module to function".to_string()) + // })? + // .call1( + // &wasm_bindgen::JsValue::NULL, + // &wasm_config::JsString::from(ws_url.as_str()), + // ) + // .map_err(|_| Error::WebSocketCreation("Failed to create WebSocket".to_string()))? + + // } else { + // // In the browser, use the native WebSocket + // wasm_config::WebSocket::new(&ws_url) + // .map_err(|e| Error::WebSocketCreation(format!("Failed to create WebSocket: {:?}", e)))? + // .into() // Cast the WebSocket to a JsValue for consistency + // }; + + // // Create a promise to handle incoming WebSocket messages + // let promise = wasm_config::Promise::new(&mut |resolve, reject| { + // let ws_clone = ws.clone(); + // let payload_clone = payload.clone(); + + // // Set up onopen, onmessage, and onerror handlers + // let onopen = wasm_config::Closure::wrap(Box::new(move || { + // // Convert payload to JsValue using gloo_utils::format::JsValueSerdeExt + // let payload_js_value = wasm_config::JsValue::from_serde(&payload_clone).unwrap(); + + // if let Err(e) = js_sys::Reflect::get(&ws_clone, &wasm_config::JsString::from("send")) + // .unwrap() + // .dyn_into::() + // .unwrap() + // .call1(&ws_clone, &payload_js_value) + // { + // reject + // .call1( + // &wasm_bindgen::JsValue::NULL, + // &wasm_bindgen::JsValue::from_str(&format!( + // "Failed to send message: {:?}", + // e + // )), + // ) + // .unwrap(); + // } else { + // let resolve_clone = resolve.clone(); + // let onmessage = + // wasm_config::Closure::wrap(Box::new(move |event: wasm_config::MessageEvent| { + // let data = event.data().as_string().unwrap_or_default(); + // resolve_clone + // .call1( + // &wasm_bindgen::JsValue::NULL, + // &wasm_bindgen::JsValue::from_str(&data), + // ) + // .unwrap(); + // }) as Box); + + // let ws_ref = ws_clone.unchecked_ref::(); + // ws_ref.set_onmessage(Some(onmessage.as_ref().unchecked_ref())); + // onmessage.forget(); + + // let reject_clone = reject.clone(); + // let onerror = + // wasm_config::Closure::wrap(Box::new(move |event: wasm_bindgen::JsValue| { + // let error_msg = event + // .as_string() + // .unwrap_or_else(|| "WebSocket error".to_string()); + // reject_clone + // .call1( + // &wasm_bindgen::JsValue::NULL, + // &wasm_bindgen::JsValue::from_str(&error_msg), + // ) + // .unwrap(); + // }) as Box); + + // ws_ref.set_onerror(Some(onerror.as_ref().unchecked_ref())); + // onerror.forget(); + // } + // }) as Box); + + // let ws_ref = ws.unchecked_ref::(); + // ws_ref.set_onopen(Some(onopen.as_ref().unchecked_ref())); + // onopen.forget(); + // }); + + // let js_future = wasm_config::JsFuture::from(js_sys::Promise::resolve(&promise)); + // let onmessage = js_future + // .await + // .map_err(|e| Error::Response(format!("Failed to receive message: {:?}", e)))?; + + // // Cast the result to a MessageEvent + // let message_event = onmessage + // .dyn_into::() + // .map_err(|_| Error::Response("Failed to cast to MessageEvent".to_string()))?; + + // // Extract the response data as a string + // let data = message_event + // .data() + // .as_string() + // .ok_or_else(|| Error::Response("Failed to parse response data".to_string()))?; // Process the response - let response = process_response(data.as_bytes().to_vec(), request_id).await?; + let response = process_response(vec![], request_id).await?; Ok(response) } @@ -257,20 +337,20 @@ async fn process_response( const REQUEST_ID_START: usize = 0; const REQUEST_ID_END: usize = REQUEST_ID_START + 2; - // Extract Request ID from the response - let _request_id = u16::from_le_bytes( - response_buf[REQUEST_ID_START..REQUEST_ID_END] - .try_into() - .expect("Failed to extract Request ID"), - ); - - // Check if request_id matches _request_id and return an error if not - if request_id != _request_id { - return Err(Error::Response(format!( - "Request ID mismatch: expected {}, got {}", - request_id, _request_id - ))); - } + // // Extract Request ID from the response + // let _request_id = u16::from_le_bytes( + // response_buf[REQUEST_ID_START..REQUEST_ID_END] + // .try_into() + // .expect("Failed to extract Request ID"), + // ); + + // // Check if request_id matches _request_id and return an error if not + // if request_id != _request_id { + // return Err(Error::Response(format!( + // "Request ID mismatch: expected {}, got {}", + // request_id, _request_id + // ))); + // } // Deserialize the remaining response data let response: BinaryResponseAndRequest = bytesrepr::deserialize_from_slice(response_buf)?; From b82f1735226ea8b61d6a998e0ed83de91213569e Mon Sep 17 00:00:00 2001 From: gRoussac Date: Mon, 21 Oct 2024 12:00:13 +0200 Subject: [PATCH 04/32] Change cargo toml --- Cargo.lock | 341 +++++++++++++++++----------------- binary_port_access/Cargo.toml | 4 +- 2 files changed, 172 insertions(+), 173 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ef35f65..4807fd1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "addr2line" -version = "0.24.1" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5fb1d8e4442bd405fdfd1dacb42792696b0cf9cb15882e5d097b742a676d375" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" dependencies = [ "gimli", ] @@ -77,9 +77,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "backtrace" @@ -93,7 +93,7 @@ dependencies = [ "miniz_oxide", "object", "rustc-demangle", - "windows-targets 0.52.6", + "windows-targets", ] [[package]] @@ -175,18 +175,35 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.7.1" +version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" +checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" [[package]] name = "casper-binary-port" version = "1.0.0" -source = "git+https://github.com/casper-network/casper-node?branch=rustSDK-feat-2.0#45bd9e57ce71b0bbd82d8e05455466cd3fc867f3" +source = "git+https://github.com/casper-network/casper-node.git?branch=feat-2.0#1ab1ff8098119d5984dd43de0f0680a869dc95ff" dependencies = [ "bincode", "bytes", - "casper-types", + "casper-types 5.0.0 (git+https://github.com/casper-network/casper-node.git?branch=feat-2.0)", + "once_cell", + "rand", + "schemars", + "serde", + "serde-map-to-array", + "thiserror", + "tokio-util", +] + +[[package]] +name = "casper-binary-port" +version = "1.0.0" +source = "git+https://github.com/casper-network/casper-node?branch=rustSDK-feat-2.0#1c4ac1d5339bf9940aeadec14d81e97ede8e1c40" +dependencies = [ + "bincode", + "bytes", + "casper-types 5.0.0 (git+https://github.com/casper-network/casper-node?branch=rustSDK-feat-2.0)", "once_cell", "rand", "schemars", @@ -200,8 +217,8 @@ dependencies = [ name = "casper-binary-port-access" version = "0.1.0" dependencies = [ - "casper-binary-port", - "casper-types", + "casper-binary-port 1.0.0 (git+https://github.com/casper-network/casper-node.git?branch=feat-2.0)", + "casper-types 5.0.0 (git+https://github.com/casper-network/casper-node.git?branch=feat-2.0)", "futures", "js-sys", "rand", @@ -216,9 +233,9 @@ dependencies = [ name = "casper-binary-port-client" version = "0.1.0" dependencies = [ - "casper-binary-port", + "casper-binary-port 1.0.0 (git+https://github.com/casper-network/casper-node?branch=rustSDK-feat-2.0)", "casper-binary-port-access", - "casper-types", + "casper-types 5.0.0 (git+https://github.com/casper-network/casper-node?branch=rustSDK-feat-2.0)", "clap", "erased-serde", "hex", @@ -231,7 +248,46 @@ dependencies = [ [[package]] name = "casper-types" version = "5.0.0" -source = "git+https://github.com/casper-network/casper-node?branch=rustSDK-feat-2.0#45bd9e57ce71b0bbd82d8e05455466cd3fc867f3" +source = "git+https://github.com/casper-network/casper-node.git?branch=feat-2.0#1ab1ff8098119d5984dd43de0f0680a869dc95ff" +dependencies = [ + "base16", + "base64", + "bitflags 1.3.2", + "blake2", + "datasize", + "derive_more", + "derp", + "ed25519-dalek", + "getrandom", + "hex", + "hex_fmt", + "humantime", + "itertools", + "k256", + "libc", + "num", + "num-derive", + "num-integer", + "num-rational", + "num-traits", + "once_cell", + "pem", + "rand", + "schemars", + "serde", + "serde-map-to-array", + "serde_bytes", + "serde_json", + "thiserror", + "tracing", + "uint", + "untrusted", +] + +[[package]] +name = "casper-types" +version = "5.0.0" +source = "git+https://github.com/casper-network/casper-node?branch=rustSDK-feat-2.0#1c4ac1d5339bf9940aeadec14d81e97ede8e1c40" dependencies = [ "base16", "base64", @@ -275,9 +331,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.5.17" +version = "4.5.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e5a21b8495e732f1b3c364c9949b201ca7bae518c502c80256c96ad79eaf6ac" +checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" dependencies = [ "clap_builder", "clap_derive", @@ -285,9 +341,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.17" +version = "4.5.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cf2dd12af7a047ad9d6da2b6b249759a22a7abc0f474c1dae1777afa4b21a73" +checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" dependencies = [ "anstream", "anstyle", @@ -298,14 +354,14 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.13" +version = "4.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0" +checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.82", ] [[package]] @@ -403,7 +459,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.82", ] [[package]] @@ -446,7 +502,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn 2.0.77", + "syn 2.0.82", ] [[package]] @@ -590,9 +646,9 @@ checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" [[package]] name = "futures" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" dependencies = [ "futures-channel", "futures-core", @@ -605,9 +661,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ "futures-core", "futures-sink", @@ -615,15 +671,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" [[package]] name = "futures-executor" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" dependencies = [ "futures-core", "futures-task", @@ -632,38 +688,38 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" [[package]] name = "futures-macro" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.82", ] [[package]] name = "futures-sink" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" [[package]] name = "futures-task" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" [[package]] name = "futures-util" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ "futures-channel", "futures-core", @@ -703,9 +759,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.31.0" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" [[package]] name = "group" @@ -726,9 +782,9 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "hashbrown" -version = "0.14.5" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" [[package]] name = "heck" @@ -782,12 +838,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5" +checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "equivalent", - "hashbrown 0.14.5", + "hashbrown 0.15.0", ] [[package]] @@ -813,18 +869,18 @@ checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "js-sys" -version = "0.3.70" +version = "0.3.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" +checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" dependencies = [ "wasm-bindgen", ] [[package]] name = "k256" -version = "0.13.3" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "956ff9b67e26e1a6a866cb758f12c6f8746208489e3e4a4b5580802f2f0a587b" +checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b" dependencies = [ "cfg-if", "ecdsa", @@ -834,9 +890,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.158" +version = "0.2.161" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" +checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" [[package]] name = "linux-raw-sys" @@ -918,7 +974,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.82", ] [[package]] @@ -964,18 +1020,18 @@ dependencies = [ [[package]] name = "object" -version = "0.36.4" +version = "0.36.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "084f1a5821ac4c651660a94a7153d27ac9d8a53736203f58b31945ded098070a" +checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.19.0" +version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] name = "opaque-debug" @@ -1027,9 +1083,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.86" +version = "1.0.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +checksum = "7c3a7fc5db1e57d5a779a352c8cdb57b29aa4c40cc69c3a68a7fedc815fbf2f9" dependencies = [ "unicode-ident", ] @@ -1075,9 +1131,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.6" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" +checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8" dependencies = [ "aho-corasick", "memchr", @@ -1087,9 +1143,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" dependencies = [ "aho-corasick", "memchr", @@ -1098,9 +1154,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "rfc6979" @@ -1168,7 +1224,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn 2.0.77", + "syn 2.0.82", ] [[package]] @@ -1226,7 +1282,7 @@ checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.82", ] [[package]] @@ -1237,16 +1293,16 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.82", ] [[package]] name = "serde_json" -version = "1.0.128" +version = "1.0.132" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" +checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" dependencies = [ - "indexmap 2.5.0", + "indexmap 2.6.0", "itoa", "memchr", "ryu", @@ -1334,9 +1390,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.77" +version = "2.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" +checksum = "83540f837a8afc019423a8edb95b52a8effe46957ee402287f4292fae35be021" dependencies = [ "proc-macro2", "quote", @@ -1345,32 +1401,32 @@ dependencies = [ [[package]] name = "terminal_size" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7" +checksum = "4f599bd7ca042cfdf8f4512b277c02ba102247820f9d9d4a9f521f496751a6ef" dependencies = [ "rustix", - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] name = "thiserror" -version = "1.0.63" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" +checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.63" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" +checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.82", ] [[package]] @@ -1397,7 +1453,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.82", ] [[package]] @@ -1486,9 +1542,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" +checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" dependencies = [ "cfg-if", "once_cell", @@ -1497,24 +1553,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" +checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.82", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.43" +version = "0.4.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61e9300f63a621e96ed275155c108eb6f843b6a26d053f122ab69724559dc8ed" +checksum = "cc7ec4f8827a71586374db3e87abdb5a2bb3a15afed140221307c3ec06b1f63b" dependencies = [ "cfg-if", "js-sys", @@ -1524,9 +1580,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" +checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1534,64 +1590,49 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" +checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.82", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" +checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" [[package]] name = "web-sys" -version = "0.3.70" +version = "0.3.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0" +checksum = "f6488b90108c040df0fe62fa815cbdee25124641df01814dd7282749234c6112" dependencies = [ "js-sys", "wasm-bindgen", ] -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets 0.48.5", -] - [[package]] name = "windows-sys" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.6", + "windows-targets", ] [[package]] -name = "windows-targets" -version = "0.48.5" +name = "windows-sys" +version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", + "windows-targets", ] [[package]] @@ -1600,46 +1641,28 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", "windows_i686_gnullvm", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - [[package]] name = "windows_aarch64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - [[package]] name = "windows_i686_gnu" version = "0.52.6" @@ -1652,48 +1675,24 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - [[package]] name = "windows_x86_64_msvc" version = "0.52.6" @@ -1718,7 +1717,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.82", ] [[package]] diff --git a/binary_port_access/Cargo.toml b/binary_port_access/Cargo.toml index 2edb2f0..b67883a 100644 --- a/binary_port_access/Cargo.toml +++ b/binary_port_access/Cargo.toml @@ -12,8 +12,8 @@ name = "casper_binary_port_access" path = "src/lib.rs" [dependencies] -casper-types = { git = "https://github.com/casper-network/casper-node.git", default-features = false, branch = "rustSDK-feat-2.0" } -casper-binary-port = { git = "https://github.com/casper-network/casper-node.git", branch = "rustSDK-feat-2.0" } +casper-types = { git = "https://github.com/casper-network/casper-node.git", default-features = false, branch = "feat-2.0" } +casper-binary-port = { git = "https://github.com/casper-network/casper-node.git", branch = "feat-2.0" } thiserror = "1" futures = "0" rand = { version = "0.8.5", default-features = false } From a6a5ea0cdad5ffb6e85aa0c3f644cd981fa04389 Mon Sep 17 00:00:00 2001 From: gRoussac Date: Mon, 21 Oct 2024 12:06:06 +0200 Subject: [PATCH 05/32] Update cargo toml --- Cargo.lock | 70 ++++++------------------------------------------------ Cargo.toml | 4 ++-- 2 files changed, 9 insertions(+), 65 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4807fd1..efe35fd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -182,28 +182,11 @@ checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" [[package]] name = "casper-binary-port" version = "1.0.0" -source = "git+https://github.com/casper-network/casper-node.git?branch=feat-2.0#1ab1ff8098119d5984dd43de0f0680a869dc95ff" +source = "git+https://github.com/casper-network/casper-node?branch=feat-2.0#1ab1ff8098119d5984dd43de0f0680a869dc95ff" dependencies = [ "bincode", "bytes", - "casper-types 5.0.0 (git+https://github.com/casper-network/casper-node.git?branch=feat-2.0)", - "once_cell", - "rand", - "schemars", - "serde", - "serde-map-to-array", - "thiserror", - "tokio-util", -] - -[[package]] -name = "casper-binary-port" -version = "1.0.0" -source = "git+https://github.com/casper-network/casper-node?branch=rustSDK-feat-2.0#1c4ac1d5339bf9940aeadec14d81e97ede8e1c40" -dependencies = [ - "bincode", - "bytes", - "casper-types 5.0.0 (git+https://github.com/casper-network/casper-node?branch=rustSDK-feat-2.0)", + "casper-types", "once_cell", "rand", "schemars", @@ -217,8 +200,8 @@ dependencies = [ name = "casper-binary-port-access" version = "0.1.0" dependencies = [ - "casper-binary-port 1.0.0 (git+https://github.com/casper-network/casper-node.git?branch=feat-2.0)", - "casper-types 5.0.0 (git+https://github.com/casper-network/casper-node.git?branch=feat-2.0)", + "casper-binary-port", + "casper-types", "futures", "js-sys", "rand", @@ -233,9 +216,9 @@ dependencies = [ name = "casper-binary-port-client" version = "0.1.0" dependencies = [ - "casper-binary-port 1.0.0 (git+https://github.com/casper-network/casper-node?branch=rustSDK-feat-2.0)", + "casper-binary-port", "casper-binary-port-access", - "casper-types 5.0.0 (git+https://github.com/casper-network/casper-node?branch=rustSDK-feat-2.0)", + "casper-types", "clap", "erased-serde", "hex", @@ -248,46 +231,7 @@ dependencies = [ [[package]] name = "casper-types" version = "5.0.0" -source = "git+https://github.com/casper-network/casper-node.git?branch=feat-2.0#1ab1ff8098119d5984dd43de0f0680a869dc95ff" -dependencies = [ - "base16", - "base64", - "bitflags 1.3.2", - "blake2", - "datasize", - "derive_more", - "derp", - "ed25519-dalek", - "getrandom", - "hex", - "hex_fmt", - "humantime", - "itertools", - "k256", - "libc", - "num", - "num-derive", - "num-integer", - "num-rational", - "num-traits", - "once_cell", - "pem", - "rand", - "schemars", - "serde", - "serde-map-to-array", - "serde_bytes", - "serde_json", - "thiserror", - "tracing", - "uint", - "untrusted", -] - -[[package]] -name = "casper-types" -version = "5.0.0" -source = "git+https://github.com/casper-network/casper-node?branch=rustSDK-feat-2.0#1c4ac1d5339bf9940aeadec14d81e97ede8e1c40" +source = "git+https://github.com/casper-network/casper-node?branch=feat-2.0#1ab1ff8098119d5984dd43de0f0680a869dc95ff" dependencies = [ "base16", "base64", diff --git a/Cargo.toml b/Cargo.toml index 74986b6..0a206ce 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,10 +11,10 @@ description = "CLI for Casper binary port." license = "Apache-2.0" [dependencies] -casper-types = { git = "https://github.com/casper-network/casper-node.git", branch = "rustSDK-feat-2.0", features = [ +casper-types = { git = "https://github.com/casper-network/casper-node.git", branch = "feat-2.0", features = [ "std-fs-io", ] } -casper-binary-port = { version = "1.0.0", git = "https://github.com/casper-network/casper-node", branch = "rustSDK-feat-2.0" } +casper-binary-port = { version = "1.0.0", git = "https://github.com/casper-network/casper-node", branch = "feat-2.0" } casper-binary-port-access = { path = "./binary_port_access" } clap = { version = "4.5.3", features = ["derive", "wrap_help"] } thiserror = "1" From 82622f6d51195d77be1aff967a589d264e5afbc6 Mon Sep 17 00:00:00 2001 From: gRoussac Date: Mon, 21 Oct 2024 12:13:07 +0200 Subject: [PATCH 06/32] typo --- binary_port_access/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/binary_port_access/Cargo.toml b/binary_port_access/Cargo.toml index 7d163a4..898c986 100644 --- a/binary_port_access/Cargo.toml +++ b/binary_port_access/Cargo.toml @@ -15,7 +15,7 @@ path = "src/lib.rs" casper-types = { git = "https://github.com/casper-network/casper-node", default-features = false, branch = "feat-2.0" } casper-binary-port = { git = "https://github.com/casper-network/casper-node", branch = "feat-2.0" } thiserror = "1" -futures = "0" +futures = "0.3.31" rand = { version = "0.8.5", default-features = false } [target.'cfg(target_arch = "wasm32")'.dependencies] From 0591bc5ada1ec9e1fac5d86abc69ad87a25f6192 Mon Sep 17 00:00:00 2001 From: gRoussac Date: Tue, 22 Oct 2024 13:14:32 +0200 Subject: [PATCH 07/32] stash --- Cargo.lock | 4 ++-- Cargo.toml | 4 ++-- binary_port_access/Cargo.toml | 4 ++-- binary_port_access/src/communication.rs | 18 +++++++++++------- 4 files changed, 17 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e3b6faf..8d37147 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -182,7 +182,7 @@ checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" [[package]] name = "casper-binary-port" version = "1.0.0" -source = "git+https://github.com/casper-network/casper-node?branch=rustSDK-feat-2.0#45bd9e57ce71b0bbd82d8e05455466cd3fc867f3" +source = "git+https://github.com/casper-network/casper-node?branch=feat-2.0#79714924f7a83d98e0d3037fef60fcb66ce4ef54" dependencies = [ "bincode", "bytes", @@ -232,7 +232,7 @@ dependencies = [ [[package]] name = "casper-types" version = "5.0.0" -source = "git+https://github.com/casper-network/casper-node?branch=rustSDK-feat-2.0#45bd9e57ce71b0bbd82d8e05455466cd3fc867f3" +source = "git+https://github.com/casper-network/casper-node?branch=feat-2.0#79714924f7a83d98e0d3037fef60fcb66ce4ef54" dependencies = [ "base16", "base64", diff --git a/Cargo.toml b/Cargo.toml index 74986b6..0a206ce 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,10 +11,10 @@ description = "CLI for Casper binary port." license = "Apache-2.0" [dependencies] -casper-types = { git = "https://github.com/casper-network/casper-node.git", branch = "rustSDK-feat-2.0", features = [ +casper-types = { git = "https://github.com/casper-network/casper-node.git", branch = "feat-2.0", features = [ "std-fs-io", ] } -casper-binary-port = { version = "1.0.0", git = "https://github.com/casper-network/casper-node", branch = "rustSDK-feat-2.0" } +casper-binary-port = { version = "1.0.0", git = "https://github.com/casper-network/casper-node", branch = "feat-2.0" } casper-binary-port-access = { path = "./binary_port_access" } clap = { version = "4.5.3", features = ["derive", "wrap_help"] } thiserror = "1" diff --git a/binary_port_access/Cargo.toml b/binary_port_access/Cargo.toml index a9c2b6a..c6ea0aa 100644 --- a/binary_port_access/Cargo.toml +++ b/binary_port_access/Cargo.toml @@ -12,8 +12,8 @@ name = "casper_binary_port_access" path = "src/lib.rs" [dependencies] -casper-types = { git = "https://github.com/casper-network/casper-node.git", default-features = false, branch = "rustSDK-feat-2.0" } -casper-binary-port = { git = "https://github.com/casper-network/casper-node.git", branch = "rustSDK-feat-2.0" } +casper-types = { git = "https://github.com/casper-network/casper-node.git", default-features = false, branch = "feat-2.0" } +casper-binary-port = { git = "https://github.com/casper-network/casper-node.git", branch = "feat-2.0" } thiserror = "1" futures = "0" rand = { version = "0.8.5", default-features = false } diff --git a/binary_port_access/src/communication.rs b/binary_port_access/src/communication.rs index e64ed97..6862d73 100644 --- a/binary_port_access/src/communication.rs +++ b/binary_port_access/src/communication.rs @@ -99,9 +99,11 @@ pub(crate) async fn send_request( process_response(response_buf, request_id).await } +// TODO Documentation +/// DOC #[cfg(target_arch = "wasm32")] #[wasm_bindgen] -fn is_node() -> bool { +pub fn is_node() -> bool { // Check if 'process' exists and if it has 'versions' property (which is present in Node.js) let is_node = js_sys::global() .dyn_into::() @@ -123,22 +125,24 @@ fn is_node() -> bool { is_node } +// TODO Documentation +/// DOC #[cfg(target_arch = "wasm32")] #[wasm_bindgen] -pub async fn load_ws_module() -> Result { +pub async fn load_ws_module() -> Result { // Dynamically import the 'ws' module using JavaScript's import() function let import_script = "import('ws')"; // Evaluate the `import` script in the JavaScript environment - let import_promise: Promise = js_sys::eval(import_script) - .map_err(|_| JsError::new("Failed to execute import for 'ws'").into())? + let import_promise: wasm_config::Promise = js_sys::eval(import_script) + .map_err(|_| JsError::new("Failed to execute import for 'ws'"))? .dyn_into() - .map_err(|_| JsError::new("Failed to convert eval result to Promise").into())?; + .map_err(|_| JsError::new("Failed to convert eval result to Promise"))?; // Wait for the Promise to resolve and load the WebSocket module - let ws_module = JsFuture::from(import_promise) + let ws_module = wasm_config::JsFuture::from(import_promise) .await - .map_err(|_| JsError::new("Failed to load ws module via import").into())?; + .map_err(|_| JsError::new("Failed to load ws module via import"))?; // Return the WebSocket module Ok(ws_module) From 167e9c32f9f5f6f2d51af694c2cc5619b7978cd6 Mon Sep 17 00:00:00 2001 From: gRoussac Date: Tue, 22 Oct 2024 13:21:19 +0200 Subject: [PATCH 08/32] update cargo --- Cargo.lock | 191 ++++++++++++---------------------- Cargo.toml | 10 +- binary_port_access/Cargo.toml | 4 +- 3 files changed, 74 insertions(+), 131 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8d37147..f0aaf69 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -93,7 +93,7 @@ dependencies = [ "miniz_oxide", "object", "rustc-demangle", - "windows-targets 0.52.6", + "windows-targets", ] [[package]] @@ -276,9 +276,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.5.17" +version = "4.5.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e5a21b8495e732f1b3c364c9949b201ca7bae518c502c80256c96ad79eaf6ac" +checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" dependencies = [ "clap_builder", "clap_derive", @@ -286,9 +286,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.17" +version = "4.5.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cf2dd12af7a047ad9d6da2b6b249759a22a7abc0f474c1dae1777afa4b21a73" +checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" dependencies = [ "anstream", "anstyle", @@ -299,14 +299,14 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.13" +version = "4.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0" +checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.82", ] [[package]] @@ -404,7 +404,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.82", ] [[package]] @@ -447,7 +447,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn 2.0.77", + "syn 2.0.82", ] [[package]] @@ -591,9 +591,9 @@ checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" [[package]] name = "futures" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" dependencies = [ "futures-channel", "futures-core", @@ -606,9 +606,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ "futures-core", "futures-sink", @@ -616,15 +616,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" [[package]] name = "futures-executor" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" dependencies = [ "futures-core", "futures-task", @@ -633,38 +633,38 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" [[package]] name = "futures-macro" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.82", ] [[package]] name = "futures-sink" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" [[package]] name = "futures-task" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" [[package]] name = "futures-util" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ "futures-channel", "futures-core", @@ -932,7 +932,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.82", ] [[package]] @@ -1182,7 +1182,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn 2.0.77", + "syn 2.0.82", ] [[package]] @@ -1206,9 +1206,9 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.210" +version = "1.0.211" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" +checksum = "1ac55e59090389fb9f0dd9e0f3c09615afed1d19094284d0b200441f13550793" dependencies = [ "serde_derive", ] @@ -1234,13 +1234,13 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.210" +version = "1.0.211" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" +checksum = "54be4f245ce16bc58d57ef2716271d0d4519e0f6defa147f6e081005bcb278ff" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.82", ] [[package]] @@ -1251,14 +1251,14 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.82", ] [[package]] name = "serde_json" -version = "1.0.128" +version = "1.0.132" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" +checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" dependencies = [ "indexmap 2.5.0", "itoa", @@ -1348,9 +1348,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.77" +version = "2.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" +checksum = "83540f837a8afc019423a8edb95b52a8effe46957ee402287f4292fae35be021" dependencies = [ "proc-macro2", "quote", @@ -1359,39 +1359,39 @@ dependencies = [ [[package]] name = "terminal_size" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7" +checksum = "4f599bd7ca042cfdf8f4512b277c02ba102247820f9d9d4a9f521f496751a6ef" dependencies = [ "rustix", - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] name = "thiserror" -version = "1.0.63" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" +checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.63" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" +checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.82", ] [[package]] name = "tokio" -version = "1.40.0" +version = "1.41.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" +checksum = "145f3413504347a2be84393cc8a7d2fb4d863b375909ea59f2158261aa258bbb" dependencies = [ "backtrace", "bytes", @@ -1411,7 +1411,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.82", ] [[package]] @@ -1520,7 +1520,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.82", "wasm-bindgen-shared", ] @@ -1554,7 +1554,7 @@ checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.82", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -1575,37 +1575,22 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets 0.48.5", -] - [[package]] name = "windows-sys" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.6", + "windows-targets", ] [[package]] -name = "windows-targets" -version = "0.48.5" +name = "windows-sys" +version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", + "windows-targets", ] [[package]] @@ -1614,46 +1599,28 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", "windows_i686_gnullvm", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - [[package]] name = "windows_aarch64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - [[package]] name = "windows_i686_gnu" version = "0.52.6" @@ -1666,48 +1633,24 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - [[package]] name = "windows_x86_64_msvc" version = "0.52.6" @@ -1732,7 +1675,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.82", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 0a206ce..979ae77 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,10 +16,10 @@ casper-types = { git = "https://github.com/casper-network/casper-node.git", bran ] } casper-binary-port = { version = "1.0.0", git = "https://github.com/casper-network/casper-node", branch = "feat-2.0" } casper-binary-port-access = { path = "./binary_port_access" } -clap = { version = "4.5.3", features = ["derive", "wrap_help"] } -thiserror = "1" -tokio = { version = "1.40.0", features = ["macros", "rt", "net"] } +clap = { version = "4.5.20", features = ["derive", "wrap_help"] } +thiserror = "1.0.64" +tokio = { version = "1.41.0", features = ["macros", "rt", "net"] } hex = "0.4.3" -serde = { version = "1.0.203", features = ["derive"] } -serde_json = "1.0.117" +serde = { version = "1.0.211", features = ["derive"] } +serde_json = "1.0.132" erased-serde = "0.4.5" diff --git a/binary_port_access/Cargo.toml b/binary_port_access/Cargo.toml index c6ea0aa..4c94e3b 100644 --- a/binary_port_access/Cargo.toml +++ b/binary_port_access/Cargo.toml @@ -14,8 +14,8 @@ path = "src/lib.rs" [dependencies] casper-types = { git = "https://github.com/casper-network/casper-node.git", default-features = false, branch = "feat-2.0" } casper-binary-port = { git = "https://github.com/casper-network/casper-node.git", branch = "feat-2.0" } -thiserror = "1" -futures = "0" +thiserror = "1.0.64" +futures = "0.3.31" rand = { version = "0.8.5", default-features = false } [target.'cfg(target_arch = "wasm32")'.dependencies] From 5c14d1489c0bdceef92a2d62fce968d99d71ce4d Mon Sep 17 00:00:00 2001 From: gRoussac Date: Tue, 22 Oct 2024 13:39:07 +0200 Subject: [PATCH 09/32] stash --- Cargo.lock | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index efe35fd..ae31cd2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -175,14 +175,14 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.7.2" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" +checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" [[package]] name = "casper-binary-port" version = "1.0.0" -source = "git+https://github.com/casper-network/casper-node?branch=feat-2.0#1ab1ff8098119d5984dd43de0f0680a869dc95ff" +source = "git+https://github.com/casper-network/casper-node?branch=feat-2.0#79714924f7a83d98e0d3037fef60fcb66ce4ef54" dependencies = [ "bincode", "bytes", @@ -231,7 +231,7 @@ dependencies = [ [[package]] name = "casper-types" version = "5.0.0" -source = "git+https://github.com/casper-network/casper-node?branch=feat-2.0#1ab1ff8098119d5984dd43de0f0680a869dc95ff" +source = "git+https://github.com/casper-network/casper-node?branch=feat-2.0#79714924f7a83d98e0d3037fef60fcb66ce4ef54" dependencies = [ "base16", "base64", @@ -1192,9 +1192,9 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.210" +version = "1.0.211" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" +checksum = "1ac55e59090389fb9f0dd9e0f3c09615afed1d19094284d0b200441f13550793" dependencies = [ "serde_derive", ] @@ -1220,9 +1220,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.210" +version = "1.0.211" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" +checksum = "54be4f245ce16bc58d57ef2716271d0d4519e0f6defa147f6e081005bcb278ff" dependencies = [ "proc-macro2", "quote", @@ -1375,9 +1375,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.40.0" +version = "1.41.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" +checksum = "145f3413504347a2be84393cc8a7d2fb4d863b375909ea59f2158261aa258bbb" dependencies = [ "backtrace", "bytes", From a2b53288c27ee95132dad27e90c43915529c6db2 Mon Sep 17 00:00:00 2001 From: gRoussac Date: Tue, 22 Oct 2024 16:38:52 +0200 Subject: [PATCH 10/32] Add workflow --- .github/workflows/ci-cd.yml | 49 +++++++++++++++++++++++++++++++++++++ Makefile | 41 +++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+) create mode 100644 .github/workflows/ci-cd.yml create mode 100644 Makefile diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml new file mode 100644 index 0000000..6816294 --- /dev/null +++ b/.github/workflows/ci-cd.yml @@ -0,0 +1,49 @@ +name: CI Pipeline + +on: + push: + branches: + - master + - 'release/*' + pull_request: + branches: + - master + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set up Rust + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + target: wasm32-unknown-unknown + + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install -y pkg-config libssl-dev + cargo install cargo-audit + + # Build using Makefile + - name: Build the project + run: make build + + - name: Run tests + run: make test + + - name: Run Clippy linter + run: make lint + + - name: Run Clippy linter for wasm target + run: make lint-wasm + + - name: Check code formatting + run: make fmt-check + + - name: Run security audit + run: make audit diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..617c487 --- /dev/null +++ b/Makefile @@ -0,0 +1,41 @@ +# Makefile for casper-binary-port-client + +# Specify the cargo target for wasm32 +WASM_TARGET = wasm32-unknown-unknown + +# Default target (build the project) +all: build + +# Build the project +build: + cargo build + +# Run the tests +test: + cargo test --all-targets + +# Run clippy (linter) on all targets +lint: + cargo clippy --all-targets -- -D warnings + +# Run clippy on wasm32-unknown-unknown target +lint-wasm: + cd binary_port_access && cargo clippy --target $(WASM_TARGET) --all-targets -- -D warnings + +# Format the codebase using rustfmt and check for correct formatting +fmt: + cargo fmt --all -- --check + +# Check for outdated dependencies +outdated: + cargo outdated || cargo install cargo-outdated + +# Run a full CI-style check (build, fmt, clippy, test) +ci-check: fmt lint lint-wasm test + +# Clean build artifacts +clean: + cargo clean + +audit: + cargo audit From e00266b65e287c401efd40c3f23bb6e88f07159a Mon Sep 17 00:00:00 2001 From: gRoussac Date: Tue, 22 Oct 2024 16:49:19 +0200 Subject: [PATCH 11/32] workflow --- .github/workflows/ci-cd.yml | 1 - Makefile | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index 6816294..3af29a9 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -27,7 +27,6 @@ jobs: run: | sudo apt-get update sudo apt-get install -y pkg-config libssl-dev - cargo install cargo-audit # Build using Makefile - name: Build the project diff --git a/Makefile b/Makefile index 617c487..ad24a1c 100644 --- a/Makefile +++ b/Makefile @@ -23,7 +23,7 @@ lint-wasm: cd binary_port_access && cargo clippy --target $(WASM_TARGET) --all-targets -- -D warnings # Format the codebase using rustfmt and check for correct formatting -fmt: +fmt-check: cargo fmt --all -- --check # Check for outdated dependencies From f3f75cbade0fc6e3b9b8bdbd8c4f58f0d6d303ee Mon Sep 17 00:00:00 2001 From: gRoussac Date: Tue, 22 Oct 2024 17:02:21 +0200 Subject: [PATCH 12/32] workflow --- .github/workflows/ci-cd.yml | 48 +++++++++++++++++++++++++++++++++++++ Makefile | 5 +++- 2 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/ci-cd.yml diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml new file mode 100644 index 0000000..3af29a9 --- /dev/null +++ b/.github/workflows/ci-cd.yml @@ -0,0 +1,48 @@ +name: CI Pipeline + +on: + push: + branches: + - master + - 'release/*' + pull_request: + branches: + - master + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set up Rust + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + target: wasm32-unknown-unknown + + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install -y pkg-config libssl-dev + + # Build using Makefile + - name: Build the project + run: make build + + - name: Run tests + run: make test + + - name: Run Clippy linter + run: make lint + + - name: Run Clippy linter for wasm target + run: make lint-wasm + + - name: Check code formatting + run: make fmt-check + + - name: Run security audit + run: make audit diff --git a/Makefile b/Makefile index 79c8983..ad24a1c 100644 --- a/Makefile +++ b/Makefile @@ -23,7 +23,7 @@ lint-wasm: cd binary_port_access && cargo clippy --target $(WASM_TARGET) --all-targets -- -D warnings # Format the codebase using rustfmt and check for correct formatting -fmt: +fmt-check: cargo fmt --all -- --check # Check for outdated dependencies @@ -36,3 +36,6 @@ ci-check: fmt lint lint-wasm test # Clean build artifacts clean: cargo clean + +audit: + cargo audit From 91a38c90fa78c4bcb08f85d9de14d9bdd41148d4 Mon Sep 17 00:00:00 2001 From: gRoussac Date: Sun, 27 Oct 2024 18:33:04 +0100 Subject: [PATCH 13/32] node js binary com --- binary_port_access/src/communication.rs | 458 +++++++++++++++--------- 1 file changed, 286 insertions(+), 172 deletions(-) diff --git a/binary_port_access/src/communication.rs b/binary_port_access/src/communication.rs index 6862d73..4d4ce6d 100644 --- a/binary_port_access/src/communication.rs +++ b/binary_port_access/src/communication.rs @@ -8,6 +8,10 @@ use casper_types::{ bytesrepr::{self, FromBytes, ToBytes}, ProtocolVersion, }; +#[cfg(target_arch = "wasm32")] +pub use gloo_utils::format::JsValueSerdeExt; +#[cfg(target_arch = "wasm32")] +pub use js_sys::{JsString, Promise, Reflect}; use rand::Rng; #[cfg(not(target_arch = "wasm32"))] use std::time::Duration; @@ -18,22 +22,11 @@ use tokio::{ time::timeout, }; #[cfg(target_arch = "wasm32")] -pub use wasm_bindgen::JsCast; +pub use wasm_bindgen::{prelude::Closure, prelude::*, JsCast, JsValue}; #[cfg(target_arch = "wasm32")] -mod wasm_config { - pub use js_sys::Promise; - pub use wasm_bindgen::prelude::Closure; - - pub use js_sys::JsString; - pub use js_sys::Reflect; - - pub use gloo_utils::format::JsValueSerdeExt; - pub use wasm_bindgen::JsValue; - pub use wasm_bindgen_futures::JsFuture; - pub use web_sys::{MessageEvent, WebSocket}; -} +pub use wasm_bindgen_futures::JsFuture; #[cfg(target_arch = "wasm32")] -use wasm_bindgen::prelude::*; +pub use web_sys::{MessageEvent, WebSocket}; #[cfg(target_arch = "wasm32")] #[wasm_bindgen] @@ -44,9 +37,12 @@ extern "C" { /// Logs an error message, prefixing it with "error wasm" and sends it to the console in JavaScript when running in a WebAssembly environment. /// When running outside WebAssembly, it prints the error message to the standard output. pub fn log(s: &str) { + #[cfg(target_arch = "wasm32")] let prefixed_s = format!("log wasm {}", s); #[cfg(target_arch = "wasm32")] log_with_prefix(&prefixed_s); + #[cfg(not(target_arch = "wasm32"))] + println!("{}", s); } // TODO[RC]: Do not hardcode this. @@ -54,7 +50,6 @@ pub(crate) const SUPPORTED_PROTOCOL_VERSION: ProtocolVersion = ProtocolVersion:: #[cfg(not(target_arch = "wasm32"))] const TIMEOUT_DURATION: Duration = Duration::from_secs(5); -#[cfg(not(target_arch = "wasm32"))] const LENGTH_FIELD_SIZE: usize = 4; // TODO[RC]: Into "communication" module @@ -89,6 +84,7 @@ pub(crate) async fn send_request( let payload = encode_request(&request, Some(request_id)).expect("should always serialize a request"); let mut client = connect_to_node(node_address).await?; + let message = BinaryMessage::new(payload); // Send the payload length and data @@ -96,6 +92,7 @@ pub(crate) async fn send_request( // Read and process the response let response_buf = read_response(&mut client).await?; + process_response(response_buf, request_id).await } @@ -108,46 +105,18 @@ pub fn is_node() -> bool { let is_node = js_sys::global() .dyn_into::() .map(|global| { - wasm_config::Reflect::has(&global, &wasm_config::JsString::from("process")) - .unwrap_or(false) - && wasm_config::Reflect::get(&global, &wasm_config::JsString::from("process")) + Reflect::has(&global, &JsString::from("process")).unwrap_or(false) + && Reflect::get(&global, &JsString::from("process")) .map(|process| { - wasm_config::Reflect::has( - &process, - &wasm_config::JsString::from("versions"), - ) - .unwrap_or(false) + Reflect::has(&process, &JsString::from("versions")).unwrap_or(false) }) .unwrap_or(false) }) .unwrap_or(false); - + // log(&format!("is_node {:?}", is_node)); is_node } -// TODO Documentation -/// DOC -#[cfg(target_arch = "wasm32")] -#[wasm_bindgen] -pub async fn load_ws_module() -> Result { - // Dynamically import the 'ws' module using JavaScript's import() function - let import_script = "import('ws')"; - - // Evaluate the `import` script in the JavaScript environment - let import_promise: wasm_config::Promise = js_sys::eval(import_script) - .map_err(|_| JsError::new("Failed to execute import for 'ws'"))? - .dyn_into() - .map_err(|_| JsError::new("Failed to convert eval result to Promise"))?; - - // Wait for the Promise to resolve and load the WebSocket module - let ws_module = wasm_config::JsFuture::from(import_promise) - .await - .map_err(|_| JsError::new("Failed to load ws module via import"))?; - - // Return the WebSocket module - Ok(ws_module) -} - #[cfg(target_arch = "wasm32")] pub(crate) async fn send_request( node_address: &str, @@ -157,120 +126,239 @@ pub(crate) async fn send_request( let payload = encode_request(&request, Some(request_id)) .map_err(|e| Error::Serialization(format!("Failed to serialize request: {}", e)))?; - let ws_url = if node_address.starts_with("ws://") || node_address.starts_with("wss://") { - node_address.to_string() + if is_node() { + // In Node.js, use raw TCP with the `net` module for direct connection + let tcp_result = open_tcp_connection(node_address, payload.clone(), request_id).await; + match tcp_result { + Ok(response) => return Ok(response), + Err(e) => return Err(Error::Response(format!("TCP connection failed: {:?}", e))), + } } else { - format!("ws://{}", node_address) - }; - - // let ws: wasm_config::JsValue = if is_node() { - // In Node.js, use the 'ws' WebSocket library via require - let ws_module = load_ws_module(); - // log(&format!("{:?}", ws_module.uwnrap())); - - // ws_module - // .dyn_into::() - // .map_err(|_| { - // Error::WebSocketCreation("Failed to cast ws module to function".to_string()) - // })? - // .call1( - // &wasm_bindgen::JsValue::NULL, - // &wasm_config::JsString::from(ws_url.as_str()), - // ) - // .map_err(|_| Error::WebSocketCreation("Failed to create WebSocket".to_string()))? - - // } else { - // // In the browser, use the native WebSocket - // wasm_config::WebSocket::new(&ws_url) - // .map_err(|e| Error::WebSocketCreation(format!("Failed to create WebSocket: {:?}", e)))? - // .into() // Cast the WebSocket to a JsValue for consistency - // }; - - // // Create a promise to handle incoming WebSocket messages - // let promise = wasm_config::Promise::new(&mut |resolve, reject| { - // let ws_clone = ws.clone(); - // let payload_clone = payload.clone(); - - // // Set up onopen, onmessage, and onerror handlers - // let onopen = wasm_config::Closure::wrap(Box::new(move || { - // // Convert payload to JsValue using gloo_utils::format::JsValueSerdeExt - // let payload_js_value = wasm_config::JsValue::from_serde(&payload_clone).unwrap(); - - // if let Err(e) = js_sys::Reflect::get(&ws_clone, &wasm_config::JsString::from("send")) - // .unwrap() - // .dyn_into::() - // .unwrap() - // .call1(&ws_clone, &payload_js_value) - // { - // reject - // .call1( - // &wasm_bindgen::JsValue::NULL, - // &wasm_bindgen::JsValue::from_str(&format!( - // "Failed to send message: {:?}", - // e - // )), - // ) - // .unwrap(); - // } else { - // let resolve_clone = resolve.clone(); - // let onmessage = - // wasm_config::Closure::wrap(Box::new(move |event: wasm_config::MessageEvent| { - // let data = event.data().as_string().unwrap_or_default(); - // resolve_clone - // .call1( - // &wasm_bindgen::JsValue::NULL, - // &wasm_bindgen::JsValue::from_str(&data), - // ) - // .unwrap(); - // }) as Box); - - // let ws_ref = ws_clone.unchecked_ref::(); - // ws_ref.set_onmessage(Some(onmessage.as_ref().unchecked_ref())); - // onmessage.forget(); - - // let reject_clone = reject.clone(); - // let onerror = - // wasm_config::Closure::wrap(Box::new(move |event: wasm_bindgen::JsValue| { - // let error_msg = event - // .as_string() - // .unwrap_or_else(|| "WebSocket error".to_string()); - // reject_clone - // .call1( - // &wasm_bindgen::JsValue::NULL, - // &wasm_bindgen::JsValue::from_str(&error_msg), - // ) - // .unwrap(); - // }) as Box); - - // ws_ref.set_onerror(Some(onerror.as_ref().unchecked_ref())); - // onerror.forget(); - // } - // }) as Box); - - // let ws_ref = ws.unchecked_ref::(); - // ws_ref.set_onopen(Some(onopen.as_ref().unchecked_ref())); - // onopen.forget(); - // }); - - // let js_future = wasm_config::JsFuture::from(js_sys::Promise::resolve(&promise)); - // let onmessage = js_future - // .await - // .map_err(|e| Error::Response(format!("Failed to receive message: {:?}", e)))?; - - // // Cast the result to a MessageEvent - // let message_event = onmessage - // .dyn_into::() - // .map_err(|_| Error::Response("Failed to cast to MessageEvent".to_string()))?; - - // // Extract the response data as a string - // let data = message_event - // .data() - // .as_string() - // .ok_or_else(|| Error::Response("Failed to parse response data".to_string()))?; + // In the browser or non-Node.js environments, use WebSocket + let ws_url = format!("ws://{}", node_address); + let web_socket = WebSocket::new(&ws_url).map_err(|e| { + Error::WebSocketCreation(format!("Failed to create WebSocket: {:?}", e)) + })?; + + let response = handle_websocket_connection(web_socket, payload, request_id).await?; + return Ok(response); + } +} - // Process the response - let response = process_response(vec![], request_id).await?; +#[cfg(target_arch = "wasm32")] +async fn open_tcp_connection( + node_address: &str, + payload: Vec, + request_id: u16, +) -> Result { + let tcp_script = format!( + r#" +(async () => {{ + try {{ + const net = require('net'); + const client = new net.Socket(); + const payload = Buffer.from({:?}); + const node_address = '{node_address}'; + const [host, port] = node_address.split(':'); + + // console.log('TCP Client created:'); + // console.log('Payload to send:', payload); + // console.log('node_address', node_address); + // console.log('host', host); + // console.log('port', port); + // console.log('Promise available:', typeof Promise !== 'undefined'); + + return new Promise((resolve, reject) => {{ + // console.log('Connecting to TCP server at', host, port); + + const lengthBuffer = Buffer.alloc(4); + lengthBuffer.writeUInt32LE(payload.length); + client.connect(parseInt(port), host, () => {{ + // console.log('Connected to TCP server'); + + // First, send the length of the payload + client.write(lengthBuffer, (err) => {{ + if (err) {{ + console.error('Error sending length:', err.message); + client.destroy(); + return; + }} + // console.log('Length of payload sent'); + + // Now, send the actual payload + client.write(payload, (err) => {{ + if (err) {{ + console.error('Error sending payload:', err.message); + }} else {{ + // console.log('Payload sent'); + }} + }}); + }}); + }}); + + client.on('data', (data) => {{ + // console.log('Data received from server:', data); + resolve(data); + client.destroy(); // Close connection after receiving response + }}); + + client.on('error', (err) => {{ + console.error('TCP connection error:', err.message); + reject(new Error('TCP connection error: ' + err.message)); + }}); + + client.on('close', () => {{ + // console.log('TCP connection closed'); + }}); + }}); + }} catch (err) {{ + console.error('Error in TCP script:', err.message); + throw new Error('Script execution error: ' + err.message); + }} +}})(); + "#, + payload + ); + // Execute the script in JavaScript context using eval + let tcp_promise: Promise = js_sys::eval(&tcp_script) + .map_err(|err| { + log("Failed to execute TCP script in eval"); + log(&err.as_string().unwrap()); + Error::Response("Failed to execute TCP script".to_string()) + })? + .dyn_into() + .map_err(|err| { + log("Failed to cast eval result to Promise"); + log(&err.as_string().unwrap()); + Error::Response("Failed to cast eval result to Promise".to_string()) + })?; + + let js_future = JsFuture::from(tcp_promise); + let tcp_response = js_future + .await + .map_err(|e| Error::Response(format!("TCP connection promise failed: {:?}", e)))?; + + // Since the resolved value is a Buffer, convert it to a byte slice + let response_bytes = js_sys::Uint8Array::new(&tcp_response).to_vec(); + + // Log the received response bytes for debugging + // log(&format!("Received response data: {:?}", response_bytes)); + + // Read and process the response + let response_buf = read_response(response_bytes).await?; + // Now process the response using the request_id + process_response(response_buf.into(), request_id).await +} + +#[cfg(target_arch = "wasm32")] +async fn handle_websocket_connection( + web_socket: WebSocket, + payload: Vec, + request_id: u16, +) -> Result { + let promise = Promise::new(&mut |resolve, reject| { + let ws_clone = web_socket.clone(); + let payload_clone = payload.clone(); + + // Set up onopen, onmessage, and onerror handlers + let onopen = Closure::wrap(Box::new(move || { + log("WebSocket connection opened, attempting to send payload."); + + // Convert payload to JsValue using gloo_utils::format::JsValueSerdeExt + let payload_js_value = wasm_bindgen::JsValue::from_serde(&payload_clone).unwrap(); + log("Payload serialized to JsValue."); + + // Send payload + match js_sys::Reflect::get(&ws_clone, &JsString::from("send")) + .and_then(|send_func| send_func.dyn_into::()) + { + Ok(send_func) => { + if let Err(e) = send_func.call1(&ws_clone, &payload_js_value) { + log(&format!("Failed to send payload: {:?}", e)); + reject + .call1( + &wasm_bindgen::JsValue::NULL, + &wasm_bindgen::JsValue::from_str(&format!( + "Failed to send message: {:?}", + e + )), + ) + .unwrap(); + } else { + log("Payload sent successfully, setting up message handler."); + + let resolve_clone = resolve.clone(); + let onmessage = Closure::wrap(Box::new(move |event: MessageEvent| { + log("Message received from WebSocket."); + + let data = event.data().as_string().unwrap_or_default(); + resolve_clone + .call1( + &wasm_bindgen::JsValue::NULL, + &wasm_bindgen::JsValue::from_str(&data), + ) + .unwrap(); + }) + as Box); + + let ws_ref = ws_clone.unchecked_ref::(); + ws_ref.set_onmessage(Some(onmessage.as_ref().unchecked_ref())); + onmessage.forget(); + + let reject_clone = reject.clone(); + let onerror = Closure::wrap(Box::new(move |event: wasm_bindgen::JsValue| { + let error_msg = event + .as_string() + .unwrap_or_else(|| "WebSocket error".to_string()); + log(&format!("WebSocket error: {}", error_msg)); + reject_clone + .call1( + &wasm_bindgen::JsValue::NULL, + &wasm_bindgen::JsValue::from_str(&error_msg), + ) + .unwrap(); + }) + as Box); + + ws_ref.set_onerror(Some(onerror.as_ref().unchecked_ref())); + onerror.forget(); + } + } + Err(e) => { + log("Failed to find WebSocket send function."); + reject.call1(&wasm_bindgen::JsValue::NULL, &e).unwrap(); + } + } + }) as Box); + + let ws_ref = web_socket.unchecked_ref::(); + ws_ref.set_onopen(Some(onopen.as_ref().unchecked_ref())); + log("WebSocket set_onopen event registered."); + + onopen.forget(); + }); + log("Promise created for WebSocket interaction."); + + let js_future = JsFuture::from(js_sys::Promise::resolve(&promise)); + let onmessage = js_future + .await + .map_err(|e| Error::Response(format!("Failed to receive message: {:?}", e)))?; + + // Cast the result to a MessageEvent + let message_event = onmessage + .dyn_into::() + .map_err(|_| Error::Response("Failed to cast to MessageEvent".to_string()))?; + + // Extract the response data as a string + let data = message_event + .data() + .as_string() + .ok_or_else(|| Error::Response("Failed to parse response data".to_string()))?; + + // Process the response + let response = process_response(data.as_bytes().into(), request_id).await?; + log("response"); Ok(response) } @@ -312,6 +400,32 @@ async fn read_response(client: &mut TcpStream) -> Result, Error> { Ok(response_buf) } +#[cfg(target_arch = "wasm32")] +#[cfg(target_arch = "wasm32")] +async fn read_response(response_bytes: Vec) -> Result, Error> { + // Ensure we have enough bytes for the length field + if response_bytes.len() < LENGTH_FIELD_SIZE { + return Err(Error::Response( + "Insufficient data for length prefix".to_string(), + )); + } + + // Read the length prefix (first 4 bytes) as a little-endian u32 + let response_length = + u32::from_le_bytes(response_bytes[0..LENGTH_FIELD_SIZE].try_into().unwrap()) as usize; + + // Ensure the buffer is large enough for the specified length + if response_bytes.len() < LENGTH_FIELD_SIZE + response_length { + return Err(Error::Response("Incomplete response data".to_string())); + } + + // Extract the actual response payload + let response_buf = + response_bytes[LENGTH_FIELD_SIZE..LENGTH_FIELD_SIZE + response_length].to_vec(); + + Ok(response_buf) +} + /// Parse response pub(crate) fn parse_response( response: &BinaryResponse, @@ -341,20 +455,20 @@ async fn process_response( const REQUEST_ID_START: usize = 0; const REQUEST_ID_END: usize = REQUEST_ID_START + 2; - // // Extract Request ID from the response - // let _request_id = u16::from_le_bytes( - // response_buf[REQUEST_ID_START..REQUEST_ID_END] - // .try_into() - // .expect("Failed to extract Request ID"), - // ); - - // // Check if request_id matches _request_id and return an error if not - // if request_id != _request_id { - // return Err(Error::Response(format!( - // "Request ID mismatch: expected {}, got {}", - // request_id, _request_id - // ))); - // } + // Extract Request ID from the response + let _request_id = u16::from_le_bytes( + response_buf[REQUEST_ID_START..REQUEST_ID_END] + .try_into() + .expect("Failed to extract Request ID"), + ); + + // Check if request_id matches _request_id and return an error if not + if request_id != _request_id { + return Err(Error::Response(format!( + "Request ID mismatch: expected {}, got {}", + request_id, _request_id + ))); + } // Deserialize the remaining response data let response: BinaryResponseAndRequest = bytesrepr::deserialize_from_slice(response_buf)?; From ce03f5c8ee108892ccc3a414097c3068f10f09b4 Mon Sep 17 00:00:00 2001 From: gRoussac Date: Mon, 28 Oct 2024 00:05:56 +0100 Subject: [PATCH 14/32] target wasm32 communication module --- Cargo.lock | 94 ++-- binary_port_access/Cargo.toml | 8 +- binary_port_access/src/communication.rs | 476 ------------------ .../src/communication/common.rs | 155 ++++++ binary_port_access/src/communication/mod.rs | 11 + .../src/communication/wasm32.rs | 377 ++++++++++++++ binary_port_access/src/lib.rs | 6 +- binary_port_access/src/utils.rs | 15 +- 8 files changed, 610 insertions(+), 532 deletions(-) delete mode 100644 binary_port_access/src/communication.rs create mode 100644 binary_port_access/src/communication/common.rs create mode 100644 binary_port_access/src/communication/mod.rs create mode 100644 binary_port_access/src/communication/wasm32.rs diff --git a/Cargo.lock b/Cargo.lock index 038795f..90fc458 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -28,9 +28,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.15" +version = "0.6.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" +checksum = "23a1e53f0f5d86382dafe1cf314783b2044280f406e7e1506368220ad11b1338" dependencies = [ "anstyle", "anstyle-parse", @@ -43,36 +43,36 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.8" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" +checksum = "8365de52b16c035ff4fcafe0092ba9390540e3e352870ac09933bebcaa2c8c56" [[package]] name = "anstyle-parse" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.4" +version = "3.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" +checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" dependencies = [ "anstyle", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -182,7 +182,7 @@ checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" [[package]] name = "casper-binary-port" version = "1.0.0" -source = "git+https://github.com/casper-network/casper-node?branch=feat-2.0#79714924f7a83d98e0d3037fef60fcb66ce4ef54" +source = "git+https://github.com/casper-network/casper-node?branch=feat-2.0#a44f882afa7f401ea55361ec26fbb8ef9bd4fbbc" dependencies = [ "bincode", "bytes", @@ -232,7 +232,7 @@ dependencies = [ [[package]] name = "casper-types" version = "5.0.0" -source = "git+https://github.com/casper-network/casper-node?branch=feat-2.0#79714924f7a83d98e0d3037fef60fcb66ce4ef54" +source = "git+https://github.com/casper-network/casper-node?branch=feat-2.0#a44f882afa7f401ea55361ec26fbb8ef9bd4fbbc" dependencies = [ "base16", "base64", @@ -306,7 +306,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.82", + "syn 2.0.85", ] [[package]] @@ -317,9 +317,9 @@ checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" [[package]] name = "colorchoice" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" [[package]] name = "const-oid" @@ -404,7 +404,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.82", + "syn 2.0.85", ] [[package]] @@ -447,7 +447,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn 2.0.82", + "syn 2.0.85", ] [[package]] @@ -645,7 +645,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.82", + "syn 2.0.85", ] [[package]] @@ -932,7 +932,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn 2.0.82", + "syn 2.0.85", ] [[package]] @@ -1010,9 +1010,9 @@ dependencies = [ [[package]] name = "pin-project-lite" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" +checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" [[package]] name = "pin-utils" @@ -1041,9 +1041,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.88" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c3a7fc5db1e57d5a779a352c8cdb57b29aa4c40cc69c3a68a7fedc815fbf2f9" +checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" dependencies = [ "unicode-ident", ] @@ -1089,9 +1089,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.11.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", @@ -1143,9 +1143,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.37" +version = "0.38.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" +checksum = "aa260229e6538e52293eeb577aabd09945a09d6d9cc0fc550ed7529056c2e32a" dependencies = [ "bitflags 2.6.0", "errno", @@ -1182,7 +1182,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn 2.0.82", + "syn 2.0.85", ] [[package]] @@ -1206,9 +1206,9 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.211" +version = "1.0.213" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ac55e59090389fb9f0dd9e0f3c09615afed1d19094284d0b200441f13550793" +checksum = "3ea7893ff5e2466df8d720bb615088341b295f849602c6956047f8f80f0e9bc1" dependencies = [ "serde_derive", ] @@ -1234,13 +1234,13 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.211" +version = "1.0.213" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54be4f245ce16bc58d57ef2716271d0d4519e0f6defa147f6e081005bcb278ff" +checksum = "7e85ad2009c50b58e87caa8cd6dac16bdf511bbfb7af6c33df902396aa480fa5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.82", + "syn 2.0.85", ] [[package]] @@ -1251,7 +1251,7 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ "proc-macro2", "quote", - "syn 2.0.82", + "syn 2.0.85", ] [[package]] @@ -1348,9 +1348,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.82" +version = "2.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83540f837a8afc019423a8edb95b52a8effe46957ee402287f4292fae35be021" +checksum = "5023162dfcd14ef8f32034d8bcd4cc5ddc61ef7a247c024a33e24e1f24d21b56" dependencies = [ "proc-macro2", "quote", @@ -1369,22 +1369,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.64" +version = "1.0.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" +checksum = "5d11abd9594d9b38965ef50805c5e469ca9cc6f197f883f717e0269a3057b3d5" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.64" +version = "1.0.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" +checksum = "ae71770322cbd277e69d762a16c444af02aa0575ac0d174f0b9562d3b37f8602" dependencies = [ "proc-macro2", "quote", - "syn 2.0.82", + "syn 2.0.85", ] [[package]] @@ -1411,7 +1411,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.82", + "syn 2.0.85", ] [[package]] @@ -1520,7 +1520,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.82", + "syn 2.0.85", "wasm-bindgen-shared", ] @@ -1554,7 +1554,7 @@ checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" dependencies = [ "proc-macro2", "quote", - "syn 2.0.82", + "syn 2.0.85", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -1675,7 +1675,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.82", + "syn 2.0.85", ] [[package]] diff --git a/binary_port_access/Cargo.toml b/binary_port_access/Cargo.toml index b163438..77ed9ad 100644 --- a/binary_port_access/Cargo.toml +++ b/binary_port_access/Cargo.toml @@ -22,7 +22,13 @@ rand = { version = "0.8.5", default-features = false } wasm-bindgen = "*" wasm-bindgen-futures = "*" js-sys = "*" -web-sys = { version = "0.3", features = ["WebSocket", "MessageEvent"] } +web-sys = { version = "0.3", features = [ + "Blob", + "FileReader", + "ProgressEvent", + "WebSocket", + "MessageEvent", +] } gloo-utils = { version = "0.2", default-features = false, features = ["serde"] } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] diff --git a/binary_port_access/src/communication.rs b/binary_port_access/src/communication.rs deleted file mode 100644 index 4d4ce6d..0000000 --- a/binary_port_access/src/communication.rs +++ /dev/null @@ -1,476 +0,0 @@ -use crate::Error; -#[cfg(not(target_arch = "wasm32"))] -use casper_binary_port::BinaryMessage; -use casper_binary_port::{ - BinaryRequest, BinaryRequestHeader, BinaryResponse, BinaryResponseAndRequest, PayloadEntity, -}; -use casper_types::{ - bytesrepr::{self, FromBytes, ToBytes}, - ProtocolVersion, -}; -#[cfg(target_arch = "wasm32")] -pub use gloo_utils::format::JsValueSerdeExt; -#[cfg(target_arch = "wasm32")] -pub use js_sys::{JsString, Promise, Reflect}; -use rand::Rng; -#[cfg(not(target_arch = "wasm32"))] -use std::time::Duration; -#[cfg(not(target_arch = "wasm32"))] -use tokio::{ - io::{AsyncReadExt, AsyncWriteExt}, - net::TcpStream, - time::timeout, -}; -#[cfg(target_arch = "wasm32")] -pub use wasm_bindgen::{prelude::Closure, prelude::*, JsCast, JsValue}; -#[cfg(target_arch = "wasm32")] -pub use wasm_bindgen_futures::JsFuture; -#[cfg(target_arch = "wasm32")] -pub use web_sys::{MessageEvent, WebSocket}; - -#[cfg(target_arch = "wasm32")] -#[wasm_bindgen] -extern "C" { - #[wasm_bindgen(js_namespace = console, js_name = log)] - fn log_with_prefix(s: &str); -} -/// Logs an error message, prefixing it with "error wasm" and sends it to the console in JavaScript when running in a WebAssembly environment. -/// When running outside WebAssembly, it prints the error message to the standard output. -pub fn log(s: &str) { - #[cfg(target_arch = "wasm32")] - let prefixed_s = format!("log wasm {}", s); - #[cfg(target_arch = "wasm32")] - log_with_prefix(&prefixed_s); - #[cfg(not(target_arch = "wasm32"))] - println!("{}", s); -} - -// TODO[RC]: Do not hardcode this. -pub(crate) const SUPPORTED_PROTOCOL_VERSION: ProtocolVersion = ProtocolVersion::from_parts(2, 0, 0); - -#[cfg(not(target_arch = "wasm32"))] -const TIMEOUT_DURATION: Duration = Duration::from_secs(5); -const LENGTH_FIELD_SIZE: usize = 4; - -// TODO[RC]: Into "communication" module - -#[cfg(not(target_arch = "wasm32"))] -async fn connect_to_node(node_address: &str) -> Result { - let stream = TcpStream::connect(node_address).await?; - Ok(stream) -} - -fn encode_request( - req: &BinaryRequest, - request_id: Option, -) -> Result, bytesrepr::Error> { - let header = BinaryRequestHeader::new( - SUPPORTED_PROTOCOL_VERSION, - req.tag(), - request_id.unwrap_or_default(), - ); - let mut bytes = Vec::with_capacity(header.serialized_length() + req.serialized_length()); - header.write_bytes(&mut bytes)?; - req.write_bytes(&mut bytes)?; - Ok(bytes) -} - -#[cfg(not(target_arch = "wasm32"))] -pub(crate) async fn send_request( - node_address: &str, - request: BinaryRequest, -) -> Result { - let request_id = rand::thread_rng().gen::(); - let payload = - encode_request(&request, Some(request_id)).expect("should always serialize a request"); - let mut client = connect_to_node(node_address).await?; - - let message = BinaryMessage::new(payload); - - // Send the payload length and data - send_payload(&mut client, &message).await?; - - // Read and process the response - let response_buf = read_response(&mut client).await?; - - process_response(response_buf, request_id).await -} - -// TODO Documentation -/// DOC -#[cfg(target_arch = "wasm32")] -#[wasm_bindgen] -pub fn is_node() -> bool { - // Check if 'process' exists and if it has 'versions' property (which is present in Node.js) - let is_node = js_sys::global() - .dyn_into::() - .map(|global| { - Reflect::has(&global, &JsString::from("process")).unwrap_or(false) - && Reflect::get(&global, &JsString::from("process")) - .map(|process| { - Reflect::has(&process, &JsString::from("versions")).unwrap_or(false) - }) - .unwrap_or(false) - }) - .unwrap_or(false); - // log(&format!("is_node {:?}", is_node)); - is_node -} - -#[cfg(target_arch = "wasm32")] -pub(crate) async fn send_request( - node_address: &str, - request: BinaryRequest, -) -> Result { - let request_id = rand::thread_rng().gen::(); - let payload = encode_request(&request, Some(request_id)) - .map_err(|e| Error::Serialization(format!("Failed to serialize request: {}", e)))?; - - if is_node() { - // In Node.js, use raw TCP with the `net` module for direct connection - let tcp_result = open_tcp_connection(node_address, payload.clone(), request_id).await; - match tcp_result { - Ok(response) => return Ok(response), - Err(e) => return Err(Error::Response(format!("TCP connection failed: {:?}", e))), - } - } else { - // In the browser or non-Node.js environments, use WebSocket - let ws_url = format!("ws://{}", node_address); - let web_socket = WebSocket::new(&ws_url).map_err(|e| { - Error::WebSocketCreation(format!("Failed to create WebSocket: {:?}", e)) - })?; - - let response = handle_websocket_connection(web_socket, payload, request_id).await?; - return Ok(response); - } -} - -#[cfg(target_arch = "wasm32")] -async fn open_tcp_connection( - node_address: &str, - payload: Vec, - request_id: u16, -) -> Result { - let tcp_script = format!( - r#" -(async () => {{ - try {{ - const net = require('net'); - const client = new net.Socket(); - const payload = Buffer.from({:?}); - const node_address = '{node_address}'; - const [host, port] = node_address.split(':'); - - // console.log('TCP Client created:'); - // console.log('Payload to send:', payload); - // console.log('node_address', node_address); - // console.log('host', host); - // console.log('port', port); - // console.log('Promise available:', typeof Promise !== 'undefined'); - - return new Promise((resolve, reject) => {{ - // console.log('Connecting to TCP server at', host, port); - - const lengthBuffer = Buffer.alloc(4); - lengthBuffer.writeUInt32LE(payload.length); - client.connect(parseInt(port), host, () => {{ - // console.log('Connected to TCP server'); - - // First, send the length of the payload - client.write(lengthBuffer, (err) => {{ - if (err) {{ - console.error('Error sending length:', err.message); - client.destroy(); - return; - }} - // console.log('Length of payload sent'); - - // Now, send the actual payload - client.write(payload, (err) => {{ - if (err) {{ - console.error('Error sending payload:', err.message); - }} else {{ - // console.log('Payload sent'); - }} - }}); - }}); - }}); - - client.on('data', (data) => {{ - // console.log('Data received from server:', data); - resolve(data); - client.destroy(); // Close connection after receiving response - }}); - - client.on('error', (err) => {{ - console.error('TCP connection error:', err.message); - reject(new Error('TCP connection error: ' + err.message)); - }}); - - client.on('close', () => {{ - // console.log('TCP connection closed'); - }}); - }}); - }} catch (err) {{ - console.error('Error in TCP script:', err.message); - throw new Error('Script execution error: ' + err.message); - }} -}})(); - "#, - payload - ); - - // Execute the script in JavaScript context using eval - let tcp_promise: Promise = js_sys::eval(&tcp_script) - .map_err(|err| { - log("Failed to execute TCP script in eval"); - log(&err.as_string().unwrap()); - Error::Response("Failed to execute TCP script".to_string()) - })? - .dyn_into() - .map_err(|err| { - log("Failed to cast eval result to Promise"); - log(&err.as_string().unwrap()); - Error::Response("Failed to cast eval result to Promise".to_string()) - })?; - - let js_future = JsFuture::from(tcp_promise); - let tcp_response = js_future - .await - .map_err(|e| Error::Response(format!("TCP connection promise failed: {:?}", e)))?; - - // Since the resolved value is a Buffer, convert it to a byte slice - let response_bytes = js_sys::Uint8Array::new(&tcp_response).to_vec(); - - // Log the received response bytes for debugging - // log(&format!("Received response data: {:?}", response_bytes)); - - // Read and process the response - let response_buf = read_response(response_bytes).await?; - // Now process the response using the request_id - process_response(response_buf.into(), request_id).await -} - -#[cfg(target_arch = "wasm32")] -async fn handle_websocket_connection( - web_socket: WebSocket, - payload: Vec, - request_id: u16, -) -> Result { - let promise = Promise::new(&mut |resolve, reject| { - let ws_clone = web_socket.clone(); - let payload_clone = payload.clone(); - - // Set up onopen, onmessage, and onerror handlers - let onopen = Closure::wrap(Box::new(move || { - log("WebSocket connection opened, attempting to send payload."); - - // Convert payload to JsValue using gloo_utils::format::JsValueSerdeExt - let payload_js_value = wasm_bindgen::JsValue::from_serde(&payload_clone).unwrap(); - log("Payload serialized to JsValue."); - - // Send payload - match js_sys::Reflect::get(&ws_clone, &JsString::from("send")) - .and_then(|send_func| send_func.dyn_into::()) - { - Ok(send_func) => { - if let Err(e) = send_func.call1(&ws_clone, &payload_js_value) { - log(&format!("Failed to send payload: {:?}", e)); - reject - .call1( - &wasm_bindgen::JsValue::NULL, - &wasm_bindgen::JsValue::from_str(&format!( - "Failed to send message: {:?}", - e - )), - ) - .unwrap(); - } else { - log("Payload sent successfully, setting up message handler."); - - let resolve_clone = resolve.clone(); - let onmessage = Closure::wrap(Box::new(move |event: MessageEvent| { - log("Message received from WebSocket."); - - let data = event.data().as_string().unwrap_or_default(); - resolve_clone - .call1( - &wasm_bindgen::JsValue::NULL, - &wasm_bindgen::JsValue::from_str(&data), - ) - .unwrap(); - }) - as Box); - - let ws_ref = ws_clone.unchecked_ref::(); - ws_ref.set_onmessage(Some(onmessage.as_ref().unchecked_ref())); - onmessage.forget(); - - let reject_clone = reject.clone(); - let onerror = Closure::wrap(Box::new(move |event: wasm_bindgen::JsValue| { - let error_msg = event - .as_string() - .unwrap_or_else(|| "WebSocket error".to_string()); - log(&format!("WebSocket error: {}", error_msg)); - reject_clone - .call1( - &wasm_bindgen::JsValue::NULL, - &wasm_bindgen::JsValue::from_str(&error_msg), - ) - .unwrap(); - }) - as Box); - - ws_ref.set_onerror(Some(onerror.as_ref().unchecked_ref())); - onerror.forget(); - } - } - Err(e) => { - log("Failed to find WebSocket send function."); - reject.call1(&wasm_bindgen::JsValue::NULL, &e).unwrap(); - } - } - }) as Box); - - let ws_ref = web_socket.unchecked_ref::(); - ws_ref.set_onopen(Some(onopen.as_ref().unchecked_ref())); - log("WebSocket set_onopen event registered."); - - onopen.forget(); - }); - log("Promise created for WebSocket interaction."); - - let js_future = JsFuture::from(js_sys::Promise::resolve(&promise)); - let onmessage = js_future - .await - .map_err(|e| Error::Response(format!("Failed to receive message: {:?}", e)))?; - - // Cast the result to a MessageEvent - let message_event = onmessage - .dyn_into::() - .map_err(|_| Error::Response("Failed to cast to MessageEvent".to_string()))?; - - // Extract the response data as a string - let data = message_event - .data() - .as_string() - .ok_or_else(|| Error::Response("Failed to parse response data".to_string()))?; - - // Process the response - let response = process_response(data.as_bytes().into(), request_id).await?; - log("response"); - Ok(response) -} - -/// Sends the payload length and data to the client. -#[cfg(not(target_arch = "wasm32"))] -async fn send_payload(client: &mut TcpStream, message: &BinaryMessage) -> Result<(), Error> { - let payload_length = message.payload().len() as u32; - let length_bytes = payload_length.to_le_bytes(); - - let _ = timeout(TIMEOUT_DURATION, client.write_all(&length_bytes)) - .await - .map_err(|e| Error::TimeoutError(e.to_string()))?; - - let _ = timeout(TIMEOUT_DURATION, client.write_all(message.payload())) - .await - .map_err(|e| Error::TimeoutError(e.to_string()))?; - - let _ = timeout(TIMEOUT_DURATION, client.flush()) - .await - .map_err(|e| Error::TimeoutError(e.to_string()))?; - - Ok(()) -} - -/// Reads the response from the client and returns the response buffer. -#[cfg(not(target_arch = "wasm32"))] -async fn read_response(client: &mut TcpStream) -> Result, Error> { - let mut length_buf = [0u8; LENGTH_FIELD_SIZE]; - let _ = timeout(TIMEOUT_DURATION, client.read_exact(&mut length_buf)) - .await - .map_err(|e| Error::TimeoutError(e.to_string()))?; - - let response_length = u32::from_le_bytes(length_buf) as usize; - let mut response_buf = vec![0u8; response_length]; - let _ = timeout(TIMEOUT_DURATION, client.read_exact(&mut response_buf)) - .await - .map_err(|e| Error::TimeoutError(e.to_string()))?; - - Ok(response_buf) -} - -#[cfg(target_arch = "wasm32")] -#[cfg(target_arch = "wasm32")] -async fn read_response(response_bytes: Vec) -> Result, Error> { - // Ensure we have enough bytes for the length field - if response_bytes.len() < LENGTH_FIELD_SIZE { - return Err(Error::Response( - "Insufficient data for length prefix".to_string(), - )); - } - - // Read the length prefix (first 4 bytes) as a little-endian u32 - let response_length = - u32::from_le_bytes(response_bytes[0..LENGTH_FIELD_SIZE].try_into().unwrap()) as usize; - - // Ensure the buffer is large enough for the specified length - if response_bytes.len() < LENGTH_FIELD_SIZE + response_length { - return Err(Error::Response("Incomplete response data".to_string())); - } - - // Extract the actual response payload - let response_buf = - response_bytes[LENGTH_FIELD_SIZE..LENGTH_FIELD_SIZE + response_length].to_vec(); - - Ok(response_buf) -} - -/// Parse response -pub(crate) fn parse_response( - response: &BinaryResponse, -) -> Result, Error> { - match response.returned_data_type_tag() { - Some(found) if found == u8::from(A::RESPONSE_TYPE) => { - // Verbose: Print length of payload - let payload = response.payload(); - let _payload_length = payload.len(); - // TODO[GR] use tracing::info! instead of dbg! - // dbg!(_payload_length); - - Ok(Some(bytesrepr::deserialize_from_slice(payload)?)) - } - Some(other) => Err(Error::Response(format!( - "unsupported response type: {other}" - ))), - _ => Ok(None), - } -} - -/// Processes the response buffer and checks for request ID mismatch. -async fn process_response( - response_buf: Vec, - request_id: u16, -) -> Result { - const REQUEST_ID_START: usize = 0; - const REQUEST_ID_END: usize = REQUEST_ID_START + 2; - - // Extract Request ID from the response - let _request_id = u16::from_le_bytes( - response_buf[REQUEST_ID_START..REQUEST_ID_END] - .try_into() - .expect("Failed to extract Request ID"), - ); - - // Check if request_id matches _request_id and return an error if not - if request_id != _request_id { - return Err(Error::Response(format!( - "Request ID mismatch: expected {}, got {}", - request_id, _request_id - ))); - } - - // Deserialize the remaining response data - let response: BinaryResponseAndRequest = bytesrepr::deserialize_from_slice(response_buf)?; - Ok(response) -} diff --git a/binary_port_access/src/communication/common.rs b/binary_port_access/src/communication/common.rs new file mode 100644 index 0000000..e6928b6 --- /dev/null +++ b/binary_port_access/src/communication/common.rs @@ -0,0 +1,155 @@ +use crate::Error; +#[cfg(not(target_arch = "wasm32"))] +use casper_binary_port::BinaryMessage; +use casper_binary_port::{ + BinaryRequest, BinaryRequestHeader, BinaryResponse, BinaryResponseAndRequest, PayloadEntity, +}; +use casper_types::{ + bytesrepr::{self, FromBytes, ToBytes}, + ProtocolVersion, +}; +#[cfg(not(target_arch = "wasm32"))] +use rand::Rng; +#[cfg(not(target_arch = "wasm32"))] +use std::time::Duration; +#[cfg(not(target_arch = "wasm32"))] +use tokio::{ + io::{AsyncReadExt, AsyncWriteExt}, + net::TcpStream, + time::timeout, +}; + +// TODO[RC]: Do not hardcode this. +pub(crate) const SUPPORTED_PROTOCOL_VERSION: ProtocolVersion = ProtocolVersion::from_parts(2, 0, 0); +pub(crate) const LENGTH_FIELD_SIZE: usize = 4; +#[cfg(not(target_arch = "wasm32"))] +const TIMEOUT_DURATION: Duration = Duration::from_secs(5); + +#[cfg(not(target_arch = "wasm32"))] +async fn connect_to_node(node_address: &str) -> Result { + let stream = TcpStream::connect(node_address).await?; + Ok(stream) +} + +/// Sends the payload length and data to the client. +#[cfg(not(target_arch = "wasm32"))] +async fn send_payload(client: &mut TcpStream, message: &BinaryMessage) -> Result<(), Error> { + let payload_length = message.payload().len() as u32; + let length_bytes = payload_length.to_le_bytes(); + + let _ = timeout(TIMEOUT_DURATION, client.write_all(&length_bytes)) + .await + .map_err(|e| Error::TimeoutError(e.to_string()))?; + + let _ = timeout(TIMEOUT_DURATION, client.write_all(message.payload())) + .await + .map_err(|e| Error::TimeoutError(e.to_string()))?; + + let _ = timeout(TIMEOUT_DURATION, client.flush()) + .await + .map_err(|e| Error::TimeoutError(e.to_string()))?; + + Ok(()) +} + +/// Reads the response from the client and returns the response buffer. +#[cfg(not(target_arch = "wasm32"))] +async fn read_response(client: &mut TcpStream) -> Result, Error> { + let mut length_buf = [0u8; LENGTH_FIELD_SIZE]; + let _ = timeout(TIMEOUT_DURATION, client.read_exact(&mut length_buf)) + .await + .map_err(|e| Error::TimeoutError(e.to_string()))?; + + let response_length = u32::from_le_bytes(length_buf) as usize; + let mut response_buf = vec![0u8; response_length]; + let _ = timeout(TIMEOUT_DURATION, client.read_exact(&mut response_buf)) + .await + .map_err(|e| Error::TimeoutError(e.to_string()))?; + + Ok(response_buf) +} + +#[cfg(not(target_arch = "wasm32"))] +pub(crate) async fn send_request( + node_address: &str, + request: BinaryRequest, +) -> Result { + let request_id = rand::thread_rng().gen::(); + let payload = + encode_request(&request, Some(request_id)).expect("should always serialize a request"); + let mut client = connect_to_node(node_address).await?; + + let message = BinaryMessage::new(payload); + + // Send the payload length and data + send_payload(&mut client, &message).await?; + + // Read and process the response + let response_buf = read_response(&mut client).await?; + // Now process the response using the request_id + process_response(response_buf, request_id).await +} + +pub(crate) fn encode_request( + req: &BinaryRequest, + request_id: Option, +) -> Result, bytesrepr::Error> { + let header = BinaryRequestHeader::new( + SUPPORTED_PROTOCOL_VERSION, + req.tag(), + request_id.unwrap_or_default(), + ); + let mut bytes = Vec::with_capacity(header.serialized_length() + req.serialized_length()); + header.write_bytes(&mut bytes)?; + req.write_bytes(&mut bytes)?; + Ok(bytes) +} + +/// Parse response +pub(crate) fn parse_response( + response: &BinaryResponse, +) -> Result, Error> { + match response.returned_data_type_tag() { + Some(found) if found == u8::from(A::RESPONSE_TYPE) => { + // Verbose: Print length of payload + let payload = response.payload(); + let _payload_length = payload.len(); + // TODO[GR] use tracing::info! instead of dbg! + // dbg!(_payload_length); + + Ok(Some(bytesrepr::deserialize_from_slice(payload)?)) + } + Some(other) => Err(Error::Response(format!( + "unsupported response type: {other}" + ))), + _ => Ok(None), + } +} + +/// Processes the response buffer and checks for request ID mismatch. +pub(crate) async fn process_response( + response_buf: Vec, + request_id: u16, +) -> Result { + const REQUEST_ID_START: usize = 0; + const REQUEST_ID_END: usize = REQUEST_ID_START + 2; + + // Extract Request ID from the response + let _request_id = u16::from_le_bytes( + response_buf[REQUEST_ID_START..REQUEST_ID_END] + .try_into() + .expect("Failed to extract Request ID"), + ); + + // Check if request_id matches _request_id and return an error if not + if request_id != _request_id { + return Err(Error::Response(format!( + "Request ID mismatch: expected {}, got {}", + request_id, _request_id + ))); + } + + // Deserialize the remaining response data + let response: BinaryResponseAndRequest = bytesrepr::deserialize_from_slice(response_buf)?; + Ok(response) +} diff --git a/binary_port_access/src/communication/mod.rs b/binary_port_access/src/communication/mod.rs new file mode 100644 index 0000000..b95212e --- /dev/null +++ b/binary_port_access/src/communication/mod.rs @@ -0,0 +1,11 @@ +/// The `communication` module provides both shared and platform-specific functionalities +/// for managing communication processes. +/// +/// # Modules +/// - [`common`]: Contains utilities and shared logic that are used across all target architectures. +pub mod common; + +/// - [`wasm32`]: Contains WebAssembly-specific (`wasm32` target) communication utilities, +/// available only when compiled for WebAssembly. +#[cfg(target_arch = "wasm32")] +pub mod wasm32; diff --git a/binary_port_access/src/communication/wasm32.rs b/binary_port_access/src/communication/wasm32.rs new file mode 100644 index 0000000..acf41d9 --- /dev/null +++ b/binary_port_access/src/communication/wasm32.rs @@ -0,0 +1,377 @@ +#[cfg(target_arch = "wasm32")] +use crate::communication::common::{encode_request, process_response, LENGTH_FIELD_SIZE}; +#[cfg(target_arch = "wasm32")] +use crate::Error; +#[cfg(target_arch = "wasm32")] +use casper_binary_port::{BinaryRequest, BinaryResponseAndRequest}; +#[cfg(target_arch = "wasm32")] +use gloo_utils::format::JsValueSerdeExt; +#[cfg(target_arch = "wasm32")] +use js_sys::{JsString, Promise, Reflect}; +#[cfg(target_arch = "wasm32")] +use rand::Rng; +#[cfg(target_arch = "wasm32")] +use wasm_bindgen::{prelude::Closure, prelude::*, JsCast, JsValue}; +#[cfg(target_arch = "wasm32")] +use wasm_bindgen_futures::JsFuture; +#[cfg(target_arch = "wasm32")] +use web_sys::{MessageEvent, WebSocket}; +#[cfg(target_arch = "wasm32")] +#[wasm_bindgen] +extern "C" { + #[wasm_bindgen(js_namespace = console, js_name = log)] + fn log_with_prefix(s: &str); +} +/// Logs an error message, prefixing it with "error wasm" and sends it to the console in JavaScript when running in a WebAssembly environment. +/// When running outside WebAssembly, it prints the error message to the standard output. +#[cfg(target_arch = "wasm32")] +fn log(s: &str) { + #[cfg(target_arch = "wasm32")] + let prefixed_s = format!("log wasm {}", s); + #[cfg(target_arch = "wasm32")] + log_with_prefix(&prefixed_s); + #[cfg(not(target_arch = "wasm32"))] + println!("{}", s); +} + +// TODO Documentation +/// DOC +#[cfg(target_arch = "wasm32")] +fn is_node() -> bool { + // Check if 'process' exists and if it has 'versions' property (which is present in Node.js) + let is_node = js_sys::global() + .dyn_into::() + .map(|global| { + Reflect::has(&global, &JsString::from("process")).unwrap_or(false) + && Reflect::get(&global, &JsString::from("process")) + .map(|process| { + Reflect::has(&process, &JsString::from("versions")).unwrap_or(false) + }) + .unwrap_or(false) + }) + .unwrap_or(false); + // log(&format!("is_node {:?}", is_node)); + is_node +} + +#[cfg(target_arch = "wasm32")] +async fn open_tcp_connection( + node_address: &str, + payload: Vec, + request_id: u16, +) -> Result { + let tcp_script = format!( + r#" +(async () => {{ + try {{ + const net = require('net'); + const client = new net.Socket(); + const payload = Buffer.from({:?}); + const node_address = '{node_address}'; + const [host, port] = node_address.split(':'); + + // console.log('TCP Client created:'); + // console.log('Payload to send:', payload); + // console.log('node_address', node_address); + // console.log('host', host); + // console.log('port', port); + // console.log('Promise available:', typeof Promise !== 'undefined'); + + return new Promise((resolve, reject) => {{ + // console.log('Connecting to TCP server at', host, port); + + const lengthBuffer = Buffer.alloc(4); + lengthBuffer.writeUInt32LE(payload.length); + client.connect(parseInt(port), host, () => {{ + // console.log('Connected to TCP server'); + + // First, send the length of the payload + client.write(lengthBuffer, (err) => {{ + if (err) {{ + console.error('Error sending length:', err.message); + client.destroy(); + return; + }} + // console.log('Length of payload sent'); + + // Now, send the actual payload + client.write(payload, (err) => {{ + if (err) {{ + console.error('Error sending payload:', err.message); + }} else {{ + // console.log('Payload sent'); + }} + }}); + }}); + }}); + + client.on('data', (data) => {{ + // console.log('Data received from server:', data); + resolve(data); + client.destroy(); // Close connection after receiving response + }}); + + client.on('error', (err) => {{ + console.error('TCP connection error:', err.message); + reject(new Error('TCP connection error: ' + err.message)); + }}); + + client.on('close', () => {{ + // console.log('TCP connection closed'); + }}); + }}); + }} catch (err) {{ + console.error('Error in TCP script:', err.message); + throw new Error('Script execution error: ' + err.message); + }} +}})(); + "#, + payload + ); + + // Execute the script in JavaScript context using eval + let tcp_promise: Promise = js_sys::eval(&tcp_script) + .map_err(|err| { + log("Failed to execute TCP script in eval"); + log(&err.as_string().unwrap()); + Error::Response("Failed to execute TCP script".to_string()) + })? + .dyn_into() + .map_err(|err| { + log("Failed to cast eval result to Promise"); + log(&err.as_string().unwrap()); + Error::Response("Failed to cast eval result to Promise".to_string()) + })?; + + let js_future = JsFuture::from(tcp_promise); + let tcp_response = js_future + .await + .map_err(|e| Error::Response(format!("TCP connection promise failed: {:?}", e)))?; + + // Since the resolved value is a Buffer, convert it to a byte slice + let response_bytes = js_sys::Uint8Array::new(&tcp_response).to_vec(); + + // Log the received response bytes for debugging + // log(&format!("Received response data: {:?}", response_bytes)); + + // Read and process the response + let response_buf = read_response(response_bytes).await?; + // Now process the response using the request_id + process_response(response_buf.into(), request_id).await +} + +#[cfg(target_arch = "wasm32")] +async fn handle_websocket_connection( + web_socket: WebSocket, + payload: Vec, + request_id: u16, +) -> Result { + let promise = Promise::new(&mut |resolve, reject| { + let ws_clone = web_socket.clone(); + let resolve_clone = resolve.clone(); // Clone to use later + let reject_clone = reject.clone(); // Clone to use later + + // Prepare length buffer using LENGTH_FIELD_SIZE + let payload_length = payload.len() as u32; + let mut length_buffer = vec![0; LENGTH_FIELD_SIZE]; + length_buffer[..LENGTH_FIELD_SIZE].copy_from_slice(&payload_length.to_le_bytes()); + + log("Payload length buffer prepared."); + + // 1. Send the length buffer first + let length_js_value = js_sys::Uint8Array::from(length_buffer.as_slice()); + + let payload_clone = payload.clone(); // Clone the payload for sending + + // Set up onopen handler to send length and then payload + let onopen = Closure::wrap(Box::new(move || { + log("WebSocket connection opened, attempting to send length buffer."); + + // Use ws_clone in the closure directly + let send_func_result = js_sys::Reflect::get(&ws_clone, &JsString::from("send")) + .and_then(|send_func| send_func.dyn_into::()); + + match send_func_result { + Ok(send_func) => { + // Send length buffer + if let Err(e) = send_func.call1(&ws_clone, &length_js_value) { + log(&format!("Failed to send length buffer: {:?}", e)); + reject_clone.call1(&JsValue::NULL, &e).unwrap(); + } else { + log("Length buffer sent successfully, now sending payload."); + + // 2. Send the payload after the length buffer has been sent + let payload_array = js_sys::Uint8Array::from(payload_clone.as_slice()); + + if let Err(e) = send_func.call1(&ws_clone, &payload_array) { + log(&format!("Failed to send payload: {:?}", e)); + reject_clone.call1(&JsValue::NULL, &e).unwrap(); + } else { + log("Payload sent successfully, setting up message handler."); + + let onerror = { + let reject_clone = reject_clone.clone(); // Clone for use in onerror + Closure::wrap(Box::new(move |event: wasm_bindgen::JsValue| { + let error_msg = event + .as_string() + .unwrap_or_else(|| "WebSocket error".to_string()); + log(&format!("WebSocket error: {}", error_msg)); + reject_clone + .call1(&JsValue::NULL, &JsValue::from_str(&error_msg)) + .unwrap(); + }) + as Box) + }; + + ws_clone.set_onerror(Some(onerror.as_ref().unchecked_ref())); + onerror.forget(); // Prevent memory leak by forgetting the closure + + let onmessage = { + let resolve_clone = resolve_clone.clone(); // Clone for use in onmessage + Closure::wrap(Box::new(move |event: MessageEvent| { + log("Message received from WebSocket."); + + // Convert the event data to Blob + let data: web_sys::Blob = + event.data().dyn_into::().unwrap(); + + // Create a FileReader to read the Blob + let file_reader = web_sys::FileReader::new().unwrap(); // Create FileReader + let resolve_clone = resolve_clone.clone(); // Clone for use in onload + + // Set up the onload closure with the file_reader borrowed + let onload = { + let file_reader_clone = file_reader.clone(); // Clone here + Closure::wrap(Box::new(move |_: web_sys::ProgressEvent| { + // log( + // "Blob read successfully, converting to Uint8Array.", + // ); + + // Get the result of the FileReader as ArrayBuffer + let result = file_reader_clone.result().unwrap(); + let array_buffer = + result.dyn_into::().unwrap(); + let uint8_array = + js_sys::Uint8Array::new(&array_buffer); + + // Convert Uint8Array to Vec + let response_bytes = uint8_array.to_vec(); + + // log(&format!("Received bytes: {:?}", response_bytes)); + + // Resolve with binary response + resolve_clone + .call1( + &JsValue::NULL, + &wasm_bindgen::JsValue::from_serde( + &response_bytes, + ) + .unwrap_or_default(), + ) + .unwrap(); + }) + as Box) + }; + + // Set up the onload event for the FileReader + file_reader.set_onload(Some(onload.as_ref().unchecked_ref())); + file_reader.read_as_array_buffer(&data).unwrap(); // Ensure read call + onload.forget(); // Prevent memory leak by forgetting the closure + }) + as Box) + }; + + ws_clone.set_onmessage(Some(onmessage.as_ref().unchecked_ref())); + onmessage.forget(); // Prevent memory leak by forgetting the closure + } + } + } + Err(e) => { + log("Failed to find WebSocket send function."); + reject_clone.call1(&JsValue::NULL, &e).unwrap(); // Use the cloned reject + } + } + }) as Box); + + let ws_ref = web_socket.unchecked_ref::(); + ws_ref.set_onopen(Some(onopen.as_ref().unchecked_ref())); + log("WebSocket set_onopen event registered."); + onopen.forget(); // Prevent memory leak by forgetting the closure + }); + + let js_future = JsFuture::from(js_sys::Promise::resolve(&promise)); + + // Await the resolved value from the promise + let onmessage = js_future + .await + .map_err(|e| Error::Response(format!("Failed to receive message: {:?}", e)))?; + + let response_data = onmessage + .dyn_into::() + .map_err(|_| Error::Response("Expected Array format for TCP response data".to_string()))? + .to_vec() + .into_iter() + .map(|val| val.as_f64().unwrap_or(0.0) as u8) + .collect::>(); + + log(&format!("read_response {:?}", response_data)); + + // Process the response data as in the original function + let response_buf = read_response(response_data).await?; + process_response(response_buf.into(), request_id).await +} + +#[cfg(target_arch = "wasm32")] +async fn read_response(response_bytes: Vec) -> Result, Error> { + // Ensure we have enough bytes for the length field + if response_bytes.len() < LENGTH_FIELD_SIZE { + return Err(Error::Response( + "Insufficient data for length prefix".to_string(), + )); + } + + // Read the length prefix (first 4 bytes) as a little-endian u32 + let response_length = + u32::from_le_bytes(response_bytes[0..LENGTH_FIELD_SIZE].try_into().unwrap()) as usize; + + // Ensure the buffer is large enough for the specified length + if response_bytes.len() < LENGTH_FIELD_SIZE + response_length { + return Err(Error::Response("Incomplete response data".to_string())); + } + + // Extract the actual response payload + let response_buf = + response_bytes[LENGTH_FIELD_SIZE..LENGTH_FIELD_SIZE + response_length].to_vec(); + + Ok(response_buf) +} + +// TODO Documentation +/// DOC +#[cfg(target_arch = "wasm32")] +pub(crate) async fn send_request( + node_address: &str, + request: BinaryRequest, +) -> Result { + let request_id = rand::thread_rng().gen::(); + let payload = encode_request(&request, Some(request_id)) + .map_err(|e| Error::Serialization(format!("Failed to serialize request: {}", e)))?; + + if is_node() { + // In Node.js, use raw TCP with the `net` module for direct connection + let tcp_result = open_tcp_connection(node_address, payload.clone(), request_id).await; + match tcp_result { + Ok(response) => return Ok(response), + Err(e) => return Err(Error::Response(format!("TCP connection failed: {:?}", e))), + } + } else { + // In the browser or non-Node.js environments, use WebSocket + let ws_url = format!("ws://{}", node_address); + let web_socket = WebSocket::new(&ws_url).map_err(|e| { + Error::WebSocketCreation(format!("Failed to create WebSocket: {:?}", e)) + })?; + + let response = handle_websocket_connection(web_socket, payload, request_id).await?; + return Ok(response); + } +} diff --git a/binary_port_access/src/lib.rs b/binary_port_access/src/lib.rs index 51b294f..86321af 100644 --- a/binary_port_access/src/lib.rs +++ b/binary_port_access/src/lib.rs @@ -18,7 +18,11 @@ use casper_types::{ BlockSynchronizerStatus, ChainspecRawBytes, Digest, EraId, GlobalStateIdentifier, Key, NextUpgrade, Peers, ProtocolVersion, PublicKey, SignedBlock, Transaction, TransactionHash, }; -use communication::{parse_response, send_request}; +use communication::common::parse_response; +#[cfg(not(target_arch = "wasm32"))] +pub(crate) use communication::common::send_request; +#[cfg(target_arch = "wasm32")] +pub(crate) use communication::wasm32::send_request; pub use error::Error; use thiserror::Error; diff --git a/binary_port_access/src/utils.rs b/binary_port_access/src/utils.rs index efb2a63..f99a3b8 100644 --- a/binary_port_access/src/utils.rs +++ b/binary_port_access/src/utils.rs @@ -5,10 +5,11 @@ use casper_binary_port::{ }; use casper_types::{bytesrepr::ToBytes, GlobalStateIdentifier, Key, PublicKey}; -use crate::{ - communication::{self, parse_response}, - Error, -}; +#[cfg(not(target_arch = "wasm32"))] +use crate::communication::common::send_request; +#[cfg(target_arch = "wasm32")] +use crate::communication::wasm32::send_request; +use crate::{communication::common::parse_response, Error}; /// Expose make_information_get_request pub(crate) fn make_information_get_request( @@ -43,7 +44,7 @@ pub(crate) async fn delegator_reward_by_era_identifier( .to_bytes()? .as_slice(), )?; - let response = communication::send_request(node_address, request).await?; + let response = send_request(node_address, request).await?; check_error_code(&response)?; parse_response::(response.response()) } @@ -63,7 +64,7 @@ pub(crate) async fn validator_reward_by_era_identifier( .to_bytes()? .as_slice(), )?; - let response = communication::send_request(node_address, request).await?; + let response = send_request(node_address, request).await?; parse_response::(response.response()) } @@ -79,7 +80,7 @@ pub(crate) async fn global_state_item_by_state_identifier( }; let global_state_request = GlobalStateRequest::new(global_state_identifier, qualifier); let request = BinaryRequest::Get(GetRequest::State(Box::new(global_state_request))); - let response = communication::send_request(node_address, request).await?; + let response = send_request(node_address, request).await?; check_error_code(&response)?; parse_response::(response.response()) } From 161fb0e2d75d80f053023a177ae2b1deefbfbff2 Mon Sep 17 00:00:00 2001 From: gRoussac Date: Mon, 28 Oct 2024 00:33:34 +0100 Subject: [PATCH 15/32] Doc --- .../src/communication/common.rs | 222 +++++++++++++++++- .../src/communication/wasm32.rs | 168 ++++++++++++- 2 files changed, 370 insertions(+), 20 deletions(-) diff --git a/binary_port_access/src/communication/common.rs b/binary_port_access/src/communication/common.rs index e6928b6..85b0d03 100644 --- a/binary_port_access/src/communication/common.rs +++ b/binary_port_access/src/communication/common.rs @@ -25,18 +25,76 @@ pub(crate) const LENGTH_FIELD_SIZE: usize = 4; #[cfg(not(target_arch = "wasm32"))] const TIMEOUT_DURATION: Duration = Duration::from_secs(5); +/// Establishes an asynchronous TCP connection to a specified node address. +/// +/// This function attempts to connect to a node using a TCP stream. It is only +/// compiled for non-WebAssembly (Wasm) targets, making it suitable for native +/// applications. +/// +/// # Parameters +/// +/// - `node_address`: A `&str` representing the address of the node to which +/// the connection will be made. This should include the host and port (e.g., +/// "localhost:28101"). The default port to use is `28101`. +/// +/// # Returns +/// +/// This function returns a `Result` that, on success, contains a `TcpStream` +/// which represents the established connection. On failure, it returns a +/// `std::io::Error`. +/// +/// # Errors +/// +/// This function may return an error if: +/// - The connection to the specified `node_address` fails. +/// - There are network issues preventing the establishment of the connection. +/// - The address format is invalid. +/// +/// # Notes +/// +/// This function is only compiled for targets other than `wasm32`, ensuring it +/// is used in appropriate environments such as servers or local applications. #[cfg(not(target_arch = "wasm32"))] async fn connect_to_node(node_address: &str) -> Result { let stream = TcpStream::connect(node_address).await?; Ok(stream) } -/// Sends the payload length and data to the client. +/// Sends the payload length and data to the connected TCP client. +/// +/// This asynchronous function sends a binary message to a TCP client. It first sends +/// the length of the message payload as a 4-byte little-endian integer for Casper binary protocol, followed by +/// the actual payload data. This function is intended for use in non-WebAssembly (Wasm) +/// environments, typically on servers or local applications. +/// +/// # Parameters +/// +/// - `client`: A mutable reference to a `TcpStream` representing the connection +/// to the client to which the payload will be sent. +/// - `message`: A reference to a `BinaryMessage` containing the payload data to send. +/// +/// # Returns +/// +/// This function returns a `Result` indicating the outcome of the operation: +/// - `Ok(())`: Indicates the payload was sent successfully. +/// - `Err(Error)`: An error if any part of the send operation fails, including timeout errors. +/// +/// # Errors +/// +/// This function may return an error if: +/// - The write operations timeout, resulting in a `TimeoutError`. +/// - There are issues with the TCP stream that prevent data from being sent. +/// +/// # Notes +/// +/// The function ensures that the TCP connection remains responsive by enforcing a timeout +/// on each write operation. This prevents the function from hanging indefinitely in case +/// of network issues or an unresponsive client. The payload length is sent first, allowing +/// the client to know how many bytes to expect for the subsequent payload data. #[cfg(not(target_arch = "wasm32"))] async fn send_payload(client: &mut TcpStream, message: &BinaryMessage) -> Result<(), Error> { let payload_length = message.payload().len() as u32; let length_bytes = payload_length.to_le_bytes(); - let _ = timeout(TIMEOUT_DURATION, client.write_all(&length_bytes)) .await .map_err(|e| Error::TimeoutError(e.to_string()))?; @@ -48,11 +106,39 @@ async fn send_payload(client: &mut TcpStream, message: &BinaryMessage) -> Result let _ = timeout(TIMEOUT_DURATION, client.flush()) .await .map_err(|e| Error::TimeoutError(e.to_string()))?; - Ok(()) } -/// Reads the response from the client and returns the response buffer. +/// Reads the response from a connected TCP client and returns the response buffer. +/// +/// This asynchronous function reads a response from a TCP stream. It first reads +/// a length prefix to determine how many bytes to read for the actual response. +/// The function is only available for non-WebAssembly (Wasm) targets, ensuring +/// it is used in appropriate environments such as servers or local applications. +/// +/// # Parameters +/// +/// - `client`: A mutable reference to a `TcpStream` representing the connection +/// to the client from which the response will be read. +/// +/// # Returns +/// +/// This function returns a `Result` containing: +/// - `Ok(Vec)`: A vector of bytes representing the response data from the client. +/// - `Err(Error)`: An error if the read operation fails, including timeout errors. +/// +/// # Errors +/// +/// This function may return an error if: +/// - The read operation times out, resulting in a `TimeoutError`. +/// - There are issues reading from the TCP stream, which may yield an `Error`. +/// +/// # Notes +/// +/// The first 4 bytes read from the stream are interpreted as a little-endian +/// unsigned integer indicating the length of the subsequent response data. +/// The function enforces a timeout for read operations to prevent hanging +/// indefinitely on slow or unresponsive clients. #[cfg(not(target_arch = "wasm32"))] async fn read_response(client: &mut TcpStream) -> Result, Error> { let mut length_buf = [0u8; LENGTH_FIELD_SIZE]; @@ -65,10 +151,43 @@ async fn read_response(client: &mut TcpStream) -> Result, Error> { let _ = timeout(TIMEOUT_DURATION, client.read_exact(&mut response_buf)) .await .map_err(|e| Error::TimeoutError(e.to_string()))?; - Ok(response_buf) } +/// Sends a binary request to a node and waits for the response. +/// +/// This asynchronous function establishes a TCP connection to the specified node address, +/// sends a serialized binary request, and processes the response. It generates a unique +/// request ID for each request to correlate with the response received. +/// +/// # Parameters +/// +/// - `node_address`: A string slice that holds the address of the node to connect to, +/// typically in the format "hostname:28101". +/// - `request`: An instance of `BinaryRequest` representing the request data to be sent. +/// +/// # Returns +/// +/// This function returns a `Result` that indicates the outcome of the operation: +/// - `Ok(BinaryResponseAndRequest)`: The processed response received from the node. +/// - `Err(Error)`: An error if any part of the operation fails, including connection issues, +/// serialization errors, or response processing errors. +/// +/// # Errors +/// +/// This function may return an error if: +/// - The connection to the node fails, returning an `Error::ConnectionError`. +/// - Serialization of the request fails, leading to an unwrapped panic in case of a serialization error. +/// - Sending the payload or reading the response times out, resulting in a `TimeoutError`. +/// +/// # Notes +/// +/// The function uses a unique request ID for each request, allowing the response to be +/// associated with the correct request. The payload is sent in two parts: first the length +/// of the payload as a 4-byte little-endian integer, and then the actual payload data. +/// After sending the request, it waits for the response and processes it accordingly. +/// This function is designed to be used in non-WebAssembly (Wasm) environments, typically +/// on servers or local applications. #[cfg(not(target_arch = "wasm32"))] pub(crate) async fn send_request( node_address: &str, @@ -90,6 +209,34 @@ pub(crate) async fn send_request( process_response(response_buf, request_id).await } +/// Encodes a binary request into a byte vector for transmission. +/// +/// This function serializes a `BinaryRequest` along with a specified request ID (if provided) +/// into a byte vector. The encoded data includes a header containing the protocol version, +/// request tag, and the request ID. This byte vector can then be sent over a network connection. +/// +/// # Parameters +/// +/// - `req`: A reference to a `BinaryRequest` instance representing the request to be serialized. +/// - `request_id`: An optional `u16` representing the unique identifier for the request. If not provided, +/// a default value of `0` is used. +/// +/// # Returns +/// +/// This function returns a `Result` that indicates the outcome of the operation: +/// - `Ok(Vec)`: A vector of bytes representing the serialized request, including the header and payload. +/// - `Err(bytesrepr::Error)`: An error if the serialization process fails, indicating the nature of the issue. +/// +/// # Errors +/// +/// The function may return an error if: +/// - Writing the header or the request data to the byte vector fails, which could be due to various +/// reasons, such as insufficient memory or incorrect data structures. +/// +/// # Notes +/// +/// The request ID helps in tracking requests and their corresponding responses, allowing for easier +/// identification in asynchronous communication. pub(crate) fn encode_request( req: &BinaryRequest, request_id: Option, @@ -105,7 +252,43 @@ pub(crate) fn encode_request( Ok(bytes) } -/// Parse response +/// Parses a binary response and deserializes it into a specified type. +/// +/// This function inspects the `BinaryResponse` to determine the type of returned data. If the +/// data type matches the expected type (specified by the generic type parameter `A`), it +/// deserializes the payload into an instance of `A`. +/// +/// # Parameters +/// +/// - `response`: A reference to a `BinaryResponse` instance containing the data to be parsed. +/// +/// # Type Parameters +/// +/// - `A`: A type that implements both `FromBytes` and `PayloadEntity` traits, indicating +/// that the type can be deserialized from a byte slice and represents a valid payload entity. +/// +/// # Returns +/// +/// This function returns a `Result` indicating the outcome of the operation: +/// - `Ok(Some(A))`: If the response type matches, the payload is successfully deserialized +/// into an instance of `A`. +/// - `Ok(None)`: If no data type tag is found in the response, indicating an empty or +/// invalid response payload. +/// - `Err(Error)`: If the data type tag does not match the expected type or if deserialization +/// fails, an error is returned providing details about the issue. +/// +/// # Errors +/// +/// The function may return an error if: +/// - The returned data type tag does not match the expected type. +/// - Deserialization of the payload into type `A` fails due to an invalid byte format or +/// insufficient data. +/// +/// # Notes +/// +/// This function is useful in scenarios where responses from a binary protocol need to be +/// dynamically parsed into specific types based on the data type tag. The use of the +/// `FromBytes` trait allows for flexible and type-safe deserialization. pub(crate) fn parse_response( response: &BinaryResponse, ) -> Result, Error> { @@ -126,7 +309,32 @@ pub(crate) fn parse_response( } } -/// Processes the response buffer and checks for request ID mismatch. +/// Processes the response buffer and checks for a request ID mismatch. +/// +/// This function takes a response buffer, extracts the request ID from the beginning of the buffer, +/// and checks it against the expected request ID. If the IDs match, it proceeds to deserialize the +/// remaining data in the buffer into a `BinaryResponseAndRequest` object. +/// +/// # Parameters +/// +/// - `response_buf`: A vector of bytes representing the response data received from the server. +/// - `request_id`: The expected request ID that was sent with the original request. +/// +/// # Returns +/// +/// This function returns a `Result` indicating the outcome of the operation: +/// - `Ok(BinaryResponseAndRequest)`: If the request ID matches and the response data is successfully +/// deserialized, it returns the deserialized `BinaryResponseAndRequest`. +/// - `Err(Error)`: If there is a mismatch in the request ID or if deserialization fails, an error +/// is returned providing details about the issue. +/// +/// # Errors +/// +/// The function may return an error if: +/// - The extracted request ID does not match the expected request ID, indicating a potential issue +/// with request handling or communication. +/// - Deserialization of the response buffer into `BinaryResponseAndRequest` fails due to an invalid +/// byte format or insufficient data. pub(crate) async fn process_response( response_buf: Vec, request_id: u16, diff --git a/binary_port_access/src/communication/wasm32.rs b/binary_port_access/src/communication/wasm32.rs index acf41d9..dd022eb 100644 --- a/binary_port_access/src/communication/wasm32.rs +++ b/binary_port_access/src/communication/wasm32.rs @@ -34,12 +34,25 @@ fn log(s: &str) { println!("{}", s); } -// TODO Documentation -/// DOC +/// Determines if the current environment is Node.js. +/// +/// This function checks for the presence of the `process` global object and +/// verifies that it has a `versions` property, which is characteristic of +/// a Node.js environment. +/// +/// # Returns +/// +/// Returns `true` if the current environment is identified as Node.js, and +/// `false` otherwise. +/// +/// # Notes +/// +/// This function is compiled only when targeting the `wasm32` architecture, +/// ensuring that it is not included in builds for other targets. #[cfg(target_arch = "wasm32")] fn is_node() -> bool { // Check if 'process' exists and if it has 'versions' property (which is present in Node.js) - let is_node = js_sys::global() + js_sys::global() .dyn_into::() .map(|global| { Reflect::has(&global, &JsString::from("process")).unwrap_or(false) @@ -49,11 +62,40 @@ fn is_node() -> bool { }) .unwrap_or(false) }) - .unwrap_or(false); - // log(&format!("is_node {:?}", is_node)); - is_node + .unwrap_or(false) } +/// Opens a TCP connection to a specified Node.js server and sends a payload. +/// +/// This asynchronous function establishes a TCP connection to a server +/// running in a Node.js environment. It sends a specified payload and +/// waits for a response. The connection is made using a JavaScript script +/// executed in the WebAssembly context, leveraging Node.js's `net` module. +/// +/// # Parameters +/// +/// - `node_address`: A string that specifies the address of the Node.js +/// server in the format "host:port". +/// - `payload`: A `Vec` containing the data to be sent to the server. +/// - `request_id`: A unique identifier for the request, used to process +/// the response appropriately. +/// +/// # Returns +/// +/// This function returns a `Result` containing either a `BinaryResponseAndRequest` +/// on success or an `Error` on failure. +/// +/// # Errors +/// +/// This function may return an `Error` if: +/// - The JavaScript execution fails. +/// - The connection to the TCP server cannot be established. +/// - There is an error in sending or receiving data. +/// +/// # Notes +/// +/// This function is only compiled for the `wasm32` target, ensuring that +/// it does not affect builds for other architectures. #[cfg(target_arch = "wasm32")] async fn open_tcp_connection( node_address: &str, @@ -157,9 +199,41 @@ async fn open_tcp_connection( // Read and process the response let response_buf = read_response(response_bytes).await?; // Now process the response using the request_id - process_response(response_buf.into(), request_id).await + process_response(response_buf, request_id).await } +/// Handles a WebSocket connection, sending a payload and awaiting a response. +/// +/// This asynchronous function manages a WebSocket connection by sending a +/// specified payload to a server and waiting for a binary response. It first +/// sends the length of the payload, followed by the payload itself. The response +/// is received through a message event, processed, and returned. +/// +/// # Parameters +/// +/// - `web_socket`: An instance of `WebSocket` used to establish the connection +/// and communicate with the server. +/// - `payload`: A `Vec` containing the data to be sent over the WebSocket. +/// - `request_id`: A unique identifier for the request, used for processing the +/// response later. +/// +/// # Returns +/// +/// This function returns a `Result` that, on success, contains a +/// `BinaryResponseAndRequest`, and on failure, contains an `Error`. +/// +/// # Errors +/// +/// This function may return an `Error` if: +/// - The WebSocket connection fails to open. +/// - There is an error sending the length buffer or payload. +/// - The WebSocket encounters an error during communication. +/// - The received message cannot be processed correctly. +/// +/// # Notes +/// +/// This function is only compiled for the `wasm32` target, making it suitable +/// for WebAssembly applications where WebSocket communication is required. #[cfg(target_arch = "wasm32")] async fn handle_websocket_connection( web_socket: WebSocket, @@ -318,9 +392,43 @@ async fn handle_websocket_connection( // Process the response data as in the original function let response_buf = read_response(response_data).await?; - process_response(response_buf.into(), request_id).await + process_response(response_buf, request_id).await } +/// Reads and processes a response from a byte vector, extracting the payload +/// based on a length prefix. +/// +/// This asynchronous function reads a response in the form of a byte vector +/// that includes a length prefix. The length prefix indicates the size of the +/// actual payload that follows. The function validates the response format +/// and returns the extracted payload if the format is correct. +/// +/// # Parameters +/// +/// - `response_bytes`: A `Vec` containing the raw bytes of the response +/// received from a server. The first `LENGTH_FIELD_SIZE` bytes represent +/// the length of the subsequent payload. +/// +/// # Returns +/// +/// This function returns a `Result` that, on success, contains a `Vec` +/// representing the extracted payload. On failure, it contains an `Error`. +/// +/// # Errors +/// +/// This function may return an `Error` if: +/// - The input `response_bytes` does not contain enough bytes to read the +/// length prefix. +/// - The specified length of the payload exceeds the total number of bytes +/// available, indicating that the response is incomplete. +/// +/// # Notes +/// +/// Ensure that the `LENGTH_FIELD_SIZE` constant is properly defined to +/// match the expected size of the length prefix (4 bytes for +/// a `u32` for Casper binary protocol). This function is only compiled for the `wasm32` target, +/// making it suitable for WebAssembly applications where binary data +/// processing is required. #[cfg(target_arch = "wasm32")] async fn read_response(response_bytes: Vec) -> Result, Error> { // Ensure we have enough bytes for the length field @@ -346,8 +454,42 @@ async fn read_response(response_bytes: Vec) -> Result, Error> { Ok(response_buf) } -// TODO Documentation -/// DOC +/// Sends a binary request to a specified node address, either via TCP or WebSocket. +/// +/// This asynchronous function generates a unique request ID, encodes the given +/// binary request into a payload, and then sends the request to the specified +/// `node_address`. The method of transmission depends on the environment: +/// - In Node.js, it uses raw TCP connections via the `net` module. +/// - In non-Node.js environments (typically browsers), it uses WebSockets. +/// Note that browsers have CORS (Cross-Origin Resource Sharing) restrictions, +/// so the WebSocket requests should/may be addressed to a WebSocket proxy that +/// redirects the requests to the node's binary port. +/// +/// # Parameters +/// +/// - `node_address`: A `&str` representing the address of the node to which +/// the request will be sent. This should include the host and port (e.g., +/// "localhost:28101"). +/// - `request`: A `BinaryRequest` instance containing the data to be sent. +/// +/// # Returns +/// +/// This function returns a `Result` that, on success, contains a `BinaryResponseAndRequest` +/// indicating the response received from the node. On failure, it returns an `Error`. +/// +/// # Errors +/// +/// This function may return an `Error` if: +/// - There is an issue serializing the request into a binary format. +/// - The connection fails when trying to open a TCP connection in Node.js. +/// - The WebSocket connection cannot be created in non-Node.js environments. +/// - There are issues handling the WebSocket connection. +/// +/// # Notes +/// +/// This function is only compiled for the `wasm32` target, making it suitable +/// for WebAssembly applications where communication with a node server is required. + #[cfg(target_arch = "wasm32")] pub(crate) async fn send_request( node_address: &str, @@ -361,8 +503,8 @@ pub(crate) async fn send_request( // In Node.js, use raw TCP with the `net` module for direct connection let tcp_result = open_tcp_connection(node_address, payload.clone(), request_id).await; match tcp_result { - Ok(response) => return Ok(response), - Err(e) => return Err(Error::Response(format!("TCP connection failed: {:?}", e))), + Ok(response) => Ok(response), + Err(e) => Err(Error::Response(format!("TCP connection failed: {:?}", e))), } } else { // In the browser or non-Node.js environments, use WebSocket @@ -372,6 +514,6 @@ pub(crate) async fn send_request( })?; let response = handle_websocket_connection(web_socket, payload, request_id).await?; - return Ok(response); + Ok(response) } } From 293ad5792d038f64216598b58c775948c7193887 Mon Sep 17 00:00:00 2001 From: gRoussac Date: Mon, 28 Oct 2024 00:36:49 +0100 Subject: [PATCH 16/32] Rename folder --- Cargo.toml | 4 ++-- Makefile | 2 +- README.md | 10 ++++++---- {binary_port_access => binary-port-access}/Cargo.toml | 0 .../src/communication/common.rs | 0 .../src/communication/mod.rs | 0 .../src/communication/wasm32.rs | 0 .../src/error.rs | 0 {binary_port_access => binary-port-access}/src/lib.rs | 0 .../src/utils.rs | 0 10 files changed, 9 insertions(+), 7 deletions(-) rename {binary_port_access => binary-port-access}/Cargo.toml (100%) rename {binary_port_access => binary-port-access}/src/communication/common.rs (100%) rename {binary_port_access => binary-port-access}/src/communication/mod.rs (100%) rename {binary_port_access => binary-port-access}/src/communication/wasm32.rs (100%) rename {binary_port_access => binary-port-access}/src/error.rs (100%) rename {binary_port_access => binary-port-access}/src/lib.rs (100%) rename {binary_port_access => binary-port-access}/src/utils.rs (100%) diff --git a/Cargo.toml b/Cargo.toml index 27e63f9..c19965b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [workspace] resolver = "2" -members = ["binary_port_access"] +members = ["binary-port-access"] [package] name = "casper-binary-port-client" @@ -15,7 +15,7 @@ casper-types = { git = "https://github.com/casper-network/casper-node", branch = "std-fs-io", ] } casper-binary-port = { version = "1.0.0", git = "https://github.com/casper-network/casper-node", branch = "feat-2.0" } -casper-binary-port-access = { path = "./binary_port_access" } +casper-binary-port-access = { path = "./binary-port-access" } clap = { version = "4.5.20", features = ["derive", "wrap_help"] } thiserror = "1.0.64" tokio = { version = "1.41.0", features = ["macros", "rt", "net"] } diff --git a/Makefile b/Makefile index ad24a1c..752bc9d 100644 --- a/Makefile +++ b/Makefile @@ -20,7 +20,7 @@ lint: # Run clippy on wasm32-unknown-unknown target lint-wasm: - cd binary_port_access && cargo clippy --target $(WASM_TARGET) --all-targets -- -D warnings + cd binary-port-access && cargo clippy --target $(WASM_TARGET) --all-targets -- -D warnings # Format the codebase using rustfmt and check for correct formatting fmt-check: diff --git a/README.md b/README.md index 7bec3c4..2d21925 100644 --- a/README.md +++ b/README.md @@ -27,9 +27,10 @@ Commands: Options: -v, --verbose Provides a verbose output as the command is being handled (not supported yet) - -n, --node-address + -n, --node-address -h, --help Print help ``` + To get further info on any command, run `help` followed by the subcommand, e.g. @@ -46,15 +47,16 @@ Retrieve block header by height or hash Usage: casper-binary-port-client information block-header [OPTIONS] Options: - --hash - --height + --hash + --height -h, --help Print help ``` + ## Client library -The `binary_port_access` directory contains source for the client library, which may be called directly rather than through the CLI binary. The CLI app `casper-binary-port-client` makes use of this library to implement its functionality. +The `binary-port-access` directory contains source for the client library, which may be called directly rather than through the CLI binary. The CLI app `casper-binary-port-client` makes use of this library to implement its functionality. ## License diff --git a/binary_port_access/Cargo.toml b/binary-port-access/Cargo.toml similarity index 100% rename from binary_port_access/Cargo.toml rename to binary-port-access/Cargo.toml diff --git a/binary_port_access/src/communication/common.rs b/binary-port-access/src/communication/common.rs similarity index 100% rename from binary_port_access/src/communication/common.rs rename to binary-port-access/src/communication/common.rs diff --git a/binary_port_access/src/communication/mod.rs b/binary-port-access/src/communication/mod.rs similarity index 100% rename from binary_port_access/src/communication/mod.rs rename to binary-port-access/src/communication/mod.rs diff --git a/binary_port_access/src/communication/wasm32.rs b/binary-port-access/src/communication/wasm32.rs similarity index 100% rename from binary_port_access/src/communication/wasm32.rs rename to binary-port-access/src/communication/wasm32.rs diff --git a/binary_port_access/src/error.rs b/binary-port-access/src/error.rs similarity index 100% rename from binary_port_access/src/error.rs rename to binary-port-access/src/error.rs diff --git a/binary_port_access/src/lib.rs b/binary-port-access/src/lib.rs similarity index 100% rename from binary_port_access/src/lib.rs rename to binary-port-access/src/lib.rs diff --git a/binary_port_access/src/utils.rs b/binary-port-access/src/utils.rs similarity index 100% rename from binary_port_access/src/utils.rs rename to binary-port-access/src/utils.rs From b512fb05188bf3474252128bbcb6b9f55cd79990 Mon Sep 17 00:00:00 2001 From: gRoussac Date: Mon, 28 Oct 2024 00:43:03 +0100 Subject: [PATCH 17/32] // doc --- binary-port-access/src/communication/wasm32.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/binary-port-access/src/communication/wasm32.rs b/binary-port-access/src/communication/wasm32.rs index dd022eb..f318eea 100644 --- a/binary-port-access/src/communication/wasm32.rs +++ b/binary-port-access/src/communication/wasm32.rs @@ -65,7 +65,7 @@ fn is_node() -> bool { .unwrap_or(false) } -/// Opens a TCP connection to a specified Node.js server and sends a payload. +/// Opens a TCP connection to a specified binary server and sends a payload. /// /// This asynchronous function establishes a TCP connection to a server /// running in a Node.js environment. It sends a specified payload and From 0c12f5f334e0baf3a97cb69804aaf75bcd812278 Mon Sep 17 00:00:00 2001 From: gRoussac Date: Mon, 28 Oct 2024 00:56:34 +0100 Subject: [PATCH 18/32] clippy --- .../src/communication/wasm32.rs | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/binary-port-access/src/communication/wasm32.rs b/binary-port-access/src/communication/wasm32.rs index f318eea..f4cc507 100644 --- a/binary-port-access/src/communication/wasm32.rs +++ b/binary-port-access/src/communication/wasm32.rs @@ -67,15 +67,15 @@ fn is_node() -> bool { /// Opens a TCP connection to a specified binary server and sends a payload. /// -/// This asynchronous function establishes a TCP connection to a server -/// running in a Node.js environment. It sends a specified payload and +/// This asynchronous function establishes a TCP connection to a binary +/// server. It sends a specified payload and /// waits for a response. The connection is made using a JavaScript script /// executed in the WebAssembly context, leveraging Node.js's `net` module. /// /// # Parameters /// -/// - `node_address`: A string that specifies the address of the Node.js -/// server in the format "host:port". +/// - `node_address`: A string that specifies the address of server +/// in the format "host:port". Typically "127.0.0.1:28101" /// - `payload`: A `Vec` containing the data to be sent to the server. /// - `request_id`: A unique identifier for the request, used to process /// the response appropriately. @@ -489,7 +489,6 @@ async fn read_response(response_bytes: Vec) -> Result, Error> { /// /// This function is only compiled for the `wasm32` target, making it suitable /// for WebAssembly applications where communication with a node server is required. - #[cfg(target_arch = "wasm32")] pub(crate) async fn send_request( node_address: &str, @@ -508,7 +507,15 @@ pub(crate) async fn send_request( } } else { // In the browser or non-Node.js environments, use WebSocket - let ws_url = format!("ws://{}", node_address); + // Note that browsers have CORS (Cross-Origin Resource Sharing) restrictions, + // so the WebSocket requests should/may be addressed to a WebSocket proxy that + // redirects the requests to the node's binary port. Typically "ws://127.0.0.1:8181" proxied to binary "127.0.0.1:28101" + // Ensure node_address does not already contain "ws://" + let ws_url = if node_address.starts_with("ws://") { + node_address.to_string() // Use the existing node_address if it already contains the prefix + } else { + format!("ws://{}", node_address) + }; let web_socket = WebSocket::new(&ws_url).map_err(|e| { Error::WebSocketCreation(format!("Failed to create WebSocket: {:?}", e)) })?; From 919062ca5aa99f6ddf71b399e020336d510e627c Mon Sep 17 00:00:00 2001 From: gRoussac Date: Mon, 28 Oct 2024 00:58:10 +0100 Subject: [PATCH 19/32] Comment --- binary-port-access/src/communication/wasm32.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/binary-port-access/src/communication/wasm32.rs b/binary-port-access/src/communication/wasm32.rs index f4cc507..5b74a9e 100644 --- a/binary-port-access/src/communication/wasm32.rs +++ b/binary-port-access/src/communication/wasm32.rs @@ -252,7 +252,7 @@ async fn handle_websocket_connection( log("Payload length buffer prepared."); - // 1. Send the length buffer first + // Send the length buffer first let length_js_value = js_sys::Uint8Array::from(length_buffer.as_slice()); let payload_clone = payload.clone(); // Clone the payload for sending From 311a8274e8447b2ab20af1445f495997002ed4a8 Mon Sep 17 00:00:00 2001 From: gRoussac Date: Mon, 28 Oct 2024 00:58:50 +0100 Subject: [PATCH 20/32] Comment --- binary-port-access/src/communication/wasm32.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/binary-port-access/src/communication/wasm32.rs b/binary-port-access/src/communication/wasm32.rs index 5b74a9e..72b9740 100644 --- a/binary-port-access/src/communication/wasm32.rs +++ b/binary-port-access/src/communication/wasm32.rs @@ -274,7 +274,7 @@ async fn handle_websocket_connection( } else { log("Length buffer sent successfully, now sending payload."); - // 2. Send the payload after the length buffer has been sent + // Send the payload after the length buffer has been sent let payload_array = js_sys::Uint8Array::from(payload_clone.as_slice()); if let Err(e) = send_func.call1(&ws_clone, &payload_array) { From 31b462f6e05c2928707ef59fdadeb002698fa2f0 Mon Sep 17 00:00:00 2001 From: gRoussac Date: Mon, 28 Oct 2024 01:01:35 +0100 Subject: [PATCH 21/32] Comment --- binary-port-access/src/communication/wasm32.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/binary-port-access/src/communication/wasm32.rs b/binary-port-access/src/communication/wasm32.rs index 72b9740..d498de6 100644 --- a/binary-port-access/src/communication/wasm32.rs +++ b/binary-port-access/src/communication/wasm32.rs @@ -390,8 +390,9 @@ async fn handle_websocket_connection( log(&format!("read_response {:?}", response_data)); - // Process the response data as in the original function - let response_buf = read_response(response_data).await?; + // Read and process the response + let response_buf = read_response(response_bytes).await?; + // Now process the response using the request_id process_response(response_buf, request_id).await } From 6b675075ade7dfa6cd75a710ebc4c8803f264781 Mon Sep 17 00:00:00 2001 From: gRoussac Date: Mon, 28 Oct 2024 01:06:32 +0100 Subject: [PATCH 22/32] remove unused error --- binary-port-access/src/communication/wasm32.rs | 4 ++-- binary-port-access/src/error.rs | 4 ---- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/binary-port-access/src/communication/wasm32.rs b/binary-port-access/src/communication/wasm32.rs index d498de6..6ddf5e7 100644 --- a/binary-port-access/src/communication/wasm32.rs +++ b/binary-port-access/src/communication/wasm32.rs @@ -380,7 +380,7 @@ async fn handle_websocket_connection( .await .map_err(|e| Error::Response(format!("Failed to receive message: {:?}", e)))?; - let response_data = onmessage + let response_bytes = onmessage .dyn_into::() .map_err(|_| Error::Response("Expected Array format for TCP response data".to_string()))? .to_vec() @@ -388,7 +388,7 @@ async fn handle_websocket_connection( .map(|val| val.as_f64().unwrap_or(0.0) as u8) .collect::>(); - log(&format!("read_response {:?}", response_data)); + log(&format!("read_response {:?}", response_bytes)); // Read and process the response let response_buf = read_response(response_bytes).await?; diff --git a/binary-port-access/src/error.rs b/binary-port-access/src/error.rs index 0935dc5..4623723 100644 --- a/binary-port-access/src/error.rs +++ b/binary-port-access/src/error.rs @@ -38,10 +38,6 @@ pub enum Error { #[error("Failed to create WebSocket: {0}")] WebSocketCreation(String), - /// WebSocket send error. - #[error("Failed to send WebSocket message: {0}")] - WebSocketSend(String), - /// JavaScript-related error. #[error("JavaScript error: {0}")] JsError(String), From 1e3979951ebe10a3387c73c7f90a300257796ac1 Mon Sep 17 00:00:00 2001 From: gRoussac Date: Mon, 28 Oct 2024 01:38:55 +0100 Subject: [PATCH 23/32] Comment todo (remove evil eval) --- binary-port-access/src/communication/wasm32.rs | 3 ++- binary-port-access/src/lib.rs | 6 ++---- binary-port-access/src/utils.rs | 1 - 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/binary-port-access/src/communication/wasm32.rs b/binary-port-access/src/communication/wasm32.rs index 6ddf5e7..79c5d89 100644 --- a/binary-port-access/src/communication/wasm32.rs +++ b/binary-port-access/src/communication/wasm32.rs @@ -171,7 +171,8 @@ async fn open_tcp_connection( payload ); - // Execute the script in JavaScript context using eval + // ! TODO [GR] Replace this eval for a global scope function call/apply + // Execute the script in JavaScript context using eval (tcp_script is local) let tcp_promise: Promise = js_sys::eval(&tcp_script) .map_err(|err| { log("Failed to execute TCP script in eval"); diff --git a/binary-port-access/src/lib.rs b/binary-port-access/src/lib.rs index 86321af..48fc938 100644 --- a/binary-port-access/src/lib.rs +++ b/binary-port-access/src/lib.rs @@ -1,11 +1,9 @@ #![deny(missing_docs)] //! This crate provides a high-level API for interacting with a Casper node's binary port interface. -/// Expose communication methods -pub mod communication; +mod communication; mod error; -/// Expose utils methods -pub mod utils; +mod utils; use casper_binary_port::{ BinaryRequest, ConsensusStatus, ConsensusValidatorChanges, EraIdentifier, diff --git a/binary-port-access/src/utils.rs b/binary-port-access/src/utils.rs index f99a3b8..471e462 100644 --- a/binary-port-access/src/utils.rs +++ b/binary-port-access/src/utils.rs @@ -11,7 +11,6 @@ use crate::communication::common::send_request; use crate::communication::wasm32::send_request; use crate::{communication::common::parse_response, Error}; -/// Expose make_information_get_request pub(crate) fn make_information_get_request( tag: InformationRequestTag, key: &[u8], From fc83f898f8f95eb131f281aa29b5e665eeca3430 Mon Sep 17 00:00:00 2001 From: gRoussac Date: Mon, 28 Oct 2024 22:38:59 +0100 Subject: [PATCH 24/32] sanitize_input of node tcp helper --- .../{wasm32.rs => wasm32/mod.rs} | 102 +++++------------- .../communication/wasm32/node_tcp_helper.rs | 67 ++++++++++++ 2 files changed, 96 insertions(+), 73 deletions(-) rename binary-port-access/src/communication/{wasm32.rs => wasm32/mod.rs} (88%) create mode 100644 binary-port-access/src/communication/wasm32/node_tcp_helper.rs diff --git a/binary-port-access/src/communication/wasm32.rs b/binary-port-access/src/communication/wasm32/mod.rs similarity index 88% rename from binary-port-access/src/communication/wasm32.rs rename to binary-port-access/src/communication/wasm32/mod.rs index 79c5d89..2a482bd 100644 --- a/binary-port-access/src/communication/wasm32.rs +++ b/binary-port-access/src/communication/wasm32/mod.rs @@ -9,6 +9,8 @@ use gloo_utils::format::JsValueSerdeExt; #[cfg(target_arch = "wasm32")] use js_sys::{JsString, Promise, Reflect}; #[cfg(target_arch = "wasm32")] +use node_tcp_helper::NODE_TCP_HELPER; +#[cfg(target_arch = "wasm32")] use rand::Rng; #[cfg(target_arch = "wasm32")] use wasm_bindgen::{prelude::Closure, prelude::*, JsCast, JsValue}; @@ -16,6 +18,10 @@ use wasm_bindgen::{prelude::Closure, prelude::*, JsCast, JsValue}; use wasm_bindgen_futures::JsFuture; #[cfg(target_arch = "wasm32")] use web_sys::{MessageEvent, WebSocket}; + +#[cfg(target_arch = "wasm32")] +pub mod node_tcp_helper; + #[cfg(target_arch = "wasm32")] #[wasm_bindgen] extern "C" { @@ -102,77 +108,29 @@ async fn open_tcp_connection( payload: Vec, request_id: u16, ) -> Result { - let tcp_script = format!( - r#" -(async () => {{ - try {{ - const net = require('net'); - const client = new net.Socket(); - const payload = Buffer.from({:?}); - const node_address = '{node_address}'; - const [host, port] = node_address.split(':'); - - // console.log('TCP Client created:'); - // console.log('Payload to send:', payload); - // console.log('node_address', node_address); - // console.log('host', host); - // console.log('port', port); - // console.log('Promise available:', typeof Promise !== 'undefined'); - - return new Promise((resolve, reject) => {{ - // console.log('Connecting to TCP server at', host, port); - - const lengthBuffer = Buffer.alloc(4); - lengthBuffer.writeUInt32LE(payload.length); - client.connect(parseInt(port), host, () => {{ - // console.log('Connected to TCP server'); - - // First, send the length of the payload - client.write(lengthBuffer, (err) => {{ - if (err) {{ - console.error('Error sending length:', err.message); - client.destroy(); - return; - }} - // console.log('Length of payload sent'); - - // Now, send the actual payload - client.write(payload, (err) => {{ - if (err) {{ - console.error('Error sending payload:', err.message); - }} else {{ - // console.log('Payload sent'); - }} - }}); - }}); - }}); - - client.on('data', (data) => {{ - // console.log('Data received from server:', data); - resolve(data); - client.destroy(); // Close connection after receiving response - }}); - - client.on('error', (err) => {{ - console.error('TCP connection error:', err.message); - reject(new Error('TCP connection error: ' + err.message)); - }}); - - client.on('close', () => {{ - // console.log('TCP connection closed'); - }}); - }}); - }} catch (err) {{ - console.error('Error in TCP script:', err.message); - throw new Error('Script execution error: ' + err.message); - }} -}})(); - "#, - payload - ); - - // ! TODO [GR] Replace this eval for a global scope function call/apply - // Execute the script in JavaScript context using eval (tcp_script is local) + use node_tcp_helper::sanitize_input; + + let parts: Vec<&str> = node_address.split(':').collect(); + let host = *parts + .get(0) + .ok_or_else(|| Error::Response("Missing host".to_string()))?; + let port = *parts + .get(1) + .ok_or_else(|| Error::Response("Missing port".to_string()))?; + + // Prepare the payload buffer + let buffer_payload = &format!("{:?}", payload); + + let sanitized_buffer_payload = sanitize_input(buffer_payload); + let sanitized_host = sanitize_input(host); + let sanitized_port = sanitize_input(port); + + let tcp_script = NODE_TCP_HELPER + .replace("{buffer_payload}", &sanitized_buffer_payload) + .replace("{host}", &sanitized_host) + .replace("{port}", &sanitized_port); + + // Execute the script in JavaScript context using eval (tcp_script is local but it requires "require" Js module not available in a classic function js_sys::Function) let tcp_promise: Promise = js_sys::eval(&tcp_script) .map_err(|err| { log("Failed to execute TCP script in eval"); @@ -389,8 +347,6 @@ async fn handle_websocket_connection( .map(|val| val.as_f64().unwrap_or(0.0) as u8) .collect::>(); - log(&format!("read_response {:?}", response_bytes)); - // Read and process the response let response_buf = read_response(response_bytes).await?; // Now process the response using the request_id diff --git a/binary-port-access/src/communication/wasm32/node_tcp_helper.rs b/binary-port-access/src/communication/wasm32/node_tcp_helper.rs new file mode 100644 index 0000000..0237e73 --- /dev/null +++ b/binary-port-access/src/communication/wasm32/node_tcp_helper.rs @@ -0,0 +1,67 @@ +#[cfg(target_arch = "wasm32")] +pub(crate) const NODE_TCP_HELPER: &str = r#" +(async () => {{ + try {{ + const net = require('net'); + const client = new net.Socket(); + const payload = Buffer.from({buffer_payload}); + const host = '{host}'; + const port = '{port}'; + + return new Promise((resolve, reject) => {{ + // console.log('Connecting to TCP server at', host, port); + + const lengthBuffer = Buffer.alloc(4); + lengthBuffer.writeUInt32LE(payload.length); + client.connect(parseInt(port), host, () => {{ + // console.log('Connected to TCP server'); + + // First, send the length of the payload + client.write(lengthBuffer, (err) => {{ + if (err) {{ + console.error('Error sending length:', err.message); + client.destroy(); + return; + }} + // console.log('Length of payload sent'); + + // Now, send the actual payload + client.write(payload, (err) => {{ + if (err) {{ + console.error('Error sending payload:', err.message); + }} else {{ + // console.log('Payload sent'); + }} + }}); + }}); + }}); + client.on('data', (data) => {{ + // console.log('Data received from server:', data); + resolve(data); + client.destroy(); // Close connection after receiving response + }}); + client.on('error', (err) => {{ + console.error('TCP connection error:', err.message); + reject(new Error('TCP connection error: ' + err.message)); + }}); + client.on('close', () => {{ + // console.log('TCP connection closed'); + }}); + }}); + }} catch (err) {{ + console.error('Error in TCP script:', err.message); + throw new Error('Script execution error: ' + err.message); + }} + }} +)();"#; + +pub(crate) fn sanitize_input(input: &str) -> String { + input + .replace("\\", "\\\\") // Escape backslashes + .replace("'", "\\'") // Escape single quotes + .replace("\"", "\\\"") // Escape double quotes + .replace("\n", "\\n") // Escape newlines + .replace("\r", "\\r") // Escape carriage returns + .replace("<", "\\<") // Escape less than + .replace(">", "\\>") // Escape greater than +} From 4fdfa8a249a562a9fa4643f24ba2f6bc95a5e704 Mon Sep 17 00:00:00 2001 From: gRoussac Date: Mon, 28 Oct 2024 22:43:40 +0100 Subject: [PATCH 25/32] clippy --- binary-port-access/src/communication/wasm32/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/binary-port-access/src/communication/wasm32/mod.rs b/binary-port-access/src/communication/wasm32/mod.rs index 2a482bd..4c308bf 100644 --- a/binary-port-access/src/communication/wasm32/mod.rs +++ b/binary-port-access/src/communication/wasm32/mod.rs @@ -112,10 +112,10 @@ async fn open_tcp_connection( let parts: Vec<&str> = node_address.split(':').collect(); let host = *parts - .get(0) + .first() .ok_or_else(|| Error::Response("Missing host".to_string()))?; let port = *parts - .get(1) + .last() .ok_or_else(|| Error::Response("Missing port".to_string()))?; // Prepare the payload buffer From 50ac3c462eab73ffe47604a1987f767e563aa3b4 Mon Sep 17 00:00:00 2001 From: gRoussac Date: Tue, 29 Oct 2024 23:42:04 +0100 Subject: [PATCH 26/32] Remove some logs --- .../src/communication/wasm32/mod.rs | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/binary-port-access/src/communication/wasm32/mod.rs b/binary-port-access/src/communication/wasm32/mod.rs index 4c308bf..8ad65dc 100644 --- a/binary-port-access/src/communication/wasm32/mod.rs +++ b/binary-port-access/src/communication/wasm32/mod.rs @@ -209,7 +209,7 @@ async fn handle_websocket_connection( let mut length_buffer = vec![0; LENGTH_FIELD_SIZE]; length_buffer[..LENGTH_FIELD_SIZE].copy_from_slice(&payload_length.to_le_bytes()); - log("Payload length buffer prepared."); + // log("Payload length buffer prepared."); // Send the length buffer first let length_js_value = js_sys::Uint8Array::from(length_buffer.as_slice()); @@ -218,7 +218,7 @@ async fn handle_websocket_connection( // Set up onopen handler to send length and then payload let onopen = Closure::wrap(Box::new(move || { - log("WebSocket connection opened, attempting to send length buffer."); + // log("WebSocket connection opened, attempting to send length buffer."); // Use ws_clone in the closure directly let send_func_result = js_sys::Reflect::get(&ws_clone, &JsString::from("send")) @@ -231,7 +231,7 @@ async fn handle_websocket_connection( log(&format!("Failed to send length buffer: {:?}", e)); reject_clone.call1(&JsValue::NULL, &e).unwrap(); } else { - log("Length buffer sent successfully, now sending payload."); + // log("Length buffer sent successfully, now sending payload."); // Send the payload after the length buffer has been sent let payload_array = js_sys::Uint8Array::from(payload_clone.as_slice()); @@ -240,7 +240,7 @@ async fn handle_websocket_connection( log(&format!("Failed to send payload: {:?}", e)); reject_clone.call1(&JsValue::NULL, &e).unwrap(); } else { - log("Payload sent successfully, setting up message handler."); + // log("Payload sent successfully, setting up message handler."); let onerror = { let reject_clone = reject_clone.clone(); // Clone for use in onerror @@ -262,7 +262,7 @@ async fn handle_websocket_connection( let onmessage = { let resolve_clone = resolve_clone.clone(); // Clone for use in onmessage Closure::wrap(Box::new(move |event: MessageEvent| { - log("Message received from WebSocket."); + // log("Message received from WebSocket."); // Convert the event data to Blob let data: web_sys::Blob = @@ -276,9 +276,7 @@ async fn handle_websocket_connection( let onload = { let file_reader_clone = file_reader.clone(); // Clone here Closure::wrap(Box::new(move |_: web_sys::ProgressEvent| { - // log( - // "Blob read successfully, converting to Uint8Array.", - // ); + // log("Blob read successfully, converting to Uint8Array."); // Get the result of the FileReader as ArrayBuffer let result = file_reader_clone.result().unwrap(); @@ -313,7 +311,6 @@ async fn handle_websocket_connection( }) as Box) }; - ws_clone.set_onmessage(Some(onmessage.as_ref().unchecked_ref())); onmessage.forget(); // Prevent memory leak by forgetting the closure } @@ -328,7 +325,7 @@ async fn handle_websocket_connection( let ws_ref = web_socket.unchecked_ref::(); ws_ref.set_onopen(Some(onopen.as_ref().unchecked_ref())); - log("WebSocket set_onopen event registered."); + // log("WebSocket set_onopen event registered."); onopen.forget(); // Prevent memory leak by forgetting the closure }); From 8e7d03827722410203b8a3d680bd1a9587dc2c34 Mon Sep 17 00:00:00 2001 From: gRoussac Date: Tue, 5 Nov 2024 15:05:13 +0100 Subject: [PATCH 27/32] check request id in rsponse buffer --- binary-port-access/src/communication/common.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/binary-port-access/src/communication/common.rs b/binary-port-access/src/communication/common.rs index 85b0d03..e974b90 100644 --- a/binary-port-access/src/communication/common.rs +++ b/binary-port-access/src/communication/common.rs @@ -342,6 +342,16 @@ pub(crate) async fn process_response( const REQUEST_ID_START: usize = 0; const REQUEST_ID_END: usize = REQUEST_ID_START + 2; + // Check if the response buffer is at least the size of the request ID + if response_buf.len() < REQUEST_ID_END { + return Err(Error::Response(format!( + "Response buffer is too small: expected at least {} bytes, got {}. Buffer contents: {:?}", + REQUEST_ID_END, + response_buf.len(), + response_buf + ))); + } + // Extract Request ID from the response let _request_id = u16::from_le_bytes( response_buf[REQUEST_ID_START..REQUEST_ID_END] @@ -358,6 +368,7 @@ pub(crate) async fn process_response( } // Deserialize the remaining response data - let response: BinaryResponseAndRequest = bytesrepr::deserialize_from_slice(response_buf)?; + let response: BinaryResponseAndRequest = + bytesrepr::deserialize_from_slice(&response_buf[REQUEST_ID_END..])?; Ok(response) } From 3d58de6ac937277f172ee562b9ac959355defa98 Mon Sep 17 00:00:00 2001 From: gRoussac Date: Tue, 5 Nov 2024 15:08:00 +0100 Subject: [PATCH 28/32] Bad commit --- binary-port-access/src/communication/common.rs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/binary-port-access/src/communication/common.rs b/binary-port-access/src/communication/common.rs index e974b90..c9b004f 100644 --- a/binary-port-access/src/communication/common.rs +++ b/binary-port-access/src/communication/common.rs @@ -345,11 +345,11 @@ pub(crate) async fn process_response( // Check if the response buffer is at least the size of the request ID if response_buf.len() < REQUEST_ID_END { return Err(Error::Response(format!( - "Response buffer is too small: expected at least {} bytes, got {}. Buffer contents: {:?}", - REQUEST_ID_END, - response_buf.len(), - response_buf - ))); + "Response buffer is too small: expected at least {} bytes, got {}. Buffer contents: {:?}", + REQUEST_ID_END, + response_buf.len(), + response_buf + ))); } // Extract Request ID from the response @@ -368,7 +368,6 @@ pub(crate) async fn process_response( } // Deserialize the remaining response data - let response: BinaryResponseAndRequest = - bytesrepr::deserialize_from_slice(&response_buf[REQUEST_ID_END..])?; + let response: BinaryResponseAndRequest = bytesrepr::deserialize_from_slice(response_buf)?; Ok(response) } From 492b3fb71d33924316a11a5d70cc6953e382c830 Mon Sep 17 00:00:00 2001 From: gRoussac Date: Tue, 5 Nov 2024 23:38:47 +0100 Subject: [PATCH 29/32] Reuse web socket in wasm32 --- .../src/communication/wasm32/mod.rs | 478 ++++++++++++------ binary-port-access/src/error.rs | 4 + 2 files changed, 332 insertions(+), 150 deletions(-) diff --git a/binary-port-access/src/communication/wasm32/mod.rs b/binary-port-access/src/communication/wasm32/mod.rs index 8ad65dc..242b37e 100644 --- a/binary-port-access/src/communication/wasm32/mod.rs +++ b/binary-port-access/src/communication/wasm32/mod.rs @@ -13,6 +13,8 @@ use node_tcp_helper::NODE_TCP_HELPER; #[cfg(target_arch = "wasm32")] use rand::Rng; #[cfg(target_arch = "wasm32")] +use std::cell::RefCell; +#[cfg(target_arch = "wasm32")] use wasm_bindgen::{prelude::Closure, prelude::*, JsCast, JsValue}; #[cfg(target_arch = "wasm32")] use wasm_bindgen_futures::JsFuture; @@ -195,147 +197,303 @@ async fn open_tcp_connection( /// for WebAssembly applications where WebSocket communication is required. #[cfg(target_arch = "wasm32")] async fn handle_websocket_connection( - web_socket: WebSocket, + web_socket: &WebSocket, payload: Vec, request_id: u16, ) -> Result { - let promise = Promise::new(&mut |resolve, reject| { - let ws_clone = web_socket.clone(); - let resolve_clone = resolve.clone(); // Clone to use later - let reject_clone = reject.clone(); // Clone to use later - - // Prepare length buffer using LENGTH_FIELD_SIZE - let payload_length = payload.len() as u32; - let mut length_buffer = vec![0; LENGTH_FIELD_SIZE]; - length_buffer[..LENGTH_FIELD_SIZE].copy_from_slice(&payload_length.to_le_bytes()); - - // log("Payload length buffer prepared."); - - // Send the length buffer first - let length_js_value = js_sys::Uint8Array::from(length_buffer.as_slice()); - - let payload_clone = payload.clone(); // Clone the payload for sending - - // Set up onopen handler to send length and then payload - let onopen = Closure::wrap(Box::new(move || { - // log("WebSocket connection opened, attempting to send length buffer."); - - // Use ws_clone in the closure directly - let send_func_result = js_sys::Reflect::get(&ws_clone, &JsString::from("send")) - .and_then(|send_func| send_func.dyn_into::()); - - match send_func_result { - Ok(send_func) => { - // Send length buffer - if let Err(e) = send_func.call1(&ws_clone, &length_js_value) { - log(&format!("Failed to send length buffer: {:?}", e)); - reject_clone.call1(&JsValue::NULL, &e).unwrap(); - } else { - // log("Length buffer sent successfully, now sending payload."); - - // Send the payload after the length buffer has been sent - let payload_array = js_sys::Uint8Array::from(payload_clone.as_slice()); - - if let Err(e) = send_func.call1(&ws_clone, &payload_array) { - log(&format!("Failed to send payload: {:?}", e)); - reject_clone.call1(&JsValue::NULL, &e).unwrap(); - } else { - // log("Payload sent successfully, setting up message handler."); - - let onerror = { - let reject_clone = reject_clone.clone(); // Clone for use in onerror - Closure::wrap(Box::new(move |event: wasm_bindgen::JsValue| { - let error_msg = event - .as_string() - .unwrap_or_else(|| "WebSocket error".to_string()); - log(&format!("WebSocket error: {}", error_msg)); - reject_clone - .call1(&JsValue::NULL, &JsValue::from_str(&error_msg)) - .unwrap(); - }) - as Box) - }; - - ws_clone.set_onerror(Some(onerror.as_ref().unchecked_ref())); - onerror.forget(); // Prevent memory leak by forgetting the closure - - let onmessage = { - let resolve_clone = resolve_clone.clone(); // Clone for use in onmessage - Closure::wrap(Box::new(move |event: MessageEvent| { - // log("Message received from WebSocket."); - - // Convert the event data to Blob - let data: web_sys::Blob = - event.data().dyn_into::().unwrap(); - - // Create a FileReader to read the Blob - let file_reader = web_sys::FileReader::new().unwrap(); // Create FileReader - let resolve_clone = resolve_clone.clone(); // Clone for use in onload - - // Set up the onload closure with the file_reader borrowed - let onload = { - let file_reader_clone = file_reader.clone(); // Clone here - Closure::wrap(Box::new(move |_: web_sys::ProgressEvent| { - // log("Blob read successfully, converting to Uint8Array."); - - // Get the result of the FileReader as ArrayBuffer - let result = file_reader_clone.result().unwrap(); - let array_buffer = - result.dyn_into::().unwrap(); - let uint8_array = - js_sys::Uint8Array::new(&array_buffer); - - // Convert Uint8Array to Vec - let response_bytes = uint8_array.to_vec(); - - // log(&format!("Received bytes: {:?}", response_bytes)); - - // Resolve with binary response - resolve_clone - .call1( - &JsValue::NULL, - &wasm_bindgen::JsValue::from_serde( - &response_bytes, - ) - .unwrap_or_default(), - ) - .unwrap(); - }) - as Box) - }; - - // Set up the onload event for the FileReader - file_reader.set_onload(Some(onload.as_ref().unchecked_ref())); - file_reader.read_as_array_buffer(&data).unwrap(); // Ensure read call - onload.forget(); // Prevent memory leak by forgetting the closure - }) - as Box) - }; - ws_clone.set_onmessage(Some(onmessage.as_ref().unchecked_ref())); - onmessage.forget(); // Prevent memory leak by forgetting the closure - } - } - } - Err(e) => { - log("Failed to find WebSocket send function."); - reject_clone.call1(&JsValue::NULL, &e).unwrap(); // Use the cloned reject - } - } - }) as Box); - - let ws_ref = web_socket.unchecked_ref::(); - ws_ref.set_onopen(Some(onopen.as_ref().unchecked_ref())); - // log("WebSocket set_onopen event registered."); - onopen.forget(); // Prevent memory leak by forgetting the closure - }); + let payload_length = payload.len() as u32; + let length_buffer = create_length_buffer(payload_length); + // log("Payload length buffer prepared."); + + let length_js_value = js_sys::Uint8Array::from(length_buffer.as_slice()); + + let promise: Promise; + // If socket is not opened + if web_socket.ready_state() != WebSocket::OPEN { + promise = Promise::new(&mut |resolve, reject| { + let web_socket_clone = web_socket.clone(); // Clone for the closure + let length_js_value = length_js_value.clone(); // Clone for the closure + let payload_clone = payload.clone(); // Clone for the closure + + // Set up onopen handler to send length and then payload + let onopen = { + Closure::wrap(Box::new(move || { + send_length_and_payload( + &web_socket_clone, + &length_js_value, + &payload_clone, + &resolve, + &reject, + ); + }) as Box) + }; + + let web_socket_ref = web_socket.unchecked_ref::(); + web_socket_ref.set_onopen(Some(onopen.as_ref().unchecked_ref())); + onopen.forget(); // Prevent memory leak by forgetting the closure + }); + } + // Socket is already opened + else { + promise = Promise::new(&mut |resolve, reject| { + let web_socket_clone = web_socket.clone(); // Clone for the closure + let length_js_value = length_js_value.clone(); // Clone for the closure + let payload_clone = payload.clone(); // Clone for the closure + + // Directly send length and payload + send_length_and_payload( + &web_socket_clone, + &length_js_value, + &payload_clone, + &resolve, + &reject, + ); + }); + } let js_future = JsFuture::from(js_sys::Promise::resolve(&promise)); // Await the resolved value from the promise - let onmessage = js_future - .await - .map_err(|e| Error::Response(format!("Failed to receive message: {:?}", e)))?; + let onmessage = js_future.await.map_err(|e| { + log(&format!("Failed to receive message: {:?}", e)); + Error::Response(format!("Failed to receive message: {:?}", e)) + })?; + + let response_bytes = extract_response_bytes(onmessage)?; + + // Read and process the response + let response_buf = read_response(response_bytes).await?; + // Now process the response using the request_id + process_response(response_buf, request_id).await +} + +/// Creates a length buffer to represent the size of the payload. +/// +/// This function initializes a buffer of fixed size, which is used to store +/// the length of the payload in little-endian byte order. It ensures that +/// the length can be correctly interpreted +/// +/// # Parameters +/// +/// - `payload_length`: The length of the payload to be encoded in the buffer, +/// represented as a `u32`. This value is converted to a byte array and +/// stored in the buffer. +/// +/// # Returns +/// +/// Returns a `Vec` containing the byte representation of the payload length, +/// with the length stored in little-endian format. The size of the vector is +/// determined by `LENGTH_FIELD_SIZE`. +#[cfg(target_arch = "wasm32")] +fn create_length_buffer(payload_length: u32) -> Vec { + let mut length_buffer = vec![0; LENGTH_FIELD_SIZE]; + length_buffer[..LENGTH_FIELD_SIZE].copy_from_slice(&payload_length.to_le_bytes()); + length_buffer +} + +/// Sends the length of the payload followed by the payload itself over a WebSocket. +/// +/// This function retrieves the WebSocket's `send` method and sends the specified +/// length and payload. It first sends the length of the payload encoded as a +/// `Uint8Array`, and then, upon successful transmission, it invokes the +/// `send_payload` function to send the actual payload data. +/// +/// # Parameters +/// +/// - `web_socket`: A reference to the `WebSocket` instance to which the data will be sent. +/// - `length_js_value`: A reference to a `Uint8Array` that contains the length of the payload, +/// which will be sent first. +/// - `payload`: A reference to the `Vec` containing the actual payload data +/// to be sent after the length. +/// - `resolve`: A reference to a JavaScript function that will be called to resolve the +/// promise if the send operation is successful. +/// - `reject`: A reference to a JavaScript function that will be called to reject the +/// promise if an error occurs during the send operation. +/// +/// # Behavior +/// +/// - If the WebSocket's `send` method is successfully retrieved and called with the +/// `length_js_value`, the function proceeds to send the actual payload using the +/// `send_payload` function. +/// - If an error occurs while sending the length, it logs the error and calls the +/// `reject` function, passing the error as an argument. +/// - If the `send` method cannot be found, it logs an error message and calls the +/// `reject` function with the corresponding error. +#[cfg(target_arch = "wasm32")] +fn send_length_and_payload( + web_socket: &WebSocket, + length_js_value: &js_sys::Uint8Array, + payload: &Vec, + resolve: &js_sys::Function, + reject: &js_sys::Function, +) { + let send_func_result = js_sys::Reflect::get(&web_socket, &JsString::from("send")) + .and_then(|send_func| send_func.dyn_into::()); + + match send_func_result { + Ok(send_func) => { + if let Err(e) = send_func.call1(&web_socket, &length_js_value) { + log(&format!("Failed to send length buffer: {:?}", e)); + reject.call1(&JsValue::NULL, &e).unwrap(); + } else { + // log("Length buffer sent successfully, now sending payload."); + send_payload(&send_func, &web_socket, &payload, &resolve, &reject); + } + } + Err(e) => { + log("Failed to find WebSocket send function."); + reject.call1(&JsValue::NULL, &e).unwrap(); // Use the cloned reject + } + } +} + +/// Sends the payload data over the specified WebSocket. +/// +/// This function converts the provided payload into a `Uint8Array` and uses the +/// provided `send_func` to send it over the WebSocket. If the send operation is +/// successful, it sets up a message handler; otherwise, it logs the error and +/// calls the provided reject function. +/// +/// # Parameters +/// +/// - `send_func`: A reference to the JavaScript function used to send data over the WebSocket. +/// - `web_socket`: A reference to the `WebSocket` instance through which the payload will be sent. +/// - `payload`: A reference to a `Vec` containing the data to be sent. +/// - `resolve`: A reference to a JavaScript function that will be called to resolve the +/// promise if the send operation is successful. +/// - `reject`: A reference to a JavaScript function that will be called to reject the +/// promise if an error occurs during the send operation. +#[cfg(target_arch = "wasm32")] +fn send_payload( + send_func: &js_sys::Function, + web_socket: &WebSocket, + payload: &Vec, + resolve: &js_sys::Function, + reject: &js_sys::Function, +) { + let payload_array = js_sys::Uint8Array::from(payload.as_slice()); + if let Err(e) = send_func.call1(&web_socket, &payload_array) { + log(&format!("Failed to send payload: {:?}", e)); + reject.call1(&JsValue::NULL, &e).unwrap(); + } else { + // log("Payload sent successfully, setting up message handler."); + setup_message_handler(web_socket, resolve, reject); + } +} + +/// Sets up message and error handlers for the specified WebSocket. +/// +/// This function configures the WebSocket to handle incoming messages and errors. +/// It defines two closures: one for handling WebSocket errors and another for +/// processing incoming messages. If an error occurs, it logs the error and calls +/// the provided reject function. When a message is received, it calls the +/// provided resolve function to process the message. +/// +/// # Parameters +/// +/// - `web_socket`: A reference to the `WebSocket` instance for which the handlers are being set up. +/// - `resolve`: A reference to a JavaScript function that will be called to resolve the +/// promise when a message is received. +/// - `reject`: A reference to a JavaScript function that will be called to reject the +/// promise if an error occurs during WebSocket communication. +#[cfg(target_arch = "wasm32")] +fn setup_message_handler( + web_socket: &WebSocket, + resolve: &js_sys::Function, + reject: &js_sys::Function, +) { + let onerror = { + let reject = reject.clone(); // Clone for use in onerror + Closure::wrap(Box::new(move |event: wasm_bindgen::JsValue| { + let error_msg = event + .as_string() + .unwrap_or_else(|| "WebSocket error".to_string()); + log(&format!("WebSocket error: {}", error_msg)); + reject + .call1(&JsValue::NULL, &JsValue::from_str(&error_msg)) + .unwrap(); + }) as Box) + }; + + web_socket.set_onerror(Some(onerror.as_ref().unchecked_ref())); + onerror.forget(); // Prevent memory leak by forgetting the closure + + let onmessage = { + let resolve = resolve.clone(); // Clone for use in onmessage + Closure::wrap(Box::new(move |event: MessageEvent| { + // log("Message received from WebSocket."); + handle_message(event, resolve.clone()); + }) as Box) + }; + web_socket.set_onmessage(Some(onmessage.as_ref().unchecked_ref())); + onmessage.forget(); // Prevent memory leak by forgetting the closure +} + +/// Handles incoming messages from the WebSocket. +/// +/// This function is triggered when a message event occurs. It extracts the data +/// from the message event, which is expected to be a `Blob`. It then uses a +/// `FileReader` to read the `Blob` data as an `ArrayBuffer`. Upon successful +/// reading, it converts the data to a `Uint8Array` and resolves the provided +/// function with the binary response. +/// +/// # Parameters +/// +/// - `event`: The `MessageEvent` that contains the incoming data from the WebSocket. +/// - `resolve`: A reference to a JavaScript function that will be called with the +/// binary response once the `Blob` data has been successfully read. +#[cfg(target_arch = "wasm32")] +fn handle_message(event: MessageEvent, resolve: js_sys::Function) { + // Convert the event data to Blob + let data: web_sys::Blob = event.data().dyn_into::().unwrap(); + + // Create a FileReader to read the Blob + let file_reader = web_sys::FileReader::new().unwrap(); // Create FileReader + let resolve = resolve.clone(); // Clone for use in onload + + // Set up the onload closure + let onload = { + let file_reader = file_reader.clone(); // Clone here + Closure::wrap(Box::new(move |_: web_sys::ProgressEvent| { + // log("Blob read successfully, converting to Uint8Array."); + let result = file_reader.result().unwrap(); + let array_buffer = result.dyn_into::().unwrap(); + let uint8_array = js_sys::Uint8Array::new(&array_buffer); + let response_bytes = uint8_array.to_vec(); + // log(&format!("Received bytes: {:?}", response_bytes)); + + // Resolve with binary response + resolve + .call1( + &JsValue::NULL, + &wasm_bindgen::JsValue::from_serde(&response_bytes).unwrap_or_default(), + ) + .unwrap(); + }) as Box) + }; + + // Set up the onload event for the FileReader + file_reader.set_onload(Some(onload.as_ref().unchecked_ref())); + file_reader.read_as_array_buffer(&data).unwrap(); // Ensure read call + onload.forget(); // Prevent memory leak by forgetting the closure +} +/// Extracts response bytes from a JavaScript value. +/// +/// This function takes a JavaScript value expected to be an `Array`, converts it +/// into a Rust vector of bytes, and returns it. If the conversion fails, it returns +/// an `Error` indicating that the expected format was not met. +/// +/// # Parameters +/// +/// - `onmessage`: A `JsValue` that should contain the response data in the form of a JavaScript `Array`. +/// +/// # Returns +/// +/// A `Result, Error>`, where the `Ok` variant contains the extracted bytes as a `Vec`, +/// and the `Err` variant contains an `Error` if the conversion fails. +#[cfg(target_arch = "wasm32")] +fn extract_response_bytes(onmessage: JsValue) -> Result, Error> { let response_bytes = onmessage .dyn_into::() .map_err(|_| Error::Response("Expected Array format for TCP response data".to_string()))? @@ -343,11 +501,7 @@ async fn handle_websocket_connection( .into_iter() .map(|val| val.as_f64().unwrap_or(0.0) as u8) .collect::>(); - - // Read and process the response - let response_buf = read_response(response_bytes).await?; - // Now process the response using the request_id - process_response(response_buf, request_id).await + Ok(response_bytes) } /// Reads and processes a response from a byte vector, extracting the payload @@ -453,6 +607,10 @@ pub(crate) async fn send_request( let payload = encode_request(&request, Some(request_id)) .map_err(|e| Error::Serialization(format!("Failed to serialize request: {}", e)))?; + thread_local! { + static WS: RefCell> = RefCell::new(None); + } + if is_node() { // In Node.js, use raw TCP with the `net` module for direct connection let tcp_result = open_tcp_connection(node_address, payload.clone(), request_id).await; @@ -461,21 +619,41 @@ pub(crate) async fn send_request( Err(e) => Err(Error::Response(format!("TCP connection failed: {:?}", e))), } } else { - // In the browser or non-Node.js environments, use WebSocket - // Note that browsers have CORS (Cross-Origin Resource Sharing) restrictions, - // so the WebSocket requests should/may be addressed to a WebSocket proxy that - // redirects the requests to the node's binary port. Typically "ws://127.0.0.1:8181" proxied to binary "127.0.0.1:28101" - // Ensure node_address does not already contain "ws://" - let ws_url = if node_address.starts_with("ws://") { - node_address.to_string() // Use the existing node_address if it already contains the prefix + let web_socket_url = if node_address.starts_with("ws://") { + node_address.to_string() } else { format!("ws://{}", node_address) }; - let web_socket = WebSocket::new(&ws_url).map_err(|e| { - Error::WebSocketCreation(format!("Failed to create WebSocket: {:?}", e)) - })?; - let response = handle_websocket_connection(web_socket, payload, request_id).await?; - Ok(response) + // Check if WebSocket is already initialized and if it is open + let mut web_socket = WS.with(|ws| ws.borrow_mut().clone()); + + if web_socket.is_none() + || web_socket.as_ref().unwrap().ready_state() == WebSocket::CLOSED + || web_socket.as_ref().unwrap().ready_state() == WebSocket::CLOSING + { + // Create a new WebSocket if it doesn't exist or is not open + web_socket = Some(WebSocket::new(&web_socket_url).map_err(|e| { + Error::WebSocketCreation(format!("Failed to create WebSocket: {:?}", e)) + })?); + + // Setup error and close event handlers to update WebSocket state + let web_socket_clone = web_socket.as_ref().unwrap().clone(); + // Save the new WebSocket in the thread-local variable + WS.with(|ws| { + *ws.borrow_mut() = Some(web_socket_clone); + }); + } + + let web_socket_ref = web_socket.as_ref().unwrap(); + + if web_socket_ref.ready_state() == WebSocket::CONNECTING + || web_socket_ref.ready_state() == WebSocket::OPEN + { + let response = handle_websocket_connection(web_socket_ref, payload, request_id).await?; + Ok(response) + } else { + return Err(Error::WebSocketSend("WebSocket is not open".to_string())); + } } } diff --git a/binary-port-access/src/error.rs b/binary-port-access/src/error.rs index 4623723..052c908 100644 --- a/binary-port-access/src/error.rs +++ b/binary-port-access/src/error.rs @@ -38,6 +38,10 @@ pub enum Error { #[error("Failed to create WebSocket: {0}")] WebSocketCreation(String), + /// WebSocket creation error. + #[error("Failed to create WebSocket: {0}")] + WebSocketSend(String), + /// JavaScript-related error. #[error("JavaScript error: {0}")] JsError(String), From f777653188e959c7a5a3c046330e0544ce1417a5 Mon Sep 17 00:00:00 2001 From: gRoussac Date: Tue, 5 Nov 2024 23:46:50 +0100 Subject: [PATCH 30/32] // comment --- binary-port-access/src/communication/wasm32/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/binary-port-access/src/communication/wasm32/mod.rs b/binary-port-access/src/communication/wasm32/mod.rs index 242b37e..4f864da 100644 --- a/binary-port-access/src/communication/wasm32/mod.rs +++ b/binary-port-access/src/communication/wasm32/mod.rs @@ -291,7 +291,7 @@ fn create_length_buffer(payload_length: u32) -> Vec { length_buffer } -/// Sends the length of the payload followed by the payload itself over a WebSocket. +/// Sends the length of the payload followed by the payload itself over the WebSocket. /// /// This function retrieves the WebSocket's `send` method and sends the specified /// length and payload. It first sends the length of the payload encoded as a From 36c2e6cb6cb43be38f1f6e30421d10094cbd1c10 Mon Sep 17 00:00:00 2001 From: gRoussac Date: Tue, 5 Nov 2024 23:54:03 +0100 Subject: [PATCH 31/32] Clippy --- Cargo.lock | 95 ++++++++++++------- .../src/communication/wasm32/mod.rs | 25 +++-- 2 files changed, 73 insertions(+), 47 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 90fc458..5ee470a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -28,9 +28,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.17" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23a1e53f0f5d86382dafe1cf314783b2044280f406e7e1506368220ad11b1338" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" dependencies = [ "anstyle", "anstyle-parse", @@ -43,9 +43,9 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8365de52b16c035ff4fcafe0092ba9390540e3e352870ac09933bebcaa2c8c56" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" [[package]] name = "anstyle-parse" @@ -182,7 +182,7 @@ checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" [[package]] name = "casper-binary-port" version = "1.0.0" -source = "git+https://github.com/casper-network/casper-node?branch=feat-2.0#a44f882afa7f401ea55361ec26fbb8ef9bd4fbbc" +source = "git+https://github.com/casper-network/casper-node?branch=feat-2.0#1305f65716b687bac362d9747cbe2d521f96007f" dependencies = [ "bincode", "bytes", @@ -192,6 +192,8 @@ dependencies = [ "schemars", "serde", "serde-map-to-array", + "strum", + "strum_macros", "thiserror", "tokio-util", ] @@ -232,7 +234,7 @@ dependencies = [ [[package]] name = "casper-types" version = "5.0.0" -source = "git+https://github.com/casper-network/casper-node?branch=feat-2.0#a44f882afa7f401ea55361ec26fbb8ef9bd4fbbc" +source = "git+https://github.com/casper-network/casper-node?branch=feat-2.0#1305f65716b687bac362d9747cbe2d521f96007f" dependencies = [ "base16", "base64", @@ -306,7 +308,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -404,7 +406,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -447,7 +449,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -645,7 +647,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -740,9 +742,9 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "hashbrown" -version = "0.15.0" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" +checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3" [[package]] name = "heck" @@ -801,7 +803,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "equivalent", - "hashbrown 0.15.0", + "hashbrown 0.15.1", ] [[package]] @@ -932,7 +934,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -1143,9 +1145,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.38" +version = "0.38.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa260229e6538e52293eeb577aabd09945a09d6d9cc0fc550ed7529056c2e32a" +checksum = "375116bee2be9ed569afe2154ea6a99dfdffd257f533f187498c2a8f5feaf4ee" dependencies = [ "bitflags 2.6.0", "errno", @@ -1154,6 +1156,12 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "rustversion" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" + [[package]] name = "ryu" version = "1.0.18" @@ -1182,7 +1190,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -1206,9 +1214,9 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.213" +version = "1.0.214" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ea7893ff5e2466df8d720bb615088341b295f849602c6956047f8f80f0e9bc1" +checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5" dependencies = [ "serde_derive", ] @@ -1234,13 +1242,13 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.213" +version = "1.0.214" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e85ad2009c50b58e87caa8cd6dac16bdf511bbfb7af6c33df902396aa480fa5" +checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -1251,7 +1259,7 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -1329,6 +1337,25 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +[[package]] +name = "strum" +version = "0.26.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" + +[[package]] +name = "strum_macros" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.87", +] + [[package]] name = "subtle" version = "2.6.1" @@ -1348,9 +1375,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.85" +version = "2.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5023162dfcd14ef8f32034d8bcd4cc5ddc61ef7a247c024a33e24e1f24d21b56" +checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" dependencies = [ "proc-macro2", "quote", @@ -1369,22 +1396,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.65" +version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d11abd9594d9b38965ef50805c5e469ca9cc6f197f883f717e0269a3057b3d5" +checksum = "02dd99dc800bbb97186339685293e1cc5d9df1f8fae2d0aecd9ff1c77efea892" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.65" +version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae71770322cbd277e69d762a16c444af02aa0575ac0d174f0b9562d3b37f8602" +checksum = "a7c61ec9a6f64d2793d8a45faba21efbe3ced62a886d44c36a009b2b519b4c7e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -1411,7 +1438,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -1520,7 +1547,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", "wasm-bindgen-shared", ] @@ -1554,7 +1581,7 @@ checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -1675,7 +1702,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] diff --git a/binary-port-access/src/communication/wasm32/mod.rs b/binary-port-access/src/communication/wasm32/mod.rs index 4f864da..5592fe2 100644 --- a/binary-port-access/src/communication/wasm32/mod.rs +++ b/binary-port-access/src/communication/wasm32/mod.rs @@ -207,10 +207,9 @@ async fn handle_websocket_connection( let length_js_value = js_sys::Uint8Array::from(length_buffer.as_slice()); - let promise: Promise; // If socket is not opened - if web_socket.ready_state() != WebSocket::OPEN { - promise = Promise::new(&mut |resolve, reject| { + let promise: Promise = if web_socket.ready_state() != WebSocket::OPEN { + Promise::new(&mut |resolve, reject| { let web_socket_clone = web_socket.clone(); // Clone for the closure let length_js_value = length_js_value.clone(); // Clone for the closure let payload_clone = payload.clone(); // Clone for the closure @@ -231,11 +230,11 @@ async fn handle_websocket_connection( let web_socket_ref = web_socket.unchecked_ref::(); web_socket_ref.set_onopen(Some(onopen.as_ref().unchecked_ref())); onopen.forget(); // Prevent memory leak by forgetting the closure - }); + }) } // Socket is already opened else { - promise = Promise::new(&mut |resolve, reject| { + Promise::new(&mut |resolve, reject| { let web_socket_clone = web_socket.clone(); // Clone for the closure let length_js_value = length_js_value.clone(); // Clone for the closure let payload_clone = payload.clone(); // Clone for the closure @@ -248,8 +247,8 @@ async fn handle_websocket_connection( &resolve, &reject, ); - }); - } + }) + }; let js_future = JsFuture::from(js_sys::Promise::resolve(&promise)); @@ -327,17 +326,17 @@ fn send_length_and_payload( resolve: &js_sys::Function, reject: &js_sys::Function, ) { - let send_func_result = js_sys::Reflect::get(&web_socket, &JsString::from("send")) + let send_func_result = js_sys::Reflect::get(web_socket, &JsString::from("send")) .and_then(|send_func| send_func.dyn_into::()); match send_func_result { Ok(send_func) => { - if let Err(e) = send_func.call1(&web_socket, &length_js_value) { + if let Err(e) = send_func.call1(web_socket, length_js_value) { log(&format!("Failed to send length buffer: {:?}", e)); reject.call1(&JsValue::NULL, &e).unwrap(); } else { // log("Length buffer sent successfully, now sending payload."); - send_payload(&send_func, &web_socket, &payload, &resolve, &reject); + send_payload(&send_func, web_socket, payload, resolve, reject); } } Err(e) => { @@ -372,7 +371,7 @@ fn send_payload( reject: &js_sys::Function, ) { let payload_array = js_sys::Uint8Array::from(payload.as_slice()); - if let Err(e) = send_func.call1(&web_socket, &payload_array) { + if let Err(e) = send_func.call1(web_socket, &payload_array) { log(&format!("Failed to send payload: {:?}", e)); reject.call1(&JsValue::NULL, &e).unwrap(); } else { @@ -608,7 +607,7 @@ pub(crate) async fn send_request( .map_err(|e| Error::Serialization(format!("Failed to serialize request: {}", e)))?; thread_local! { - static WS: RefCell> = RefCell::new(None); + static WS: RefCell> = const { RefCell::new(None) }; } if is_node() { @@ -653,7 +652,7 @@ pub(crate) async fn send_request( let response = handle_websocket_connection(web_socket_ref, payload, request_id).await?; Ok(response) } else { - return Err(Error::WebSocketSend("WebSocket is not open".to_string())); + Err(Error::WebSocketSend("WebSocket is not open".to_string())) } } } From 63ae0cb02cc34d9a5813cbf32f8da4428fd67e4b Mon Sep 17 00:00:00 2001 From: gRoussac Date: Wed, 11 Dec 2024 20:24:16 +0100 Subject: [PATCH 32/32] DelegatorKind --- Cargo.lock | 202 +++++++++++++++++--------------- binary-port-access/src/utils.rs | 6 +- 2 files changed, 110 insertions(+), 98 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5ee470a..1c1210b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -175,14 +175,14 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" +checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" [[package]] name = "casper-binary-port" version = "1.0.0" -source = "git+https://github.com/casper-network/casper-node?branch=feat-2.0#1305f65716b687bac362d9747cbe2d521f96007f" +source = "git+https://github.com/casper-network/casper-node?branch=feat-2.0#c881b11436676af775eccc46fb85e50fc8a504f9" dependencies = [ "bincode", "bytes", @@ -196,6 +196,7 @@ dependencies = [ "strum_macros", "thiserror", "tokio-util", + "tracing", ] [[package]] @@ -234,7 +235,7 @@ dependencies = [ [[package]] name = "casper-types" version = "5.0.0" -source = "git+https://github.com/casper-network/casper-node?branch=feat-2.0#1305f65716b687bac362d9747cbe2d521f96007f" +source = "git+https://github.com/casper-network/casper-node?branch=feat-2.0#c881b11436676af775eccc46fb85e50fc8a504f9" dependencies = [ "base16", "base64", @@ -278,9 +279,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.5.20" +version = "4.5.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" +checksum = "3135e7ec2ef7b10c6ed8950f0f792ed96ee093fa088608f1c76e569722700c84" dependencies = [ "clap_builder", "clap_derive", @@ -288,9 +289,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.20" +version = "4.5.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" +checksum = "30582fc632330df2bd26877bde0c1f4470d57c582bbc070376afcd04d8cb4838" dependencies = [ "anstream", "anstyle", @@ -308,14 +309,14 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] name = "clap_lex" -version = "0.7.2" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" +checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" [[package]] name = "colorchoice" @@ -337,9 +338,9 @@ checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" [[package]] name = "cpufeatures" -version = "0.2.14" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" +checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3" dependencies = [ "libc", ] @@ -406,7 +407,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -449,7 +450,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -567,12 +568,12 @@ dependencies = [ [[package]] name = "errno" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -647,7 +648,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -742,9 +743,9 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "hashbrown" -version = "0.15.1" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" [[package]] name = "heck" @@ -752,12 +753,6 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" -[[package]] -name = "hermit-abi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" - [[package]] name = "hex" version = "0.4.3" @@ -798,12 +793,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.6.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" +checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" dependencies = [ "equivalent", - "hashbrown 0.15.1", + "hashbrown 0.15.2", ] [[package]] @@ -823,16 +818,17 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.11" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" [[package]] name = "js-sys" -version = "0.3.72" +version = "0.3.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" +checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7" dependencies = [ + "once_cell", "wasm-bindgen", ] @@ -850,9 +846,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.161" +version = "0.2.168" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" +checksum = "5aaeb2981e0606ca11d79718f8bb01164f1d6ed75080182d3abf017e6d244b6d" [[package]] name = "linux-raw-sys" @@ -883,11 +879,10 @@ dependencies = [ [[package]] name = "mio" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" +checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" dependencies = [ - "hermit-abi", "libc", "wasi", "windows-sys 0.52.0", @@ -934,7 +929,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -1043,9 +1038,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.89" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" dependencies = [ "unicode-ident", ] @@ -1103,9 +1098,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.8" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", @@ -1145,15 +1140,15 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.39" +version = "0.38.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "375116bee2be9ed569afe2154ea6a99dfdffd257f533f187498c2a8f5feaf4ee" +checksum = "f93dc38ecbab2eb790ff964bb77fa94faf256fd3e73285fd7ba0903b76bedb85" dependencies = [ "bitflags 2.6.0", "errno", "libc", "linux-raw-sys", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -1190,7 +1185,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -1214,9 +1209,9 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.214" +version = "1.0.216" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5" +checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e" dependencies = [ "serde_derive", ] @@ -1242,13 +1237,13 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.214" +version = "1.0.216" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766" +checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -1259,16 +1254,16 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] name = "serde_json" -version = "1.0.132" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" +checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" dependencies = [ - "indexmap 2.6.0", + "indexmap 2.7.0", "itoa", "memchr", "ryu", @@ -1307,9 +1302,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.5.7" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8" dependencies = [ "libc", "windows-sys 0.52.0", @@ -1353,7 +1348,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -1375,9 +1370,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.87" +version = "2.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" +checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" dependencies = [ "proc-macro2", "quote", @@ -1386,9 +1381,9 @@ dependencies = [ [[package]] name = "terminal_size" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f599bd7ca042cfdf8f4512b277c02ba102247820f9d9d4a9f521f496751a6ef" +checksum = "5352447f921fda68cf61b4101566c0bdb5104eff6804d0678e5227580ab6a4e9" dependencies = [ "rustix", "windows-sys 0.59.0", @@ -1396,29 +1391,29 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.68" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02dd99dc800bbb97186339685293e1cc5d9df1f8fae2d0aecd9ff1c77efea892" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.68" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7c61ec9a6f64d2793d8a45faba21efbe3ced62a886d44c36a009b2b519b4c7e" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] name = "tokio" -version = "1.41.0" +version = "1.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "145f3413504347a2be84393cc8a7d2fb4d863b375909ea59f2158261aa258bbb" +checksum = "5cec9b21b0450273377fc97bd4c33a8acffc8c996c987a7c5b319a0083707551" dependencies = [ "backtrace", "bytes", @@ -1438,7 +1433,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -1457,19 +1452,34 @@ dependencies = [ [[package]] name = "tracing" -version = "0.1.40" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ "pin-project-lite", + "tracing-attributes", "tracing-core", ] +[[package]] +name = "tracing-attributes" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", +] + [[package]] name = "tracing-core" -version = "0.1.32" +version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" +dependencies = [ + "once_cell", +] [[package]] name = "typeid" @@ -1497,9 +1507,9 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" [[package]] name = "untrusted" @@ -1527,9 +1537,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.95" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" +checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396" dependencies = [ "cfg-if", "once_cell", @@ -1538,36 +1548,36 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.95" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" +checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79" dependencies = [ "bumpalo", "log", - "once_cell", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.45" +version = "0.4.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc7ec4f8827a71586374db3e87abdb5a2bb3a15afed140221307c3ec06b1f63b" +checksum = "38176d9b44ea84e9184eff0bc34cc167ed044f816accfe5922e54d84cf48eca2" dependencies = [ "cfg-if", "js-sys", + "once_cell", "wasm-bindgen", "web-sys", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.95" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" +checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1575,28 +1585,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.95" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" +checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.95" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" +checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6" [[package]] name = "web-sys" -version = "0.3.72" +version = "0.3.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6488b90108c040df0fe62fa815cbdee25124641df01814dd7282749234c6112" +checksum = "04dd7223427d52553d3702c004d3b2fe07c148165faa56313cb00211e31c12bc" dependencies = [ "js-sys", "wasm-bindgen", @@ -1702,7 +1712,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] diff --git a/binary-port-access/src/utils.rs b/binary-port-access/src/utils.rs index 471e462..962a33b 100644 --- a/binary-port-access/src/utils.rs +++ b/binary-port-access/src/utils.rs @@ -3,7 +3,9 @@ use casper_binary_port::{ GlobalStateQueryResult, GlobalStateRequest, InformationRequest, InformationRequestTag, RecordId, RewardResponse, }; -use casper_types::{bytesrepr::ToBytes, GlobalStateIdentifier, Key, PublicKey}; +use casper_types::{ + bytesrepr::ToBytes, system::auction::DelegatorKind, GlobalStateIdentifier, Key, PublicKey, +}; #[cfg(not(target_arch = "wasm32"))] use crate::communication::common::send_request; @@ -38,7 +40,7 @@ pub(crate) async fn delegator_reward_by_era_identifier( InformationRequest::Reward { era_identifier: Some(era_identifier), validator: Box::new(validator_key), - delegator: Some(Box::new(delegator_key)), + delegator: Some(Box::new(DelegatorKind::PublicKey(delegator_key))), } .to_bytes()? .as_slice(),