diff --git a/Cargo.lock b/Cargo.lock index 8ddd374c6..73ded7933 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -59,7 +59,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" dependencies = [ "cfg-if", - "getrandom 0.3.4", + "getrandom 0.3.3", "once_cell", "version_check", "zerocopy", @@ -67,9 +67,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.1.4" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] @@ -91,9 +91,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.21" +version = "0.6.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" +checksum = "3ae563653d1938f79b1ab1b5e668c87c76a9930414574a6583a7b7e11a8e6192" dependencies = [ "anstyle", "anstyle-parse", @@ -213,7 +213,7 @@ dependencies = [ "polling 3.11.0", "rustix", "slab", - "windows-sys 0.61.2", + "windows-sys 0.61.1", ] [[package]] @@ -224,7 +224,7 @@ checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.106", ] [[package]] @@ -259,13 +259,13 @@ checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "axum" -version = "0.8.7" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b098575ebe77cb6d14fc7f32749631a6e44edbef6b796f89b020e99ba20d425" +checksum = "8a18ed336352031311f4e0b4dd2ff392d4fbb370777c9d18d7fc9d7359f73871" dependencies = [ "axum-core", "base64 0.22.1", - "bytes 1.11.0", + "bytes 1.10.1", "form_urlencoded", "futures-util", "http 1.3.1", @@ -298,7 +298,7 @@ version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "59446ce19cd142f8833f856eb31f3eb097812d1479ab224f54d72428ca21ea22" dependencies = [ - "bytes 1.11.0", + "bytes 1.10.1", "futures-core", "http 1.3.1", "http-body", @@ -322,7 +322,7 @@ dependencies = [ "miniz_oxide", "object 0.37.3", "rustc-demangle", - "windows-link 0.2.1", + "windows-link 0.2.0", ] [[package]] @@ -358,7 +358,7 @@ version = "0.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f49d8fed880d473ea71efb9bf597651e77201bdd4893efe54c9e5d65ae04ce6f" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.9.4", "cexpr", "clang-sys", "itertools 0.13.0", @@ -369,7 +369,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.110", + "syn 2.0.106", ] [[package]] @@ -380,11 +380,11 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.10.0" +version = "2.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" +checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394" dependencies = [ - "serde_core", + "serde", ] [[package]] @@ -410,15 +410,6 @@ dependencies = [ "generic-array", ] -[[package]] -name = "block2" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdeb9d870516001442e364c5220d3574d2da8dc765554b4a617230d33fa58ef5" -dependencies = [ - "objc2", -] - [[package]] name = "bs58" version = "0.5.1" @@ -430,9 +421,9 @@ dependencies = [ [[package]] name = "bstr" -version = "1.12.1" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63044e1ae8e69f3b5a92c736ca6269b8d12fa7efe39bf34ddb06d102cf0e2cab" +checksum = "234113d19d0d7d613b40e86fb654acf958910802bcceab913a4f9e7cda03b1a4" dependencies = [ "memchr", "regex-automata", @@ -487,14 +478,14 @@ checksum = "89385e82b5d1821d2219e0b095efa2cc1f246cbf99080f3be46a1a85c0d392d9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.106", ] [[package]] name = "bytemuck" -version = "1.24.0" +version = "1.23.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fbdf580320f38b612e485521afda1ee26d10cc9884efaaa750d383e13e3c5f4" +checksum = "3995eaeebcdf32f91f980d360f78732ddc061097ab4e39991ae7a6ace9194677" [[package]] name = "byteorder" @@ -514,15 +505,15 @@ dependencies = [ [[package]] name = "bytes" -version = "1.11.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" +checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" [[package]] name = "bytesize" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c99fa31e08a43eaa5913ef68d7e01c37a2bdce6ed648168239ad33b7d30a9cd8" +checksum = "00f4369ba008f82b968b1acbe31715ec37bd45236fa0726605a36cc3060ea256" [[package]] name = "castaway" @@ -532,9 +523,9 @@ checksum = "a2698f953def977c68f935bb0dfa959375ad4638570e969e2f1e9f433cbf1af6" [[package]] name = "cc" -version = "1.2.44" +version = "1.2.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37521ac7aabe3d13122dc382493e20c9416f299d2ccd5b3a5340a2570cdeb0f3" +checksum = "e1354349954c6fc9cb0deab020f27f783cf0b604e8bb754dc4658ecf0d29c35f" dependencies = [ "find-msvc-tools", "shlex", @@ -551,9 +542,9 @@ dependencies = [ [[package]] name = "cfg-if" -version = "1.0.4" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" +checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" [[package]] name = "cfg_aliases" @@ -597,7 +588,7 @@ dependencies = [ "num-traits", "serde", "wasm-bindgen", - "windows-link 0.2.1", + "windows-link 0.2.0", ] [[package]] @@ -624,9 +615,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.52" +version = "4.5.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa8120877db0e5c011242f96806ce3c94e0737ab8108532a76a3300a01db2ab8" +checksum = "4c26d721170e0295f191a69bd9a1f93efcdb0aff38684b61ab5750468972e5f5" dependencies = [ "clap_builder", "clap_derive", @@ -634,9 +625,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.52" +version = "4.5.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02576b399397b659c26064fbc92a75fede9d18ffd5f80ca1cd74ddab167016e1" +checksum = "75835f0c7bf681bfd05abe44e965760fea999a5286c6eb2d59883634fd02011a" dependencies = [ "anstream", "anstyle", @@ -653,14 +644,14 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.106", ] [[package]] name = "clap_lex" -version = "0.7.6" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" +checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" [[package]] name = "cmake" @@ -759,7 +750,7 @@ dependencies = [ "cookie", "document-features", "idna", - "indexmap 2.12.0", + "indexmap 2.11.4", "log", "serde", "serde_derive", @@ -988,21 +979,21 @@ dependencies = [ [[package]] name = "csv" -version = "1.4.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52cd9d68cf7efc6ddfaaee42e7288d3a99d613d4b50f76ce9827ae0c6e14f938" +checksum = "acdc4883a9c96732e4733212c01447ebd805833b7275a73ca3ee080fd77afdaf" dependencies = [ "csv-core", "itoa", "ryu", - "serde_core", + "serde", ] [[package]] name = "csv-core" -version = "0.1.13" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "704a3c26996a80471189265814dbc2c257598b96b8a7feae2d31ace646bb9782" +checksum = "7d02f3b0da4c6504f86e9cd789d8dbafab48c2321be74e9987593de5a894d93d" dependencies = [ "memchr", ] @@ -1018,13 +1009,13 @@ dependencies = [ [[package]] name = "ctrlc" -version = "3.5.1" +version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73736a89c4aff73035ba2ed2e565061954da00d4970fc9ac25dcc85a2a20d790" +checksum = "881c5d0a13b2f1498e2306e82cbada78390e152d4b1378fb28a84f4dcd0dc4f3" dependencies = [ - "dispatch2", + "dispatch", "nix", - "windows-sys 0.61.2", + "windows-sys 0.61.1", ] [[package]] @@ -1038,7 +1029,7 @@ dependencies = [ "openssl-probe", "openssl-sys", "schannel", - "socket2 0.6.1", + "socket2 0.6.0", "windows-sys 0.59.0", ] @@ -1078,7 +1069,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.110", + "syn 2.0.106", ] [[package]] @@ -1089,7 +1080,7 @@ checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" dependencies = [ "darling_core", "quote", - "syn 2.0.110", + "syn 2.0.106", ] [[package]] @@ -1114,13 +1105,13 @@ checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" [[package]] name = "delegate" -version = "0.13.5" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "780eb241654bf097afb00fc5f054a09b687dad862e485fdcf8399bb056565370" +checksum = "6178a82cf56c836a3ba61a7935cdb1c49bfaa6fa4327cd5bf554a503087de26b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.106", ] [[package]] @@ -1136,9 +1127,9 @@ dependencies = [ [[package]] name = "deranged" -version = "0.5.5" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ececcb659e7ba858fb4f10388c250a7252eb0a27373f1a72b8748afdd248e587" +checksum = "a41953f86f8a05768a6cda24def994fd2f424b04ec5c719cf89989779f199071" dependencies = [ "powerfmt", "serde_core", @@ -1152,7 +1143,7 @@ checksum = "1e567bd82dcff979e4b03460c307b3cdc9e96fde3d73bed1496d2bc75d9dd62a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.106", ] [[package]] @@ -1163,7 +1154,7 @@ checksum = "6edb4b64a43d977b8e99788fe3a04d483834fba1215a7e02caa415b626497f7f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.106", ] [[package]] @@ -1183,7 +1174,7 @@ checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.106", "unicode-xid", ] @@ -1227,7 +1218,7 @@ dependencies = [ "libc", "option-ext", "redox_users 0.5.2", - "windows-sys 0.59.0", + "windows-sys 0.61.1", ] [[package]] @@ -1242,16 +1233,10 @@ dependencies = [ ] [[package]] -name = "dispatch2" -version = "0.3.0" +name = "dispatch" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89a09f22a6c6069a18470eb92d2298acf25463f14256d24778e1230d789a2aec" -dependencies = [ - "bitflags 2.10.0", - "block2", - "libc", - "objc2", -] +checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" [[package]] name = "displaydoc" @@ -1261,14 +1246,14 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.106", ] [[package]] name = "document-features" -version = "0.2.12" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4b8a88685455ed29a21542a33abd9cb6510b6b129abadabdcef0f4c55bc8f61" +checksum = "95249b50c6c185bee49034bcb378a49dc2b5dff0be90ff6616d31d64febab05d" dependencies = [ "litrs", ] @@ -1291,13 +1276,13 @@ version = "4.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a31e49f416ec431ceef002ee220eee9da97687ec3ecea8040703edbaa75e157" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.9.4", "byteorder", "lazy_static", "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.106", ] [[package]] @@ -1309,7 +1294,7 @@ dependencies = [ "byteorder", "dynasm", "fnv", - "memmap2 0.9.9", + "memmap2 0.9.8", ] [[package]] @@ -1345,7 +1330,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.106", ] [[package]] @@ -1386,14 +1371,14 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.106", ] [[package]] name = "env_filter" -version = "0.1.4" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bf3c259d255ca70051b30e2e95b5446cdb8949ac4cd22c0d7fd634d89f568e2" +checksum = "186e05a59d4c50738528153b83b0b0194d3a29507dfec16eccd4b342903397d0" dependencies = [ "log", ] @@ -1429,7 +1414,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.61.1", ] [[package]] @@ -1552,9 +1537,9 @@ dependencies = [ [[package]] name = "find-msvc-tools" -version = "0.1.4" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52051878f80a721bb68ebfbc930e07b65ba72f2da88968ea5c06fd6ca3d3a127" +checksum = "1ced73b1dacfc750a6db6c0a0c3a3853c8b41997e2e2c563dc90804ae6867959" [[package]] name = "flatbuffers" @@ -1572,15 +1557,15 @@ version = "25.9.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09b6620799e7340ebd9968d2e0708eb82cf1971e9a16821e2091b6d6e475eed5" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.9.4", "rustc_version", ] [[package]] name = "flate2" -version = "1.1.5" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfe33edd8e85a12a67454e37f8c75e730830d83e313556ab9ebf9ee7fbeb3bfb" +checksum = "4a3d7db9596fecd151c5f638c0ee5d5bd487b6e0ea232e5dc96d5250f6f94b1d" dependencies = [ "crc32fast", "miniz_oxide", @@ -1646,7 +1631,7 @@ dependencies = [ "blake3", "bs58", "byteorder", - "bytes 1.11.0", + "bytes 1.10.1", "chacha20poly1305", "chrono", "clap", @@ -1719,7 +1704,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.106", "trybuild", ] @@ -1731,7 +1716,7 @@ checksum = "3357fc23a41e5eca883901009e0c509e9c500d66d87da970767a2ca9fd6ddeef" dependencies = [ "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.106", ] [[package]] @@ -1742,6 +1727,7 @@ dependencies = [ "chrono", "clap", "freenet", + "freenet-macros 0.1.0", "freenet-ping-types", "freenet-stdlib", "futures 0.3.31", @@ -1812,16 +1798,18 @@ dependencies = [ [[package]] name = "freenet-test-network" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d06be6aef3bb0433a963d0cc0c0f9b7d05e50b54fcb929e405fefab10d3b2db9" +checksum = "69a0fa5cba6c26cf35b0ebf8832c74f5d3c985b70238e558e553369b2886baab" dependencies = [ "anyhow", "chrono", "freenet-stdlib", "futures 0.3.31", + "regex", "serde", "serde_json", + "ssh2", "sysinfo", "thiserror 1.0.69", "tokio", @@ -1937,7 +1925,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.106", ] [[package]] @@ -1972,9 +1960,9 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.9" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bb6743198531e02858aeaea5398fcc883e71851fcbcb5a2f773e2fb6cb1edf2" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", @@ -1989,20 +1977,20 @@ dependencies = [ "cfg-if", "js-sys", "libc", - "wasi", + "wasi 0.11.1+wasi-snapshot-preview1", "wasm-bindgen", ] [[package]] name = "getrandom" -version = "0.3.4" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" dependencies = [ "cfg-if", "libc", "r-efi", - "wasip2", + "wasi 0.14.7+wasi-0.2.4", ] [[package]] @@ -2022,7 +2010,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" dependencies = [ "fallible-iterator", - "indexmap 2.12.0", + "indexmap 2.11.4", "stable_deref_trait", ] @@ -2045,12 +2033,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3c0b69cfcb4e1b9f1bf2f53f95f766e4661169728ec61cd3fe5a0166f2d1386" dependencies = [ "atomic-waker", - "bytes 1.11.0", + "bytes 1.10.1", "fnv", "futures-core", "futures-sink", "http 1.3.1", - "indexmap 2.12.0", + "indexmap 2.11.4", "slab", "tokio", "tokio-util", @@ -2092,12 +2080,6 @@ dependencies = [ "foldhash", ] -[[package]] -name = "hashbrown" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" - [[package]] name = "hashlink" version = "0.10.0" @@ -2127,7 +2109,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b3314d5adb5d94bcdf56771f2e50dbbc80bb4bdf88967526706205ac9eff24eb" dependencies = [ "base64 0.22.1", - "bytes 1.11.0", + "bytes 1.10.1", "headers-core", "http 1.3.1", "httpdate", @@ -2180,7 +2162,7 @@ dependencies = [ "once_cell", "rand 0.8.5", "rustls 0.21.12", - "rustls-pemfile", + "rustls-pemfile 1.0.4", "thiserror 1.0.69", "tinyvec", "tokio", @@ -2232,11 +2214,11 @@ dependencies = [ [[package]] name = "home" -version = "0.5.12" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc627f471c528ff0c4a49e1d5e60450c8f6461dd6d10ba9dcd3a61d3dff7728d" +checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -2245,7 +2227,7 @@ version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" dependencies = [ - "bytes 1.11.0", + "bytes 1.10.1", "fnv", "itoa", ] @@ -2256,7 +2238,7 @@ version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" dependencies = [ - "bytes 1.11.0", + "bytes 1.10.1", "fnv", "itoa", ] @@ -2267,7 +2249,7 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ - "bytes 1.11.0", + "bytes 1.10.1", "http 1.3.1", ] @@ -2277,7 +2259,7 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" dependencies = [ - "bytes 1.11.0", + "bytes 1.10.1", "futures-core", "http 1.3.1", "http-body", @@ -2309,7 +2291,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bde82de3ef9bd882493c6a5edbc3363ad928925b30ccecc0f2ddeb42601b3021" dependencies = [ "bstr", - "bytes 1.11.0", + "bytes 1.10.1", "crossbeam-channel", "form_urlencoded", "futures 0.3.31", @@ -2349,7 +2331,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eb3aa54a13a0dfe7fbe3a59e0c76093041720fdc77b110cc0fc260fafb4dc51e" dependencies = [ "atomic-waker", - "bytes 1.11.0", + "bytes 1.10.1", "futures-channel", "futures-core", "h2", @@ -2374,7 +2356,7 @@ dependencies = [ "http 1.3.1", "hyper", "hyper-util", - "rustls 0.23.34", + "rustls 0.23.32", "rustls-pki-types", "tokio", "tokio-rustls 0.26.4", @@ -2400,7 +2382,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" dependencies = [ - "bytes 1.11.0", + "bytes 1.10.1", "http-body-util", "hyper", "hyper-util", @@ -2417,7 +2399,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c6995591a8f1380fcb4ba966a252a4b29188d51d2b89e3a252f5305be65aea8" dependencies = [ "base64 0.22.1", - "bytes 1.11.0", + "bytes 1.10.1", "futures-channel", "futures-core", "futures-util", @@ -2428,7 +2410,7 @@ dependencies = [ "libc", "percent-encoding", "pin-project-lite", - "socket2 0.5.10", + "socket2 0.6.0", "system-configuration", "tokio", "tower-service", @@ -2448,7 +2430,7 @@ dependencies = [ "js-sys", "log", "wasm-bindgen", - "windows-core 0.62.2", + "windows-core 0.62.1", ] [[package]] @@ -2462,9 +2444,9 @@ dependencies = [ [[package]] name = "icu_collections" -version = "2.1.1" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" +checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" dependencies = [ "displaydoc", "potential_utf", @@ -2475,9 +2457,9 @@ dependencies = [ [[package]] name = "icu_locale_core" -version = "2.1.1" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" +checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" dependencies = [ "displaydoc", "litemap", @@ -2488,10 +2470,11 @@ dependencies = [ [[package]] name = "icu_normalizer" -version = "2.1.1" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" +checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" dependencies = [ + "displaydoc", "icu_collections", "icu_normalizer_data", "icu_properties", @@ -2502,38 +2485,42 @@ dependencies = [ [[package]] name = "icu_normalizer_data" -version = "2.1.1" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" +checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" [[package]] name = "icu_properties" -version = "2.1.1" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e93fcd3157766c0c8da2f8cff6ce651a31f0810eaa1c51ec363ef790bbb5fb99" +checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b" dependencies = [ + "displaydoc", "icu_collections", "icu_locale_core", "icu_properties_data", "icu_provider", + "potential_utf", "zerotrie", "zerovec", ] [[package]] name = "icu_properties_data" -version = "2.1.1" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02845b3647bb045f1100ecd6480ff52f34c35f82d9880e029d329c21d1054899" +checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632" [[package]] name = "icu_provider" -version = "2.1.1" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" +checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" dependencies = [ "displaydoc", "icu_locale_core", + "stable_deref_trait", + "tinystr", "writeable", "yoke", "zerofrom", @@ -2581,12 +2568,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.12.0" +version = "2.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6717a8d2a5a929a1a2eb43a12812498ed141a0bcfb7e8f7844fbdbe4303bba9f" +checksum = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5" dependencies = [ "equivalent", - "hashbrown 0.16.0", + "hashbrown 0.15.5", "serde", "serde_core", ] @@ -2597,7 +2584,7 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f37dccff2791ab604f9babef0ba14fbe0be30bd368dc541e2b08d07c8aa908f3" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.9.4", "inotify-sys", "libc", ] @@ -2674,20 +2661,20 @@ dependencies = [ [[package]] name = "is-terminal" -version = "0.4.17" +version = "0.4.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46" +checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9" dependencies = [ "hermit-abi", "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "is_terminal_polyfill" -version = "1.70.2" +version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" [[package]] name = "isahc" @@ -2749,9 +2736,9 @@ checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "js-sys" -version = "0.3.82" +version = "0.3.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b011eec8cc36da2aab2d5cff675ec18454fad408585853910a202391cf9f8e65" +checksum = "ec48937a97411dcb524a265206ccd4c90bb711fca92b2792c407f268825b9305" dependencies = [ "once_cell", "wasm-bindgen", @@ -2800,9 +2787,9 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" [[package]] name = "libc" -version = "0.2.177" +version = "0.2.176" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" +checksum = "58f929b4d672ea937a23a1ab494143d968337a5f47e56d0815df1e0890ddf174" [[package]] name = "libloading" @@ -2811,7 +2798,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" dependencies = [ "cfg-if", - "windows-link 0.2.1", + "windows-link 0.2.0", ] [[package]] @@ -2826,7 +2813,7 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "416f7e718bdb06000964960ffa43b4335ad4012ae8b99060261aa4a8088d5ccb" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.9.4", "libc", "redox_syscall", ] @@ -2842,6 +2829,20 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "libssh2-sys" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "220e4f05ad4a218192533b300327f5150e809b54c4ec83b5a1d91833601811b9" +dependencies = [ + "cc", + "libc", + "libz-sys", + "openssl-sys", + "pkg-config", + "vcpkg", +] + [[package]] name = "libunwind" version = "1.3.3" @@ -2874,15 +2875,15 @@ checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" [[package]] name = "litemap" -version = "0.8.1" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" +checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" [[package]] name = "litrs" -version = "1.0.0" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092" +checksum = "f5e54036fe321fd421e10d732f155734c4e4afd610dd556d9a82833ab3ee0bed" [[package]] name = "lock_api" @@ -2991,9 +2992,9 @@ dependencies = [ [[package]] name = "memmap2" -version = "0.9.9" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "744133e4a0e0a658e1374cf3bf8e415c4052a15a111acd372764c55b4177d490" +checksum = "843a98750cd611cc2965a8213b53b43e715f13c37a9e096c6408e69990961db7" dependencies = [ "libc", ] @@ -3036,19 +3037,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" dependencies = [ "adler2", - "simd-adler32", ] [[package]] name = "mio" -version = "1.1.0" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69d83b0086dc8ecf3ce9ae2874b2d1290252e2a30720bea58a5c6639b0092873" +checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" dependencies = [ "libc", "log", - "wasi", - "windows-sys 0.61.2", + "wasi 0.11.1+wasi-snapshot-preview1", + "windows-sys 0.59.0", ] [[package]] @@ -3074,7 +3074,7 @@ checksum = "4568f25ccbd45ab5d5603dc34318c1ec56b117531781260002151b8530a9f931" dependencies = [ "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.106", ] [[package]] @@ -3117,7 +3117,7 @@ version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.9.4", "cfg-if", "cfg_aliases", "libc", @@ -3151,7 +3151,7 @@ version = "8.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4d3d07927151ff8575b7087f245456e549fea62edf0ec4e565a5ee50c8402bc3" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.9.4", "fsevent-sys", "inotify", "kqueue", @@ -3180,11 +3180,11 @@ dependencies = [ [[package]] name = "nu-ansi-term" -version = "0.50.3" +version = "0.50.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" +checksum = "d4a28e057d01f97e61255210fcff094d74ed0466038633e95017f5beb68e4399" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -3281,30 +3281,15 @@ dependencies = [ "libc", ] -[[package]] -name = "objc2" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7c2599ce0ec54857b29ce62166b0ed9b4f6f1a70ccc9a71165b6154caca8c05" -dependencies = [ - "objc2-encode", -] - [[package]] name = "objc2-core-foundation" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.9.4", ] -[[package]] -name = "objc2-encode" -version = "4.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33" - [[package]] name = "objc2-io-kit" version = "0.3.2" @@ -3324,7 +3309,7 @@ dependencies = [ "crc32fast", "flate2", "hashbrown 0.14.5", - "indexmap 2.12.0", + "indexmap 2.11.4", "memchr", "ruzstd", ] @@ -3346,9 +3331,9 @@ checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] name = "once_cell_polyfill" -version = "1.70.2" +version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" +checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" [[package]] name = "opaque-debug" @@ -3358,11 +3343,11 @@ checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] name = "openssl" -version = "0.10.74" +version = "0.10.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24ad14dd45412269e1a30f52ad8f0664f0f4f4a89ee8fe28c3b3527021ebb654" +checksum = "8505734d46c8ab1e19a1dce3aef597ad87dcb4c37e7188231769bd6bd51cebf8" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.9.4", "cfg-if", "foreign-types", "libc", @@ -3379,7 +3364,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.106", ] [[package]] @@ -3390,9 +3375,9 @@ checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" [[package]] name = "openssl-sys" -version = "0.9.110" +version = "0.9.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a9f0075ba3c21b09f8e8b2026584b1d18d49388648f2fbbf3c97ea8deced8e2" +checksum = "90096e2e47630d78b7d1c20952dc621f957103f8bc2c8359ec81290d75238571" dependencies = [ "cc", "libc", @@ -3435,7 +3420,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b0ba633e55c5ea6f431875ba55e71664f2fa5d3a90bd34ec9302eecc41c865dd" dependencies = [ "async-trait", - "bytes 1.11.0", + "bytes 1.10.1", "http 0.2.12", "opentelemetry 0.23.0", ] @@ -3447,7 +3432,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7a6d09a73194e6b66df7c8f1b680f156d916a1a942abf2de06823dd02b7855d" dependencies = [ "async-trait", - "bytes 1.11.0", + "bytes 1.10.1", "http 1.3.1", "opentelemetry 0.31.0", "reqwest", @@ -3605,7 +3590,7 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "windows-link 0.2.1", + "windows-link 0.2.0", ] [[package]] @@ -3658,7 +3643,7 @@ checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" dependencies = [ "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.106", ] [[package]] @@ -3727,7 +3712,7 @@ dependencies = [ "hermit-abi", "pin-project-lite", "rustix", - "windows-sys 0.61.2", + "windows-sys 0.61.1", ] [[package]] @@ -3770,9 +3755,9 @@ dependencies = [ [[package]] name = "potential_utf" -version = "0.1.4" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" +checksum = "84df19adbe5b5a0782edcab45899906947ab039ccf4573713735ee7de1e6b08a" dependencies = [ "zerovec", ] @@ -3799,7 +3784,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", - "syn 2.0.110", + "syn 2.0.106", ] [[package]] @@ -3835,14 +3820,14 @@ dependencies = [ "proc-macro-error-attr2", "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.106", ] [[package]] name = "proc-macro2" -version = "1.0.103" +version = "1.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" +checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" dependencies = [ "unicode-ident", ] @@ -3853,7 +3838,7 @@ version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7231bd9b3d3d33c86b58adbac74b5ec0ad9f496b19d22801d773636feaa95f3d" dependencies = [ - "bytes 1.11.0", + "bytes 1.10.1", "prost-derive", ] @@ -3867,7 +3852,7 @@ dependencies = [ "itertools 0.14.0", "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.106", ] [[package]] @@ -3916,14 +3901,14 @@ checksum = "7347867d0a7e1208d93b46767be83e2b8f978c3dad35f775ac8d8847551d6fe1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.106", ] [[package]] name = "quote" -version = "1.0.42" +version = "1.0.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f" +checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" dependencies = [ "proc-macro2", ] @@ -3999,7 +3984,7 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" dependencies = [ - "getrandom 0.3.4", + "getrandom 0.3.3", ] [[package]] @@ -4049,11 +4034,11 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.18" +version = "0.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.9.4", ] [[package]] @@ -4095,7 +4080,7 @@ checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.106", ] [[package]] @@ -4113,9 +4098,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.12.2" +version = "1.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" +checksum = "8b5288124840bee7b386bc413c487869b360b2b4ec421ea56425128692f2a82c" dependencies = [ "aho-corasick", "memchr", @@ -4125,9 +4110,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.13" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" +checksum = "833eb9ce86d40ef33cb1306d8accf7bc8ec2bfea4355cbdebb3df68b40925cad" dependencies = [ "aho-corasick", "memchr", @@ -4136,9 +4121,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.8" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" +checksum = "caf4aa5b0f434c91fe5c7f1ecb6a5ece2130b02ad2a590589dda5146df959001" [[package]] name = "region" @@ -4168,7 +4153,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d0946410b9f7b082a427e4ef5c8ff541a88b357bc6c637c40db3a68ac70a36f" dependencies = [ "base64 0.22.1", - "bytes 1.11.0", + "bytes 1.10.1", "encoding_rs", "futures-channel", "futures-core", @@ -4230,9 +4215,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "35a640b26f007713818e9a9b65d34da1cf58538207b052916a83d80e43f3ffa4" dependencies = [ "bytecheck 0.8.2", - "bytes 1.11.0", + "bytes 1.10.1", "hashbrown 0.15.5", - "indexmap 2.12.0", + "indexmap 2.11.4", "munge", "ptr_meta 0.3.1", "rancor", @@ -4250,14 +4235,14 @@ checksum = "bd83f5f173ff41e00337d97f6572e416d022ef8a19f371817259ae960324c482" dependencies = [ "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.106", ] [[package]] name = "rsa" -version = "0.9.9" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40a0376c50d0358279d9d643e4bf7b7be212f1f4ff1da9070a7b54d22ef75c88" +checksum = "78928ac1ed176a5ca1d17e578a1825f3d81ca54cf41053a592584b020cfd691b" dependencies = [ "const-oid", "digest", @@ -4301,11 +4286,11 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.9.4", "errno", "libc", "linux-raw-sys", - "windows-sys 0.52.0", + "windows-sys 0.61.1", ] [[package]] @@ -4322,15 +4307,15 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.34" +version = "0.23.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a9586e9ee2b4f8fab52a0048ca7334d7024eef48e2cb9407e3497bb7cab7fa7" +checksum = "cd3c25631629d034ce7cd9940adc9d45762d46de2b0f57193c4443b92c6d4d40" dependencies = [ "log", "once_cell", "ring", "rustls-pki-types", - "rustls-webpki 0.103.8", + "rustls-webpki 0.103.7", "subtle", "zeroize", ] @@ -4344,11 +4329,20 @@ dependencies = [ "base64 0.21.7", ] +[[package]] +name = "rustls-pemfile" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "rustls-pki-types" -version = "1.13.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94182ad936a0c91c324cd46c6511b9510ed16af436d7b5bab34beab0afd55f7a" +checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79" dependencies = [ "zeroize", ] @@ -4365,9 +4359,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.103.8" +version = "0.103.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ffdfa2f5286e2247234e03f680868ac2815974dc39e00ea15adc445d0aafe52" +checksum = "e10b3f4191e8a80e6b43eebabfac91e5dcecebb27a71f04e820c47ec41d314bf" dependencies = [ "ring", "rustls-pki-types", @@ -4421,7 +4415,7 @@ version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.61.1", ] [[package]] @@ -4476,7 +4470,7 @@ version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.9.4", "core-foundation", "core-foundation-sys", "libc", @@ -4495,9 +4489,9 @@ dependencies = [ [[package]] name = "self_cell" -version = "1.2.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16c2f82143577edb4921b71ede051dac62ca3c16084e918bf7b40c96ae10eb33" +checksum = "0f7d95a54511e0c7be3f51e8867aa8cf35148d7b9445d44de2f943e2b206e749" [[package]] name = "semver" @@ -4557,7 +4551,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.106", ] [[package]] @@ -4607,15 +4601,15 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.16.0" +version = "3.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10574371d41b0d9b2cff89418eda27da52bcaff2cc8741db26382a77c29131f1" +checksum = "aa66c845eee442168b2c8134fec70ac50dc20e760769c8ba0ad1319ca1959b04" dependencies = [ "base64 0.22.1", "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.12.0", + "indexmap 2.11.4", "schemars 0.9.0", "schemars 1.0.4", "serde_core", @@ -4626,14 +4620,14 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.16.0" +version = "3.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08a72d8216842fdd57820dc78d840bef99248e35fb2554ff923319e60f2d686b" +checksum = "b91a903660542fced4e99881aa481bdbaec1634568ee02e0b8bd57c64cb38955" dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.106", ] [[package]] @@ -4673,7 +4667,7 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6c99835bad52957e7aa241d3975ed17c1e5f8c92026377d117a606f36b84b16" dependencies = [ - "bytes 1.11.0", + "bytes 1.10.1", "memmap2 0.6.2", ] @@ -4715,12 +4709,6 @@ dependencies = [ "wide", ] -[[package]] -name = "simd-adler32" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" - [[package]] name = "simdutf8" version = "0.1.5" @@ -4771,12 +4759,12 @@ dependencies = [ [[package]] name = "socket2" -version = "0.6.1" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" +checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807" dependencies = [ "libc", - "windows-sys 0.60.2", + "windows-sys 0.59.0", ] [[package]] @@ -4818,7 +4806,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee6798b1838b6a0f69c007c133b8df5866302197e404e8b6ee8ed3e3a5e68dc6" dependencies = [ "base64 0.22.1", - "bytes 1.11.0", + "bytes 1.10.1", "crc", "crossbeam-queue", "either", @@ -4829,12 +4817,12 @@ dependencies = [ "futures-util", "hashbrown 0.15.5", "hashlink", - "indexmap 2.12.0", + "indexmap 2.11.4", "log", "memchr", "once_cell", "percent-encoding", - "rustls 0.23.34", + "rustls 0.23.32", "serde", "serde_json", "sha2", @@ -4857,7 +4845,7 @@ dependencies = [ "quote", "sqlx-core", "sqlx-macros-core", - "syn 2.0.110", + "syn 2.0.106", ] [[package]] @@ -4880,7 +4868,7 @@ dependencies = [ "sqlx-mysql", "sqlx-postgres", "sqlx-sqlite", - "syn 2.0.110", + "syn 2.0.106", "tokio", "url", ] @@ -4893,9 +4881,9 @@ checksum = "aa003f0038df784eb8fecbbac13affe3da23b45194bd57dba231c8f48199c526" dependencies = [ "atoi", "base64 0.22.1", - "bitflags 2.10.0", + "bitflags 2.9.4", "byteorder", - "bytes 1.11.0", + "bytes 1.10.1", "crc", "digest", "dotenvy", @@ -4935,7 +4923,7 @@ checksum = "db58fcd5a53cf07c184b154801ff91347e4c30d17a3562a635ff028ad5deda46" dependencies = [ "atoi", "base64 0.22.1", - "bitflags 2.10.0", + "bitflags 2.9.4", "byteorder", "crc", "dotenvy", @@ -4988,11 +4976,23 @@ dependencies = [ "url", ] +[[package]] +name = "ssh2" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f84d13b3b8a0d4e91a2629911e951db1bb8671512f5c09d7d4ba34500ba68c8" +dependencies = [ + "bitflags 2.9.4", + "libc", + "libssh2-sys", + "parking_lot", +] + [[package]] name = "stable_deref_trait" -version = "1.2.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "static_assertions" @@ -5069,9 +5069,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.110" +version = "2.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a99801b5bd34ede4cf3fc688c5919368fea4e4814a4664359503e6015b280aea" +checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" dependencies = [ "proc-macro2", "quote", @@ -5095,7 +5095,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.106", ] [[package]] @@ -5118,7 +5118,7 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.9.4", "core-foundation", "system-configuration-sys", ] @@ -5163,10 +5163,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" dependencies = [ "fastrand 2.3.0", - "getrandom 0.3.4", + "getrandom 0.3.3", "once_cell", "rustix", - "windows-sys 0.52.0", + "windows-sys 0.61.1", ] [[package]] @@ -5226,7 +5226,7 @@ checksum = "451b374529930d7601b1eef8d32bc79ae870b6079b069401709c2a8bf9e75f36" dependencies = [ "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.106", ] [[package]] @@ -5261,7 +5261,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.106", ] [[package]] @@ -5272,7 +5272,7 @@ checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" dependencies = [ "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.106", ] [[package]] @@ -5339,9 +5339,9 @@ dependencies = [ [[package]] name = "tinystr" -version = "0.8.2" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" +checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" dependencies = [ "displaydoc", "zerovec", @@ -5368,16 +5368,16 @@ version = "1.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408" dependencies = [ - "bytes 1.11.0", + "bytes 1.10.1", "libc", "mio", "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2 0.6.1", + "socket2 0.6.0", "tokio-macros", "tracing", - "windows-sys 0.61.2", + "windows-sys 0.61.1", ] [[package]] @@ -5399,7 +5399,7 @@ checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.106", ] [[package]] @@ -5428,7 +5428,7 @@ version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" dependencies = [ - "rustls 0.23.34", + "rustls 0.23.32", "tokio", ] @@ -5475,7 +5475,7 @@ version = "0.7.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14307c986784f72ef81c89db7d9e28d6ac26d16213b109ea501696195e6e3ce5" dependencies = [ - "bytes 1.11.0", + "bytes 1.10.1", "futures-core", "futures-sink", "pin-project-lite", @@ -5488,7 +5488,7 @@ version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0dc8b1fb61449e27716ec0e1bdf0f6b8f3e8f6b05391e8497b8b6d7804ea6d8" dependencies = [ - "indexmap 2.12.0", + "indexmap 2.11.4", "serde_core", "serde_spanned", "toml_datetime", @@ -5530,7 +5530,7 @@ dependencies = [ "async-trait", "axum", "base64 0.22.1", - "bytes 1.11.0", + "bytes 1.10.1", "h2", "http 1.3.1", "http-body", @@ -5540,7 +5540,7 @@ dependencies = [ "hyper-util", "percent-encoding", "pin-project", - "socket2 0.6.1", + "socket2 0.6.0", "sync_wrapper", "tokio", "tokio-stream", @@ -5556,7 +5556,7 @@ version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "66bd50ad6ce1252d87ef024b3d64fe4c3cf54a86fb9ef4c631fdd0ded7aeaa67" dependencies = [ - "bytes 1.11.0", + "bytes 1.10.1", "prost", "tonic", ] @@ -5569,7 +5569,7 @@ checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" dependencies = [ "futures-core", "futures-util", - "indexmap 2.12.0", + "indexmap 2.11.4", "pin-project-lite", "slab", "sync_wrapper", @@ -5586,8 +5586,8 @@ version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" dependencies = [ - "bitflags 2.10.0", - "bytes 1.11.0", + "bitflags 2.9.4", + "bytes 1.10.1", "futures-core", "futures-util", "http 1.3.1", @@ -5640,7 +5640,7 @@ checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" dependencies = [ "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.106", ] [[package]] @@ -5726,9 +5726,9 @@ dependencies = [ [[package]] name = "triomphe" -version = "0.1.15" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd69c5aa8f924c7519d6372789a74eac5b94fb0f8fcf0d4a97eb0bfc3e785f39" +checksum = "ef8f7726da4807b58ea5c96fdc122f80702030edc33b35aff9190a51148ccc85" dependencies = [ "serde", "stable_deref_trait", @@ -5742,9 +5742,9 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "trybuild" -version = "1.0.114" +version = "1.0.113" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e17e807bff86d2a06b52bca4276746584a78375055b6e45843925ce2802b335" +checksum = "559b6a626c0815c942ac98d434746138b4f89ddd6a1b8cbb168c6845fb3376c5" dependencies = [ "glob", "serde", @@ -5761,7 +5761,7 @@ version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eadc29d668c91fcc564941132e17b28a7ceb2f3ebf0b9dae3e03fd7a6748eb0d" dependencies = [ - "bytes 1.11.0", + "bytes 1.10.1", "data-encoding", "http 1.3.1", "httparse", @@ -5779,7 +5779,7 @@ version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8628dcc84e5a09eb3d8423d6cb682965dea9133204e8fb3efee74c2a0c259442" dependencies = [ - "bytes 1.11.0", + "bytes 1.10.1", "data-encoding", "http 1.3.1", "httparse", @@ -5831,24 +5831,24 @@ checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5" [[package]] name = "unicode-ident" -version = "1.0.22" +version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" +checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d" [[package]] name = "unicode-normalization" -version = "0.1.25" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fd4f6878c9cb28d874b009da9e8d183b5abc80117c40bbd187a1fde336be6e8" +checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" dependencies = [ "tinyvec", ] [[package]] name = "unicode-properties" -version = "0.1.4" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7df058c713841ad818f1dc5d3fd88063241cc61f49f5fbea4b951e8cf5a8d71d" +checksum = "e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0" [[package]] name = "unicode-width" @@ -5858,9 +5858,9 @@ checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" [[package]] name = "unicode-width" -version = "0.2.2" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" +checksum = "4a1a07cc7db3810833284e8d372ccdc6da29741639ecc70c9ec107df0fa6154c" [[package]] name = "unicode-xid" @@ -5886,22 +5886,23 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "ureq" -version = "3.1.4" +version = "3.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d39cb1dbab692d82a977c0392ffac19e188bd9186a9f32806f0aaa859d75585a" +checksum = "99ba1025f18a4a3fc3e9b48c868e9beb4f24f4b4b1a325bada26bd4119f46537" dependencies = [ "base64 0.22.1", "cookie_store", "flate2", "log", "percent-encoding", - "rustls 0.23.34", + "rustls 0.23.32", + "rustls-pemfile 2.2.0", "rustls-pki-types", "serde", "serde_json", "ureq-proto", "utf-8", - "webpki-roots 1.0.3", + "webpki-roots 1.0.2", ] [[package]] @@ -6005,6 +6006,15 @@ version = "0.11.1+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" +[[package]] +name = "wasi" +version = "0.14.7+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "883478de20367e224c0090af9cf5f9fa85bed63a95c1abf3afc5c083ebc06e8c" +dependencies = [ + "wasip2", +] + [[package]] name = "wasip2" version = "1.0.1+wasi-0.2.4" @@ -6022,9 +6032,9 @@ checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" [[package]] name = "wasm-bindgen" -version = "0.2.105" +version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da95793dfc411fbbd93f5be7715b0578ec61fe87cb1a42b12eb625caa5c5ea60" +checksum = "c1da10c01ae9f1ae40cbfac0bac3b1e724b320abfcf52229f80b547c0d250e2d" dependencies = [ "cfg-if", "once_cell", @@ -6035,11 +6045,25 @@ dependencies = [ "wasm-bindgen-shared", ] +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "671c9a5a66f49d8a47345ab942e2cb93c7d1d0339065d4f8139c486121b43b19" +dependencies = [ + "bumpalo", + "log", + "proc-macro2", + "quote", + "syn 2.0.106", + "wasm-bindgen-shared", +] + [[package]] name = "wasm-bindgen-futures" -version = "0.4.55" +version = "0.4.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "551f88106c6d5e7ccc7cd9a16f312dd3b5d36ea8b4954304657d5dfba115d4a0" +checksum = "7e038d41e478cc73bae0ff9b36c60cff1c98b8f38f8d7e8061e79ee63608ac5c" dependencies = [ "cfg-if", "js-sys", @@ -6050,9 +6074,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.105" +version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04264334509e04a7bf8690f2384ef5265f05143a4bff3889ab7a3269adab59c2" +checksum = "7ca60477e4c59f5f2986c50191cd972e3a50d8a95603bc9434501cf156a9a119" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -6060,34 +6084,34 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.105" +version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "420bc339d9f322e562942d52e115d57e950d12d88983a14c79b86859ee6c7ebc" +checksum = "9f07d2f20d4da7b26400c9f4a0511e6e0345b040694e8a75bd41d578fa4421d7" dependencies = [ - "bumpalo", "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.106", + "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.105" +version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76f218a38c84bcb33c25ec7059b07847d465ce0e0a76b995e134a45adcb6af76" +checksum = "bad67dc8b2a1a6e5448428adec4c3e84c43e561d8c9ee8a9e5aabeb193ec41d1" dependencies = [ "unicode-ident", ] [[package]] name = "wasm-encoder" -version = "0.240.0" +version = "0.239.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06d642d8c5ecc083aafe9ceb32809276a304547a3a6eeecceb5d8152598bc71f" +checksum = "5be00faa2b4950c76fe618c409d2c3ea5a3c9422013e079482d78544bb2d184c" dependencies = [ "leb128fmt", - "wasmparser 0.240.0", + "wasmparser 0.239.0", ] [[package]] @@ -6097,11 +6121,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d85671948f8886a1cc946141c0b688a5617603c103699a5fceeebeb4e75b0b6" dependencies = [ "bindgen", - "bytes 1.11.0", + "bytes 1.10.1", "cfg-if", "cmake", "derive_more 2.0.1", - "indexmap 2.12.0", + "indexmap 2.11.4", "js-sys", "more-asserts", "paste", @@ -6131,7 +6155,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4946475adc0af265af8f10aadf4d4a3c64845bcd3801c655bdd81ce5e3ee869b" dependencies = [ "backtrace", - "bytes 1.11.0", + "bytes 1.10.1", "cfg-if", "enum-iterator", "enumset", @@ -6227,7 +6251,7 @@ dependencies = [ "enumset", "getrandom 0.2.16", "hex", - "indexmap 2.12.0", + "indexmap 2.11.4", "more-asserts", "rkyv", "sha2", @@ -6250,7 +6274,7 @@ dependencies = [ "dashmap", "enum-iterator", "fnv", - "indexmap 2.12.0", + "indexmap 2.11.4", "libc", "libunwind", "mach2", @@ -6270,47 +6294,47 @@ version = "0.224.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04f17a5917c2ddd3819e84c661fae0d6ba29d7b9c1f0e96c708c65a9c4188e11" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.9.4", ] [[package]] name = "wasmparser" -version = "0.240.0" +version = "0.239.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b722dcf61e0ea47440b53ff83ccb5df8efec57a69d150e4f24882e4eba7e24a4" +checksum = "8c9d90bb93e764f6beabf1d02028c70a2156a6583e63ac4218dd07ef733368b0" dependencies = [ - "bitflags 2.10.0", - "indexmap 2.12.0", + "bitflags 2.9.4", + "indexmap 2.11.4", "semver", ] [[package]] name = "wast" -version = "240.0.0" +version = "239.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0efe1c93db4ac562b9733e3dca19ed7fc878dba29aef22245acf84f13da4a19" +checksum = "9139176fe8a2590e0fb174cdcaf373b224cb93c3dde08e4297c1361d2ba1ea5d" dependencies = [ "bumpalo", "leb128fmt", "memchr", - "unicode-width 0.2.2", + "unicode-width 0.2.1", "wasm-encoder", ] [[package]] name = "wat" -version = "1.240.0" +version = "1.239.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec9b6eab7ecd4d639d78515e9ea491c9bacf494aa5eda10823bd35992cf8c1e" +checksum = "3e1c941927d34709f255558166f8901a2005f8ab4a9650432e9281b7cc6f3b75" dependencies = [ "wast", ] [[package]] name = "web-sys" -version = "0.3.82" +version = "0.3.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a1f95c0d03a47f4ae1f7a64643a6bb97465d9b740f0fa8f90ea33915c99a9a1" +checksum = "9367c417a924a74cae129e6a2ae3b47fabb1f8995595ab474029da749a8be120" dependencies = [ "js-sys", "wasm-bindgen", @@ -6332,14 +6356,14 @@ version = "0.26.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9" dependencies = [ - "webpki-roots 1.0.3", + "webpki-roots 1.0.2", ] [[package]] name = "webpki-roots" -version = "1.0.3" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32b130c0d2d49f8b6889abc456e795e82525204f27c42cf767cf0d7734e089b8" +checksum = "7e8983c3ab33d6fb807cfcdad2491c4ea8cbc8ed839181c7dfd9c67c83e261b2" dependencies = [ "rustls-pki-types", ] @@ -6390,9 +6414,9 @@ dependencies = [ [[package]] name = "widestring" -version = "1.2.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72069c3113ab32ab29e5584db3c6ec55d416895e60715417b5b883a357c3e471" +checksum = "dd7cf3379ca1aac9eea11fba24fd7e315d621f8dfe35c8d7d2be8b793726e07d" [[package]] name = "winapi" @@ -6416,7 +6440,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.61.1", ] [[package]] @@ -6440,14 +6464,14 @@ dependencies = [ [[package]] name = "windows" -version = "0.62.2" +version = "0.62.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "527fadee13e0c05939a6a05d5bd6eec6cd2e3dbd648b9f8e447c6518133d8580" +checksum = "49e6c4a1f363c8210c6f77ba24f645c61c6fb941eccf013da691f7e09515b8ac" dependencies = [ - "windows-collections 0.3.2", - "windows-core 0.62.2", - "windows-future 0.3.2", - "windows-numerics 0.3.1", + "windows-collections 0.3.1", + "windows-core 0.62.1", + "windows-future 0.3.1", + "windows-numerics 0.3.0", ] [[package]] @@ -6461,11 +6485,11 @@ dependencies = [ [[package]] name = "windows-collections" -version = "0.3.2" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23b2d95af1a8a14a3c7367e1ed4fc9c20e0a26e79551b1454d72583c97cc6610" +checksum = "123e712f464a8a60ce1a13f4c446d2d43ab06464cb5842ff68f5c71b6fb7852e" dependencies = [ - "windows-core 0.62.2", + "windows-core 0.62.1", ] [[package]] @@ -6483,15 +6507,15 @@ dependencies = [ [[package]] name = "windows-core" -version = "0.62.2" +version = "0.62.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" +checksum = "6844ee5416b285084d3d3fffd743b925a6c9385455f64f6d4fa3031c4c2749a9" dependencies = [ "windows-implement", "windows-interface", - "windows-link 0.2.1", - "windows-result 0.4.1", - "windows-strings 0.5.1", + "windows-link 0.2.0", + "windows-result 0.4.0", + "windows-strings 0.5.0", ] [[package]] @@ -6507,35 +6531,35 @@ dependencies = [ [[package]] name = "windows-future" -version = "0.3.2" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1d6f90251fe18a279739e78025bd6ddc52a7e22f921070ccdc67dde84c605cb" +checksum = "68f3db6b24b120200d649cd4811b4947188ed3a8d2626f7075146c5d178a9a4a" dependencies = [ - "windows-core 0.62.2", - "windows-link 0.2.1", - "windows-threading 0.2.1", + "windows-core 0.62.1", + "windows-link 0.2.0", + "windows-threading 0.2.0", ] [[package]] name = "windows-implement" -version = "0.60.2" +version = "0.60.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" +checksum = "edb307e42a74fb6de9bf3a02d9712678b22399c87e6fa869d6dfcd8c1b7754e0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.106", ] [[package]] name = "windows-interface" -version = "0.59.3" +version = "0.59.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" +checksum = "c0abd1ddbc6964ac14db11c7213d6532ef34bd9aa042c2e5935f59d7908b46a5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.106", ] [[package]] @@ -6546,9 +6570,9 @@ checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" [[package]] name = "windows-link" -version = "0.2.1" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" +checksum = "45e46c0661abb7180e7b9c281db115305d49ca1709ab8242adf09666d2173c65" [[package]] name = "windows-numerics" @@ -6562,12 +6586,12 @@ dependencies = [ [[package]] name = "windows-numerics" -version = "0.3.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e2e40844ac143cdb44aead537bbf727de9b044e107a0f1220392177d15b0f26" +checksum = "2ce3498fe0aba81e62e477408383196b4b0363db5e0c27646f932676283b43d8" dependencies = [ - "windows-core 0.62.2", - "windows-link 0.2.1", + "windows-core 0.62.1", + "windows-link 0.2.0", ] [[package]] @@ -6592,11 +6616,11 @@ dependencies = [ [[package]] name = "windows-result" -version = "0.4.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" +checksum = "7084dcc306f89883455a206237404d3eaf961e5bd7e0f312f7c91f57eb44167f" dependencies = [ - "windows-link 0.2.1", + "windows-link 0.2.0", ] [[package]] @@ -6610,11 +6634,11 @@ dependencies = [ [[package]] name = "windows-strings" -version = "0.5.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" +checksum = "7218c655a553b0bed4426cf54b20d7ba363ef543b52d515b3e48d7fd55318dda" dependencies = [ - "windows-link 0.2.1", + "windows-link 0.2.0", ] [[package]] @@ -6650,16 +6674,16 @@ version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" dependencies = [ - "windows-targets 0.53.5", + "windows-targets 0.53.4", ] [[package]] name = "windows-sys" -version = "0.61.2" +version = "0.61.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +checksum = "6f109e41dd4a3c848907eb83d5a42ea98b3769495597450cf6d153507b166f0f" dependencies = [ - "windows-link 0.2.1", + "windows-link 0.2.0", ] [[package]] @@ -6695,19 +6719,19 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.53.5" +version = "0.53.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" +checksum = "2d42b7b7f66d2a06854650af09cfdf8713e427a439c97ad65a6375318033ac4b" dependencies = [ - "windows-link 0.2.1", - "windows_aarch64_gnullvm 0.53.1", - "windows_aarch64_msvc 0.53.1", - "windows_i686_gnu 0.53.1", - "windows_i686_gnullvm 0.53.1", - "windows_i686_msvc 0.53.1", - "windows_x86_64_gnu 0.53.1", - "windows_x86_64_gnullvm 0.53.1", - "windows_x86_64_msvc 0.53.1", + "windows-link 0.2.0", + "windows_aarch64_gnullvm 0.53.0", + "windows_aarch64_msvc 0.53.0", + "windows_i686_gnu 0.53.0", + "windows_i686_gnullvm 0.53.0", + "windows_i686_msvc 0.53.0", + "windows_x86_64_gnu 0.53.0", + "windows_x86_64_gnullvm 0.53.0", + "windows_x86_64_msvc 0.53.0", ] [[package]] @@ -6721,11 +6745,11 @@ dependencies = [ [[package]] name = "windows-threading" -version = "0.2.1" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3949bd5b99cafdf1c7ca86b43ca564028dfe27d66958f2470940f73d86d75b37" +checksum = "ab47f085ad6932defa48855254c758cdd0e2f2d48e62a34118a268d8f345e118" dependencies = [ - "windows-link 0.2.1", + "windows-link 0.2.0", ] [[package]] @@ -6742,9 +6766,9 @@ checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_gnullvm" -version = "0.53.1" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" +checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" [[package]] name = "windows_aarch64_msvc" @@ -6760,9 +6784,9 @@ checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_aarch64_msvc" -version = "0.53.1" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" +checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" [[package]] name = "windows_i686_gnu" @@ -6778,9 +6802,9 @@ checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnu" -version = "0.53.1" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" +checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" [[package]] name = "windows_i686_gnullvm" @@ -6790,9 +6814,9 @@ checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_gnullvm" -version = "0.53.1" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" +checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" [[package]] name = "windows_i686_msvc" @@ -6808,9 +6832,9 @@ checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_i686_msvc" -version = "0.53.1" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" +checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" [[package]] name = "windows_x86_64_gnu" @@ -6826,9 +6850,9 @@ checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnu" -version = "0.53.1" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" +checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" [[package]] name = "windows_x86_64_gnullvm" @@ -6844,9 +6868,9 @@ checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_gnullvm" -version = "0.53.1" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" +checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" [[package]] name = "windows_x86_64_msvc" @@ -6862,9 +6886,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "windows_x86_64_msvc" -version = "0.53.1" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" +checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" [[package]] name = "winnow" @@ -6905,15 +6929,15 @@ dependencies = [ "log", "serde", "thiserror 2.0.17", - "windows 0.62.2", - "windows-core 0.62.2", + "windows 0.62.1", + "windows-core 0.62.1", ] [[package]] name = "writeable" -version = "0.6.2" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" +checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" [[package]] name = "xattr" @@ -6944,10 +6968,11 @@ dependencies = [ [[package]] name = "yoke" -version = "0.8.1" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" +checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" dependencies = [ + "serde", "stable_deref_trait", "yoke-derive", "zerofrom", @@ -6955,13 +6980,13 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.8.1" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" +checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.106", "synstructure", ] @@ -6982,7 +7007,7 @@ checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831" dependencies = [ "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.106", ] [[package]] @@ -7002,7 +7027,7 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.106", "synstructure", ] @@ -7014,9 +7039,9 @@ checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" [[package]] name = "zerotrie" -version = "0.2.3" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" +checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" dependencies = [ "displaydoc", "yoke", @@ -7025,9 +7050,9 @@ dependencies = [ [[package]] name = "zerovec" -version = "0.11.5" +version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" +checksum = "e7aa2bd55086f1ab526693ecbe444205da57e25f4489879da80635a46d90e73b" dependencies = [ "yoke", "zerofrom", @@ -7036,11 +7061,11 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.11.2" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" +checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.110", + "syn 2.0.106", ] diff --git a/MACRO_TEST_CONVERSION_STATUS.md b/MACRO_TEST_CONVERSION_STATUS.md deleted file mode 100644 index f44eee4aa..000000000 --- a/MACRO_TEST_CONVERSION_STATUS.md +++ /dev/null @@ -1,192 +0,0 @@ -# Test Conversion Status: `#[freenet_test]` Macro - -## Overview - -This document tracks which integration tests have been converted to use the `#[freenet_test]` procedural macro and explains why certain tests were not converted. - -## Successfully Converted Tests - -### error_notification.rs (3/4 tests converted) - -✅ **Converted:** -1. `test_get_error_notification` - GET operation error notification -2. `test_put_error_notification` - PUT operation error notification -3. `test_update_error_notification` - UPDATE operation error notification - -❌ **Not Converted:** -- `test_connection_drop_error_notification` - Requires custom peer lifecycle management (selective shutdown) - - **Reason:** The macro doesn't support stopping individual nodes mid-test - -### isolated_node_regression.rs (4/4 tests converted) - -✅ **All Converted:** -1. `test_isolated_node_put_get_workflow` - Complete PUT→GET workflow on isolated node -2. `test_concurrent_get_deduplication_race` - Concurrent GET operations -3. `test_isolated_node_local_subscription` - Subscribe operations on isolated node -4. `test_isolated_node_update_operation` - UPDATE operations on isolated nodes - -### test_macro_example.rs (7/7 tests - examples) - -✅ **All Using Macro:** -1. `test_single_node` - Single gateway node -2. `test_multi_node` - Multiple nodes (gateway + 2 peers) -3. `test_with_event_aggregation` - Event aggregation on failure -4. `test_always_aggregate` - Event aggregation always -5. `test_custom_tokio_config` - Custom tokio worker threads -6. `test_current_thread_runtime` - Single-threaded tokio runtime -7. `test_multiple_gateways` - Multiple gateway nodes (NEW!) - -## Tests Not Yet Converted - -### operations.rs (0/11 tests converted) - -**Tests in this file:** -- `test_put_contract` -- `test_update_contract` -- `test_put_merge_persists_state` -- `test_multiple_clients_subscription` -- `test_get_with_subscribe_flag` -- `test_put_with_subscribe_flag` -- `test_delegate_request` -- `test_gateway_packet_size_change_after_60s` -- `test_production_decryption_error_scenario` -- `test_subscription_introspection` -- `test_update_no_change_notification` - -**Why not converted:** -1. **Complex peer-gateway relationships** - Tests set up specific gateway configurations and peer connections -2. **Custom gateway discovery** - Uses `gw_config()` and `base_node_test_config()` helpers with specific network topologies -3. **Multi-phase testing** - Some tests require stopping/starting nodes at specific points -4. **Contract persistence verification** - Tests verify data persists across specific node restarts -5. **Uses `#[test_log::test]`** - Would need to verify macro compatibility - -**Future conversion approach:** -- Macro would need to support: - - Configuring peer gateway lists (which gateways peers should connect to) - - Mid-test node lifecycle control (stop/restart specific nodes) - - Or: Create specialized macros for these patterns (e.g., `#[freenet_network_test]`) - -### connectivity.rs (0/3 tests converted) - -**Tests in this file:** -- `test_gateway_reconnection` -- `test_basic_gateway_connectivity` -- `test_three_node_network_connectivity` - -**Why not converted:** -1. **Network topology testing** - These tests specifically test connection establishment and maintenance -2. **Custom disconnect/reconnect logic** - Tests intentionally disconnect and reconnect nodes -3. **Connection state verification** - Tests verify specific connection counts and states -4. **Requires fine-grained control** - Need to control exactly when nodes connect/disconnect - -**Future conversion approach:** -- Similar to operations.rs, would need lifecycle control features -- Or: Keep as-is since these are network layer tests, not contract operation tests - -### Other Test Files - -- `redb_migration.rs` - Database migration tests (no multi-node setup) -- `token_expiration.rs` - Token config tests (no multi-node setup) -- `ubertest.rs` - Large-scale River app test (too specialized/complex) - -## Conversion Statistics - -- **Total test files analyzed:** 8 -- **Files with converted tests:** 3 -- **Total tests converted:** 7 -- **Total boilerplate lines eliminated:** ~300+ - -## Macro Features Used in Converted Tests - -### Basic Features -- ✅ Single gateway node -- ✅ Multiple peer nodes -- ✅ Multiple gateway nodes (NEW!) -- ✅ Custom timeouts -- ✅ Custom startup wait times -- ✅ Event aggregation (on_failure, always, never) -- ✅ Custom log levels -- ✅ Tokio flavor configuration -- ✅ Tokio worker thread configuration - -### TestContext API Used -- ✅ `ctx.node(label)` - Get specific node -- ✅ `ctx.gateway()` - Get first gateway -- ✅ `ctx.gateways()` - Get all gateways (NEW!) -- ✅ `ctx.peers()` - Get all peers (NEW!) -- ✅ `ctx.node_labels()` - Get all node labels -- ✅ `ctx.event_log_path(label)` - Get node event log path -- ✅ `ctx.aggregate_events()` - Aggregate events from all nodes -- ✅ `ctx.generate_failure_report(error)` - Generate comprehensive failure report -- ✅ `ctx.generate_success_summary()` - Generate success summary - -## Future Enhancements - -### For Conversion of Remaining Tests - -1. **Peer Gateway Configuration** - ```rust - #[freenet_test( - nodes = ["gw-1", "gw-2", "peer-1", "peer-2"], - gateways = ["gw-1", "gw-2"], - peer_gateways = { - "peer-1": ["gw-1"], - "peer-2": ["gw-2"] - } - )] - ``` - -2. **Node Lifecycle Control** - ```rust - async fn test(ctx: &mut TestContext) -> TestResult { - // Start with nodes running - ctx.stop_node("peer-1").await?; - // Test something - ctx.start_node("peer-1").await?; - // Test something else - Ok(()) - } - ``` - -3. **Network State Verification** - ```rust - async fn test(ctx: &mut TestContext) -> TestResult { - let conn_count = ctx.connection_count("gateway").await?; - assert_eq!(conn_count, 2); - Ok(()) - } - ``` - -### Specialized Macros - -For network/connectivity tests, consider creating specialized macros: - -```rust -#[freenet_network_test( - topology = "star", // or "mesh", "chain", etc. - gateway_count = 1, - peer_count = 3, - test_disconnections = true -)] -async fn test(ctx: &mut NetworkTestContext) -> TestResult { - // Network-specific test context with connection control - Ok(()) -} -``` - -## Conclusion - -The `#[freenet_test]` macro successfully handles: -- ✅ Isolated node tests -- ✅ Simple multi-node tests -- ✅ Tests with multiple gateways -- ✅ Tests with custom tokio configurations -- ✅ Tests with event aggregation - -The macro is **not suitable** for: -- ❌ Tests requiring specific peer-gateway connections -- ❌ Tests requiring node lifecycle control (stop/restart) -- ❌ Network topology and connectivity tests -- ❌ Tests with complex custom configurations - -For these cases, the existing test infrastructure remains appropriate and should be kept as-is. diff --git a/apps/freenet-ping/Cargo.lock b/apps/freenet-ping/Cargo.lock index 92a5933dc..340aa1761 100644 --- a/apps/freenet-ping/Cargo.lock +++ b/apps/freenet-ping/Cargo.lock @@ -1028,7 +1028,7 @@ dependencies = [ "libc", "option-ext", "redox_users", - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] @@ -1281,7 +1281,7 @@ dependencies = [ [[package]] name = "freenet" -version = "0.1.37" +version = "0.1.36" dependencies = [ "aes-gcm", "ahash", @@ -1309,7 +1309,6 @@ dependencies = [ "hickory-resolver", "itertools 0.14.0", "notify", - "once_cell", "opentelemetry", "parking_lot", "pav_regression", @@ -1342,6 +1341,16 @@ dependencies = [ "xz2", ] +[[package]] +name = "freenet-macros" +version = "0.1.0" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.106", +] + [[package]] name = "freenet-macros" version = "0.1.1" @@ -1361,6 +1370,7 @@ dependencies = [ "chrono", "clap", "freenet", + "freenet-macros 0.1.0", "freenet-ping-types", "freenet-stdlib", "futures", @@ -1399,9 +1409,9 @@ dependencies = [ [[package]] name = "freenet-stdlib" -version = "0.1.24" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f39e2953b4b0d82dd02458653b57166ba8c967c6b3fcec146102a27e05a7081a" +checksum = "66c64fa03f4a083918c7e347be47122c223d8156f4c012a0fe8e89a643350f2d" dependencies = [ "arbitrary", "bincode", @@ -1410,7 +1420,7 @@ dependencies = [ "byteorder", "chrono", "flatbuffers 24.12.23", - "freenet-macros", + "freenet-macros 0.1.1", "futures", "js-sys", "once_cell", @@ -3718,9 +3728,9 @@ checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" [[package]] name = "slab" -version = "0.4.11" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" +checksum = "04dc19736151f35336d325007ac991178d504a119863a2fcb3758cdb5e52c50d" [[package]] name = "slice-group-by" @@ -5288,9 +5298,9 @@ dependencies = [ [[package]] name = "wmi" -version = "0.18.0" +version = "0.17.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71d1d435f7745ba9ed55c43049d47b5fbd1104449beaa2afbc80a1e10a4a018" +checksum = "120d8c2b6a7c96c27bf4a7947fd7f02d73ca7f5958b8bd72a696e46cb5521ee6" dependencies = [ "chrono", "futures", diff --git a/apps/freenet-ping/app/Cargo.toml b/apps/freenet-ping/app/Cargo.toml index 1d13586f6..f18798403 100644 --- a/apps/freenet-ping/app/Cargo.toml +++ b/apps/freenet-ping/app/Cargo.toml @@ -26,6 +26,7 @@ humantime = "2.2.0" [dev-dependencies] freenet = { path = "../../../crates/core" } +freenet-macros = { path = "../../../crates/freenet-macros" } testresult = { workspace = true } [lib] diff --git a/apps/freenet-ping/app/src/ping_client.rs b/apps/freenet-ping/app/src/ping_client.rs index a8396a64f..f4aa8df15 100644 --- a/apps/freenet-ping/app/src/ping_client.rs +++ b/apps/freenet-ping/app/src/ping_client.rs @@ -1,7 +1,7 @@ use std::collections::HashMap; use std::time::{Duration, Instant}; -use chrono::{DateTime, Utc}; +use freenet_ping_types::chrono::{DateTime, Utc}; use freenet_ping_types::{Ping, PingContractOptions}; use freenet_stdlib::client_api::{ ClientRequest, ContractRequest, ContractResponse, HostResponse, WebApi, diff --git a/apps/freenet-ping/app/tests/common/mod.rs b/apps/freenet-ping/app/tests/common/mod.rs index 665962391..be3e20a8e 100644 --- a/apps/freenet-ping/app/tests/common/mod.rs +++ b/apps/freenet-ping/app/tests/common/mod.rs @@ -307,18 +307,22 @@ fn compile_contract(contract_path: &PathBuf) -> anyhow::Result> { .map_err(|_| anyhow::anyhow!("CARGO_TARGET_DIR should be set"))?; println!("trying to compile the test contract, target: {target}"); - compile_rust_wasm_lib( - &BuildToolConfig { - features: None, - package_type: PackageType::Contract, - debug: true, - }, - contract_path, - )?; + let build_config = BuildToolConfig { + features: None, + package_type: PackageType::Contract, + debug: false, + }; + + compile_rust_wasm_lib(&build_config, contract_path)?; + let build_dir = if build_config.debug { + "debug" + } else { + "release" + }; let output_file = Path::new(&target) .join(WASM_TARGET) - .join("debug") + .join(build_dir) .join(WASM_FILE_NAME.replace('-', "_")) .with_extension("wasm"); println!("output file: {output_file:?}"); diff --git a/apps/freenet-ping/app/tests/run_app.rs b/apps/freenet-ping/app/tests/run_app.rs index a6a7c2009..3dc74a063 100644 --- a/apps/freenet-ping/app/tests/run_app.rs +++ b/apps/freenet-ping/app/tests/run_app.rs @@ -3,7 +3,7 @@ mod common; use std::{net::TcpListener, path::PathBuf, time::Duration}; use anyhow::anyhow; -use freenet::{local_node::NodeConfig, server::serve_gateway}; +use freenet::{local_node::NodeConfig, server::serve_gateway, test_utils::TestContext}; use freenet_ping_types::{Ping, PingContractOptions}; use freenet_stdlib::{ client_api::{ @@ -12,7 +12,7 @@ use freenet_stdlib::{ }, prelude::*, }; -use futures::{stream::FuturesUnordered, FutureExt, StreamExt}; +use futures::FutureExt; use rand::SeedableRng; use testresult::TestResult; use tokio::{select, time::sleep, time::timeout}; @@ -20,8 +20,8 @@ use tokio_tungstenite::connect_async; use tracing::{level_filters::LevelFilter, span, Instrument, Level}; use common::{ - base_node_test_config, base_node_test_config_with_rng, gw_config_from_path, - gw_config_from_path_with_rng, APP_TAG, PACKAGE_DIR, PATH_TO_CONTRACT, + base_node_test_config_with_rng, gw_config_from_path_with_rng, APP_TAG, PACKAGE_DIR, + PATH_TO_CONTRACT, }; use freenet_ping_app::ping_client::{ run_ping_client, wait_for_get_response, wait_for_put_response, wait_for_subscribe_response, @@ -1519,769 +1519,626 @@ async fn test_ping_application_loop() -> TestResult { Ok(()) } -#[cfg(feature = "manual-tests")] -#[tokio::test(flavor = "multi_thread")] -async fn test_ping_partially_connected_network() -> TestResult { +#[freenet_macros::freenet_test( + nodes = ["gw-0", "gw-1", "gw-2", "node-0", "node-1", "node-2", "node-3", "node-4", "node-5", "node-6"], + gateways = ["gw-0", "gw-1", "gw-2"], + peer_connectivity_ratio = 0.3, + timeout_secs = 240, + startup_wait_secs = 60, + tokio_flavor = "multi_thread", + aggregate_events = "on_failure" +)] +async fn test_ping_partially_connected_network( + ctx: &mut freenet::test_utils::TestContext, +) -> TestResult { /* * This test verifies how subscription propagation works in a partially connected network. * - * Parameters: - * - NUM_GATEWAYS: Number of gateway nodes to create (default: 3) - * - NUM_REGULAR_NODES: Number of regular nodes to create (default: 7) - * - CONNECTIVITY_RATIO: Percentage of connectivity between regular nodes (0.0-1.0) - * - * Network Topology: - * - Creates a network with specified number of gateway and regular nodes - * - ALL regular nodes connect to ALL gateways (full gateway connectivity) - * - Regular nodes have partial connectivity to other regular nodes based on CONNECTIVITY_RATIO - * - Uses a deterministic approach to create partial connectivity between regular nodes + * Network Topology (configured by macro): + * - 3 gateways (gw-0, gw-1, gw-2) + * - 7 regular nodes (node-0 through node-6) + * - ALL regular nodes connect to ALL gateways (auto_connect_peers = true) + * - Regular nodes have 50% connectivity to other regular nodes (peer_connectivity_ratio = 0.5) + * - Uses deterministic blocking pattern based on node indices * * Test procedure: - * 1. Configures and starts all nodes with the specified topology - * 2. One node publishes the ping contract - * 3. Tracks which nodes successfully access the contract - * 4. Subscribes available nodes to the contract - * 5. Sends an update from one node - * 6. Verifies update propagation across the network - * 7. Analyzes results to detect potential subscription propagation issues + * 1. Load and publish the ping contract + * 2. Track which nodes successfully access the contract + * 3. Subscribe available nodes to the contract + * 4. Send an update from one node + * 5. Verify update propagation across the network + * 6. Analyze results to detect potential subscription propagation issues */ - // Network configuration parameters - const NUM_GATEWAYS: usize = 3; - const NUM_REGULAR_NODES: usize = 7; - const CONNECTIVITY_RATIO: f64 = 0.5; // Controls connectivity between regular nodes + use tokio_tungstenite::connect_async; + + let num_gateways = ctx.gateways().len(); + let num_regular_nodes = ctx.peers().len(); - // Configure logging - freenet::config::set_logger(Some(LevelFilter::DEBUG), None); tracing::info!( - "Starting test with {} gateways and {} regular nodes (connectivity ratio: {})", - NUM_GATEWAYS, - NUM_REGULAR_NODES, - CONNECTIVITY_RATIO + "Test started with {} gateways and {} regular nodes (50% connectivity ratio)", + num_gateways, + num_regular_nodes ); - // Setup network sockets for the gateways - let mut gateway_sockets = Vec::with_capacity(NUM_GATEWAYS); - let mut ws_api_gateway_sockets = Vec::with_capacity(NUM_GATEWAYS); - - for _ in 0..NUM_GATEWAYS { - gateway_sockets.push(TcpListener::bind("127.0.0.1:0")?); - ws_api_gateway_sockets.push(TcpListener::bind("127.0.0.1:0")?); + // Connect WebSocket clients to all gateway nodes + let mut gateway_clients = Vec::with_capacity(num_gateways); + for gw in ctx.gateways() { + let uri = format!( + "ws://127.0.0.1:{}/v1/contract/command?encodingProtocol=native", + gw.ws_port + ); + let (stream, _) = connect_async(&uri).await?; + let client = WebApi::start(stream); + gateway_clients.push(client); + tracing::info!("Connected to gateway {}", gw.label); } - // Setup API sockets for regular nodes - let mut ws_api_node_sockets = Vec::with_capacity(NUM_REGULAR_NODES); - let mut regular_node_addresses = Vec::with_capacity(NUM_REGULAR_NODES); - - // First, bind all sockets to get addresses for later blocking - for _i in 0..NUM_REGULAR_NODES { - let socket = TcpListener::bind("127.0.0.1:0")?; - // Store the address for later use in blocked_addresses - regular_node_addresses.push(socket.local_addr()?); - ws_api_node_sockets.push(TcpListener::bind("127.0.0.1:0")?); + // Connect WebSocket clients to all peer nodes + let mut node_clients = Vec::with_capacity(num_regular_nodes); + for peer in ctx.peers() { + let uri = format!( + "ws://127.0.0.1:{}/v1/contract/command?encodingProtocol=native", + peer.ws_port + ); + let (stream, _) = connect_async(&uri).await?; + let client = WebApi::start(stream); + node_clients.push(client); + tracing::info!("Connected to peer {}", peer.label); } - // Configure gateway nodes - let mut gateway_info = Vec::new(); - let mut ws_api_ports_gw = Vec::new(); - - // Build configurations and keep temp directories alive - let mut gateway_configs = Vec::with_capacity(NUM_GATEWAYS); - let mut gateway_presets = Vec::with_capacity(NUM_GATEWAYS); - - for i in 0..NUM_GATEWAYS { - let data_dir_suffix = format!("gw_{i}"); + // Load the ping contract. Compile once to determine the code hash, then again with proper options. + let path_to_code = PathBuf::from(PACKAGE_DIR).join(PATH_TO_CONTRACT); + tracing::info!(path=%path_to_code.display(), "loading contract code"); + let temp_options = PingContractOptions { + frequency: Duration::from_secs(3), + ttl: Duration::from_secs(60), + tag: APP_TAG.to_string(), + code_key: String::new(), + }; + let temp_params = Parameters::from(serde_json::to_vec(&temp_options).unwrap()); + let temp_container = common::load_contract(&path_to_code, temp_params)?; + let code_hash = CodeHash::from_code(temp_container.data()); + let ping_options = PingContractOptions { + frequency: Duration::from_secs(3), + ttl: Duration::from_secs(60), + tag: APP_TAG.to_string(), + code_key: code_hash.to_string(), + }; - let (cfg, preset) = base_node_test_config( - true, - vec![], - Some(gateway_sockets[i].local_addr()?.port()), - ws_api_gateway_sockets[i].local_addr()?.port(), - &data_dir_suffix, - None, // base_tmp_dir - None, // No blocked addresses for gateways - ) + let params = Parameters::from(serde_json::to_vec(&ping_options).unwrap()); + let container = common::load_contract(&path_to_code, params)?; + let contract_key = container.key(); + + // Choose a node to publish the contract + let publisher_idx = 0; + tracing::info!("Node {} will publish the contract", publisher_idx); + + // Publisher node puts the contract + let ping = Ping::default(); + let serialized = serde_json::to_vec(&ping)?; + let wrapped_state = WrappedState::new(serialized); + + let publisher = &mut node_clients[publisher_idx]; + publisher + .send(ClientRequest::ContractOp(ContractRequest::Put { + contract: container.clone(), + state: wrapped_state.clone(), + related_contracts: RelatedContracts::new(), + subscribe: false, + })) .await?; - let public_port = cfg.network_api.public_port.unwrap(); - let path = preset.temp_dir.path().to_path_buf(); - let config_info = gw_config_from_path(public_port, &path)?; - - tracing::info!("Gateway {} data dir: {:?}", i, preset.temp_dir.path()); - ws_api_ports_gw.push(cfg.ws_api.ws_api_port.unwrap()); - gateway_info.push(config_info); - gateway_configs.push(cfg); - gateway_presets.push(preset); - } + // Wait for put response on publisher + let key = wait_for_put_response(publisher, &contract_key) + .await + .map_err(anyhow::Error::msg)?; + tracing::info!(key=%key, "Publisher node {} put ping contract successfully!", publisher_idx); - // Serialize gateway info for nodes to use - let serialized_gateways: Vec = gateway_info - .iter() - .map(|info| serde_json::to_string(info).unwrap()) - .collect(); - - // Configure regular nodes with partial connectivity to OTHER regular nodes - let mut ws_api_ports_nodes = Vec::new(); - let mut node_connections = Vec::new(); - - // Build configurations and keep temp directories alive - let mut node_configs = Vec::with_capacity(NUM_REGULAR_NODES); - let mut node_presets = Vec::with_capacity(NUM_REGULAR_NODES); - - for (i, _) in ws_api_node_sockets.iter().enumerate() { - // Determine which other regular nodes this node should block - let mut blocked_addresses = Vec::new(); - for (j, &addr) in regular_node_addresses.iter().enumerate() { - if i == j { - continue; // Skip self - } + // All nodes try to get the contract to see which have access + let mut nodes_with_contract = vec![false; num_regular_nodes]; + let mut get_requests = Vec::with_capacity(num_regular_nodes); - // Use a deterministic approach based on node indices - // If the result is >= than CONNECTIVITY_RATIO, block the connection - let should_block = (i * j) % 100 >= (CONNECTIVITY_RATIO * 100.0) as usize; - if should_block { - blocked_addresses.push(addr); - } - } - - // Count effective connections to other regular nodes - let effective_connections = (NUM_REGULAR_NODES - 1) - blocked_addresses.len(); - node_connections.push(effective_connections); - - let data_dir_suffix = format!("node_{i}"); - - let (cfg, preset) = base_node_test_config( - false, - serialized_gateways.clone(), // All nodes connect to all gateways - None, - ws_api_node_sockets[i].local_addr()?.port(), - &data_dir_suffix, - None, - Some(blocked_addresses.clone()), // Use blocked_addresses for regular nodes - ) - .await?; - - tracing::info!( - "Node {} data dir: {:?} - Connected to {} other regular nodes (blocked: {})", - i, - preset.temp_dir.path(), - effective_connections, - blocked_addresses.len() - ); - - ws_api_ports_nodes.push(cfg.ws_api.ws_api_port.unwrap()); - node_configs.push(cfg); - node_presets.push(preset); + for (i, client) in node_clients.iter_mut().enumerate() { + client + .send(ClientRequest::ContractOp(ContractRequest::Get { + key: contract_key, + return_contract_code: true, + subscribe: false, + })) + .await?; + get_requests.push(i); } - // Free ports to avoid binding errors - std::mem::drop(gateway_sockets); - std::mem::drop(ws_api_gateway_sockets); - std::mem::drop(ws_api_node_sockets); - - // Start all gateway nodes - let gateway_futures = FuturesUnordered::new(); - for config in gateway_configs.into_iter() { - let gateway_future = async move { - let config = config.build().await?; - let node = NodeConfig::new(config.clone()) - .await? - .build(serve_gateway(config.ws_api).await) - .await?; - node.run().await - } - .boxed_local(); - gateway_futures.push(gateway_future); - } + // Track gateways with the contract + let mut gateways_with_contract = vec![false; num_gateways]; + let mut gw_get_requests = Vec::with_capacity(num_gateways); - // Start all regular nodes - let regular_node_futures = FuturesUnordered::new(); - for config in node_configs.into_iter() { - let regular_node_future = async move { - let config = config.build().await?; - let node = NodeConfig::new(config.clone()) - .await? - .build(serve_gateway(config.ws_api).await) - .await?; - node.run().await - } - .boxed_local(); - tokio::time::sleep(Duration::from_secs(2)).await; - regular_node_futures.push(regular_node_future); + for (i, client) in gateway_clients.iter_mut().enumerate() { + client + .send(ClientRequest::ContractOp(ContractRequest::Get { + key: contract_key, + return_contract_code: true, + subscribe: false, + })) + .await?; + gw_get_requests.push(i); } - // Create a future that will complete if any gateway fails - let mut gateway_monitor = gateway_futures.into_future(); - let mut regular_node_monitor = regular_node_futures.into_future(); + // Process all get responses with a timeout + let total_timeout = Duration::from_secs(30); + let start = std::time::Instant::now(); - let test = tokio::time::timeout(Duration::from_secs(240), async { - // Wait for nodes to start up - tracing::info!("Waiting for nodes to start up..."); - tokio::time::sleep(Duration::from_secs(30)).await; - tracing::info!("Proceeding to connect to nodes..."); - - // Connect to all nodes with retry logic - let mut gateway_clients = Vec::with_capacity(NUM_GATEWAYS); - for (i, port) in ws_api_ports_gw.iter().enumerate() { - let uri = format!( - "ws://127.0.0.1:{port}/v1/contract/command?encodingProtocol=native" - ); - let (stream, _) = connect_async(&uri).await?; - let client = WebApi::start(stream); - gateway_clients.push(client); - tracing::info!("Connected to gateway {}", i); + while !get_requests.is_empty() || !gw_get_requests.is_empty() { + if start.elapsed() > total_timeout { + tracing::warn!("Timeout waiting for get responses, continuing with test"); + break; } - let mut node_clients = Vec::with_capacity(NUM_REGULAR_NODES); - for (i, port) in ws_api_ports_nodes.iter().enumerate() { - let uri = format!( - "ws://127.0.0.1:{port}/v1/contract/command?encodingProtocol=native" - ); - let (stream, _) = connect_async(&uri).await?; - let client = WebApi::start(stream); - node_clients.push(client); - tracing::info!("Connected to regular node {}", i); + // Check regular nodes + let mut i = 0; + while i < get_requests.len() { + let node_idx = get_requests[i]; + let client = &mut node_clients[node_idx]; + + match timeout(Duration::from_millis(500), client.recv()).await { + Ok(Ok(HostResponse::ContractResponse(ContractResponse::GetResponse { + key, + .. + }))) => { + if key == contract_key { + tracing::info!("Node {} successfully got the contract", node_idx); + nodes_with_contract[node_idx] = true; + get_requests.remove(i); + continue; + } + } + Ok(Ok(_)) => {} + Ok(Err(e)) => { + tracing::warn!("Error receiving from node {}: {}", node_idx, e); + get_requests.remove(i); + continue; + } + Err(_) => {} + } + i += 1; } - // Log the node connectivity - tracing::info!("Node connectivity setup:"); - for (i, num_connections) in node_connections.iter().enumerate() { - tracing::info!("Node {} is connected to all {} gateways and {} other regular nodes", - i, NUM_GATEWAYS, num_connections); + // Check gateways + let mut i = 0; + while i < gw_get_requests.len() { + let gw_idx = gw_get_requests[i]; + let client = &mut gateway_clients[gw_idx]; + + match timeout(Duration::from_millis(500), client.recv()).await { + Ok(Ok(HostResponse::ContractResponse(ContractResponse::GetResponse { + key, + .. + }))) => { + if key == contract_key { + tracing::info!("Gateway {} successfully got the contract", gw_idx); + gateways_with_contract[gw_idx] = true; + gw_get_requests.remove(i); + continue; + } + } + Ok(Ok(_)) => {} + Ok(Err(e)) => { + tracing::warn!("Error receiving from gateway {}: {}", gw_idx, e); + gw_get_requests.remove(i); + continue; + } + Err(_) => {} + } + i += 1; } - // Load the ping contract. Compile once to determine the code hash, then again with proper options. - let path_to_code = PathBuf::from(PACKAGE_DIR).join(PATH_TO_CONTRACT); - tracing::info!(path=%path_to_code.display(), "loading contract code"); - let temp_options = PingContractOptions { - frequency: Duration::from_secs(3), - ttl: Duration::from_secs(60), - tag: APP_TAG.to_string(), - code_key: String::new(), - }; - let temp_params = Parameters::from(serde_json::to_vec(&temp_options).unwrap()); - let temp_container = common::load_contract(&path_to_code, temp_params)?; - let code_hash = CodeHash::from_code(temp_container.data()); - let ping_options = PingContractOptions { - frequency: Duration::from_secs(3), - ttl: Duration::from_secs(60), - tag: APP_TAG.to_string(), - code_key: code_hash.to_string(), - }; - - let params = Parameters::from(serde_json::to_vec(&ping_options).unwrap()); - let container = common::load_contract(&path_to_code, params)?; - let contract_key = container.key(); - - // Choose a node to publish the contract - let publisher_idx = 0; - tracing::info!("Node {} will publish the contract", publisher_idx); - - // Publisher node puts the contract - let ping = Ping::default(); - let serialized = serde_json::to_vec(&ping)?; - let wrapped_state = WrappedState::new(serialized); - - let publisher = &mut node_clients[publisher_idx]; - publisher - .send(ClientRequest::ContractOp(ContractRequest::Put { - contract: container.clone(), - state: wrapped_state.clone(), - related_contracts: RelatedContracts::new(), - subscribe: false, - })) - .await?; + tokio::time::sleep(Duration::from_millis(100)).await; + } - // Wait for put response on publisher - let key = wait_for_put_response(publisher, &contract_key) - .await - .map_err(anyhow::Error::msg)?; - tracing::info!(key=%key, "Publisher node {} put ping contract successfully!", publisher_idx); + // Log initial contract distribution + tracing::info!("Initial contract distribution:"); + tracing::info!( + "Gateways with contract: {}/{}", + gateways_with_contract.iter().filter(|&&x| x).count(), + num_gateways + ); + tracing::info!( + "Regular nodes with contract: {}/{}", + nodes_with_contract.iter().filter(|&&x| x).count(), + num_regular_nodes + ); - // All nodes try to get the contract to see which have access - let mut nodes_with_contract = [false; NUM_REGULAR_NODES]; - let mut get_requests = Vec::with_capacity(NUM_REGULAR_NODES); + // All nodes with the contract subscribe to it + let mut subscribed_nodes = vec![false; num_regular_nodes]; + let mut subscription_requests = Vec::new(); - for (i, client) in node_clients.iter_mut().enumerate() { - client - .send(ClientRequest::ContractOp(ContractRequest::Get { + for (i, has_contract) in nodes_with_contract.iter().enumerate() { + if *has_contract { + node_clients[i] + .send(ClientRequest::ContractOp(ContractRequest::Subscribe { key: contract_key, - return_contract_code: true, - subscribe: false, + summary: None, })) .await?; - get_requests.push(i); + subscription_requests.push(i); } + } - // Track gateways with the contract - let mut gateways_with_contract = [false; NUM_GATEWAYS]; - let mut gw_get_requests = Vec::with_capacity(NUM_GATEWAYS); + // Also subscribe gateways + let mut subscribed_gateways = vec![false; num_gateways]; + let mut gw_subscription_requests = Vec::new(); - for (i, client) in gateway_clients.iter_mut().enumerate() { - client - .send(ClientRequest::ContractOp(ContractRequest::Get { + for (i, has_contract) in gateways_with_contract.iter().enumerate() { + if *has_contract { + gateway_clients[i] + .send(ClientRequest::ContractOp(ContractRequest::Subscribe { key: contract_key, - return_contract_code: true, - subscribe: false, + summary: None, })) .await?; - gw_get_requests.push(i); + gw_subscription_requests.push(i); } + } - // Process all get responses with a timeout - let total_timeout = Duration::from_secs(30); - let start = std::time::Instant::now(); + // Process subscription responses with a timeout + let start = std::time::Instant::now(); + let total_timeout = Duration::from_secs(30); - while !get_requests.is_empty() || !gw_get_requests.is_empty() { - if start.elapsed() > total_timeout { - tracing::warn!("Timeout waiting for get responses, continuing with test"); - break; - } + while !subscription_requests.is_empty() || !gw_subscription_requests.is_empty() { + if start.elapsed() > total_timeout { + tracing::warn!("Timeout waiting for subscription responses, continuing with test"); + break; + } - // Check regular nodes - let mut i = 0; - while i < get_requests.len() { - let node_idx = get_requests[i]; - let client = &mut node_clients[node_idx]; - - match timeout(Duration::from_millis(500), client.recv()).await { - Ok(Ok(HostResponse::ContractResponse(ContractResponse::GetResponse { key, .. }))) => { - if key == contract_key { - tracing::info!("Node {} successfully got the contract", node_idx); - nodes_with_contract[node_idx] = true; - get_requests.remove(i); - continue; - } - } - Ok(Ok(_)) => {}, - Ok(Err(e)) => { - tracing::warn!("Error receiving from node {}: {}", node_idx, e); - get_requests.remove(i); + // Check regular nodes + let mut i = 0; + while i < subscription_requests.len() { + let node_idx = subscription_requests[i]; + let client = &mut node_clients[node_idx]; + + match timeout(Duration::from_millis(500), client.recv()).await { + Ok(Ok(HostResponse::ContractResponse(ContractResponse::SubscribeResponse { + key, + subscribed, + .. + }))) => { + if key == contract_key { + tracing::info!("Node {} subscription result: {}", node_idx, subscribed); + subscribed_nodes[node_idx] = subscribed; + subscription_requests.remove(i); continue; } - Err(_) => {} } - i += 1; + Ok(Ok(_)) => {} + Ok(Err(e)) => { + tracing::warn!("Error receiving from node {}: {}", node_idx, e); + subscription_requests.remove(i); + continue; + } + Err(_) => {} } + i += 1; + } - // Check gateways - let mut i = 0; - while i < gw_get_requests.len() { - let gw_idx = gw_get_requests[i]; - let client = &mut gateway_clients[gw_idx]; - - match timeout(Duration::from_millis(500), client.recv()).await { - Ok(Ok(HostResponse::ContractResponse(ContractResponse::GetResponse { key, .. }))) => { - if key == contract_key { - tracing::info!("Gateway {} successfully got the contract", gw_idx); - gateways_with_contract[gw_idx] = true; - gw_get_requests.remove(i); - continue; - } - } - Ok(Ok(_)) => {}, - Ok(Err(e)) => { - tracing::warn!("Error receiving from gateway {}: {}", gw_idx, e); - gw_get_requests.remove(i); + // Check gateways + let mut i = 0; + while i < gw_subscription_requests.len() { + let gw_idx = gw_subscription_requests[i]; + let client = &mut gateway_clients[gw_idx]; + + match timeout(Duration::from_millis(500), client.recv()).await { + Ok(Ok(HostResponse::ContractResponse(ContractResponse::SubscribeResponse { + key, + subscribed, + .. + }))) => { + if key == contract_key { + tracing::info!("Gateway {} subscription result: {}", gw_idx, subscribed); + subscribed_gateways[gw_idx] = subscribed; + gw_subscription_requests.remove(i); continue; } - Err(_) => {} } - i += 1; - } - - tokio::time::sleep(Duration::from_millis(100)).await; - } - - // Log initial contract distribution - tracing::info!("Initial contract distribution:"); - tracing::info!("Gateways with contract: {}/{}", - gateways_with_contract.iter().filter(|&&x| x).count(), - NUM_GATEWAYS); - tracing::info!("Regular nodes with contract: {}/{}", - nodes_with_contract.iter().filter(|&&x| x).count(), - NUM_REGULAR_NODES); - - // All nodes with the contract subscribe to it - let mut subscribed_nodes = [false; NUM_REGULAR_NODES]; - let mut subscription_requests = Vec::new(); - - for (i, has_contract) in nodes_with_contract.iter().enumerate() { - if *has_contract { - node_clients[i] - .send(ClientRequest::ContractOp(ContractRequest::Subscribe { - key: contract_key, - summary: None, - })) - .await?; - subscription_requests.push(i); - } - } - - // Also subscribe gateways - let mut subscribed_gateways = [false; NUM_GATEWAYS]; - let mut gw_subscription_requests = Vec::new(); - - for (i, has_contract) in gateways_with_contract.iter().enumerate() { - if *has_contract { - gateway_clients[i] - .send(ClientRequest::ContractOp(ContractRequest::Subscribe { - key: contract_key, - summary: None, - })) - .await?; - gw_subscription_requests.push(i); + Ok(Ok(_)) => {} + Ok(Err(e)) => { + tracing::warn!("Error receiving from gateway {}: {}", gw_idx, e); + gw_subscription_requests.remove(i); + continue; + } + Err(_) => {} } + i += 1; } - // Process subscription responses with a timeout - let start = std::time::Instant::now(); - let total_timeout = Duration::from_secs(30); + tokio::time::sleep(Duration::from_millis(100)).await; + } - while !subscription_requests.is_empty() || !gw_subscription_requests.is_empty() { - if start.elapsed() > total_timeout { - tracing::warn!("Timeout waiting for subscription responses, continuing with test"); - break; - } + // Log subscription results + tracing::info!("Initial subscription results:"); + tracing::info!( + "Subscribed gateways: {}/{} (with contract: {})", + subscribed_gateways.iter().filter(|&&x| x).count(), + num_gateways, + gateways_with_contract.iter().filter(|&&x| x).count() + ); + tracing::info!( + "Subscribed regular nodes: {}/{} (with contract: {})", + subscribed_nodes.iter().filter(|&&x| x).count(), + num_regular_nodes, + nodes_with_contract.iter().filter(|&&x| x).count() + ); - // Check regular nodes - let mut i = 0; - while i < subscription_requests.len() { - let node_idx = subscription_requests[i]; - let client = &mut node_clients[node_idx]; - - match timeout(Duration::from_millis(500), client.recv()).await { - Ok(Ok(HostResponse::ContractResponse(ContractResponse::SubscribeResponse { key, subscribed, .. }))) => { - if key == contract_key { - tracing::info!("Node {} subscription result: {}", node_idx, subscribed); - subscribed_nodes[node_idx] = subscribed; - subscription_requests.remove(i); - continue; - } - } - Ok(Ok(_)) => {}, - Ok(Err(e)) => { - tracing::warn!("Error receiving from node {}: {}", node_idx, e); - subscription_requests.remove(i); - continue; - } - Err(_) => {} - } - i += 1; - } + // Choose one subscribed node to send an update + let updater_indices = subscribed_nodes + .iter() + .enumerate() + .filter_map(|(i, &subscribed)| if subscribed { Some(i) } else { None }) + .collect::>(); - // Check gateways - let mut i = 0; - while i < gw_subscription_requests.len() { - let gw_idx = gw_subscription_requests[i]; - let client = &mut gateway_clients[gw_idx]; - - match timeout(Duration::from_millis(500), client.recv()).await { - Ok(Ok(HostResponse::ContractResponse(ContractResponse::SubscribeResponse { key, subscribed, .. }))) => { - if key == contract_key { - tracing::info!("Gateway {} subscription result: {}", gw_idx, subscribed); - subscribed_gateways[gw_idx] = subscribed; - gw_subscription_requests.remove(i); - continue; - } - } - Ok(Ok(_)) => {}, - Ok(Err(e)) => { - tracing::warn!("Error receiving from gateway {}: {}", gw_idx, e); - gw_subscription_requests.remove(i); - continue; - } - Err(_) => {} - } - i += 1; - } + if updater_indices.is_empty() { + return Err(anyhow!("No subscribed nodes to send updates!")); + } - tokio::time::sleep(Duration::from_millis(100)).await; - } + let updater_idx = updater_indices[0]; + tracing::info!("Node {} will send an update", updater_idx); - // Log subscription results - tracing::info!("Initial subscription results:"); - tracing::info!("Subscribed gateways: {}/{} (with contract: {})", - subscribed_gateways.iter().filter(|&&x| x).count(), - NUM_GATEWAYS, - gateways_with_contract.iter().filter(|&&x| x).count()); - tracing::info!("Subscribed regular nodes: {}/{} (with contract: {})", - subscribed_nodes.iter().filter(|&&x| x).count(), - NUM_REGULAR_NODES, - nodes_with_contract.iter().filter(|&&x| x).count()); - - // Choose one subscribed node to send an update - let updater_indices = subscribed_nodes.iter() - .enumerate() - .filter_map(|(i, &subscribed)| if subscribed { Some(i) } else { None }) - .collect::>(); - - if updater_indices.is_empty() { - return Err(anyhow!("No subscribed nodes to send updates!")); - } + // Create a unique tag for the updater + let update_tag = format!("ping-from-node-{updater_idx}"); - let updater_idx = updater_indices[0]; - tracing::info!("Node {} will send an update", updater_idx); + // Send the update + let mut update_ping = Ping::default(); + update_ping.insert(update_tag.clone()); - // Create a unique tag for the updater - let update_tag = format!("ping-from-node-{updater_idx}"); + tracing::info!( + "Node {} sending update with tag: {}", + updater_idx, + update_tag + ); + node_clients[updater_idx] + .send(ClientRequest::ContractOp(ContractRequest::Update { + key: contract_key, + data: UpdateData::Delta(StateDelta::from(serde_json::to_vec(&update_ping).unwrap())), + })) + .await?; - // Send the update - let mut update_ping = Ping::default(); - update_ping.insert(update_tag.clone()); + // Wait for the update to propagate through the network + tracing::info!("Waiting for update to propagate..."); + tokio::time::sleep(Duration::from_secs(20)).await; - tracing::info!("Node {} sending update with tag: {}", updater_idx, update_tag); - node_clients[updater_idx] - .send(ClientRequest::ContractOp(ContractRequest::Update { - key: contract_key, - data: UpdateData::Delta(StateDelta::from(serde_json::to_vec(&update_ping).unwrap())), - })) - .await?; + // Check which nodes received the update + let mut nodes_received_update = vec![false; num_regular_nodes]; + let mut get_state_requests = Vec::new(); - // Wait for the update to propagate through the network - tracing::info!("Waiting for update to propagate..."); - tokio::time::sleep(Duration::from_secs(20)).await; - - // Check which nodes received the update - let mut nodes_received_update = [false; NUM_REGULAR_NODES]; - let mut get_state_requests = Vec::new(); - - for (i, subscribed) in subscribed_nodes.iter().enumerate() { - if *subscribed { - node_clients[i] - .send(ClientRequest::ContractOp(ContractRequest::Get { - key: contract_key, - return_contract_code: false, - subscribe: false, - })) - .await?; - get_state_requests.push(i); - } + for (i, subscribed) in subscribed_nodes.iter().enumerate() { + if *subscribed { + node_clients[i] + .send(ClientRequest::ContractOp(ContractRequest::Get { + key: contract_key, + return_contract_code: false, + subscribe: false, + })) + .await?; + get_state_requests.push(i); } + } - // Also check gateways - let mut gateways_received_update = [false; NUM_GATEWAYS]; - let mut gw_get_state_requests = Vec::new(); - - for (i, subscribed) in subscribed_gateways.iter().enumerate() { - if *subscribed { - gateway_clients[i] - .send(ClientRequest::ContractOp(ContractRequest::Get { - key: contract_key, - return_contract_code: false, - subscribe: false, - })) - .await?; - gw_get_state_requests.push(i); - } - } + // Also check gateways + let mut gateways_received_update = vec![false; num_gateways]; + let mut gw_get_state_requests = Vec::new(); - // Process get state responses with a timeout - let start = std::time::Instant::now(); - let total_timeout = Duration::from_secs(30); + for (i, subscribed) in subscribed_gateways.iter().enumerate() { + if *subscribed { + gateway_clients[i] + .send(ClientRequest::ContractOp(ContractRequest::Get { + key: contract_key, + return_contract_code: false, + subscribe: false, + })) + .await?; + gw_get_state_requests.push(i); + } + } - while !get_state_requests.is_empty() || !gw_get_state_requests.is_empty() { - if start.elapsed() > total_timeout { - tracing::warn!("Timeout waiting for get state responses, finalizing test"); - break; - } + // Process get state responses with a timeout + let start = std::time::Instant::now(); + let total_timeout = Duration::from_secs(30); - // Check regular nodes - let mut i = 0; - while i < get_state_requests.len() { - let node_idx = get_state_requests[i]; - let client = &mut node_clients[node_idx]; - - match timeout(Duration::from_millis(500), client.recv()).await { - Ok(Ok(HostResponse::ContractResponse(ContractResponse::GetResponse { key, state, .. }))) => { - if key == contract_key { - // Deserialize state and check for the update tag - match serde_json::from_slice::(&state) { - Ok(ping_state) => { - let has_update = ping_state.get(&update_tag).is_some(); - tracing::info!("Node {} has update: {}", node_idx, has_update); - - if has_update { - let timestamps = ping_state.get(&update_tag).unwrap(); - tracing::info!("Node {} has {} timestamps for tag {}", - node_idx, - timestamps.len(), - update_tag); - } + while !get_state_requests.is_empty() || !gw_get_state_requests.is_empty() { + if start.elapsed() > total_timeout { + tracing::warn!("Timeout waiting for get state responses, finalizing test"); + break; + } - nodes_received_update[node_idx] = has_update; - } - Err(e) => { - tracing::warn!("Failed to deserialize state from node {}: {}", node_idx, e); + // Check regular nodes + let mut i = 0; + while i < get_state_requests.len() { + let node_idx = get_state_requests[i]; + let client = &mut node_clients[node_idx]; + + match timeout(Duration::from_millis(500), client.recv()).await { + Ok(Ok(HostResponse::ContractResponse(ContractResponse::GetResponse { + key, + state, + .. + }))) => { + if key == contract_key { + // Deserialize state and check for the update tag + match serde_json::from_slice::(&state) { + Ok(ping_state) => { + let has_update = ping_state.get(&update_tag).is_some(); + tracing::info!("Node {} has update: {}", node_idx, has_update); + + if has_update { + let timestamps = ping_state.get(&update_tag).unwrap(); + tracing::info!( + "Node {} has {} timestamps for tag {}", + node_idx, + timestamps.len(), + update_tag + ); } + + nodes_received_update[node_idx] = has_update; + } + Err(e) => { + tracing::warn!( + "Failed to deserialize state from node {}: {}", + node_idx, + e + ); } - get_state_requests.remove(i); - continue; } - } - Ok(Ok(_)) => {}, - Ok(Err(e)) => { - tracing::warn!("Error receiving from node {}: {}", node_idx, e); get_state_requests.remove(i); continue; } - Err(_) => {} } - i += 1; + Ok(Ok(_)) => {} + Ok(Err(e)) => { + tracing::warn!("Error receiving from node {}: {}", node_idx, e); + get_state_requests.remove(i); + continue; + } + Err(_) => {} } + i += 1; + } - // Check gateways - let mut i = 0; - while i < gw_get_state_requests.len() { - let gw_idx = gw_get_state_requests[i]; - let client = &mut gateway_clients[gw_idx]; - - match timeout(Duration::from_millis(500), client.recv()).await { - Ok(Ok(HostResponse::ContractResponse(ContractResponse::GetResponse { key, state, .. }))) => { - if key == contract_key { - // Deserialize state and check for the update tag - match serde_json::from_slice::(&state) { - Ok(ping_state) => { - let has_update = ping_state.get(&update_tag).is_some(); - tracing::info!("Gateway {} has update: {}", gw_idx, has_update); - - if has_update { - let timestamps = ping_state.get(&update_tag).unwrap(); - tracing::info!("Gateway {} has {} timestamps for tag {}", - gw_idx, - timestamps.len(), - update_tag); - } - - gateways_received_update[gw_idx] = has_update; - } - Err(e) => { - tracing::warn!("Failed to deserialize state from gateway {}: {}", gw_idx, e); + // Check gateways + let mut i = 0; + while i < gw_get_state_requests.len() { + let gw_idx = gw_get_state_requests[i]; + let client = &mut gateway_clients[gw_idx]; + + match timeout(Duration::from_millis(500), client.recv()).await { + Ok(Ok(HostResponse::ContractResponse(ContractResponse::GetResponse { + key, + state, + .. + }))) => { + if key == contract_key { + // Deserialize state and check for the update tag + match serde_json::from_slice::(&state) { + Ok(ping_state) => { + let has_update = ping_state.get(&update_tag).is_some(); + tracing::info!("Gateway {} has update: {}", gw_idx, has_update); + + if has_update { + let timestamps = ping_state.get(&update_tag).unwrap(); + tracing::info!( + "Gateway {} has {} timestamps for tag {}", + gw_idx, + timestamps.len(), + update_tag + ); } + + gateways_received_update[gw_idx] = has_update; + } + Err(e) => { + tracing::warn!( + "Failed to deserialize state from gateway {}: {}", + gw_idx, + e + ); } - gw_get_state_requests.remove(i); - continue; } - } - Ok(Ok(_)) => {}, - Ok(Err(e)) => { - tracing::warn!("Error receiving from gateway {}: {}", gw_idx, e); gw_get_state_requests.remove(i); continue; } - Err(_) => {} } - i += 1; + Ok(Ok(_)) => {} + Ok(Err(e)) => { + tracing::warn!("Error receiving from gateway {}: {}", gw_idx, e); + gw_get_state_requests.remove(i); + continue; + } + Err(_) => {} } - - tokio::time::sleep(Duration::from_millis(100)).await; + i += 1; } - // Analyze update propagation results - tracing::info!("Final update propagation results:"); - - // Summary for gateways - let subscribed_gw_count = subscribed_gateways.iter().filter(|&&x| x).count(); - let updated_gw_count = gateways_received_update.iter().filter(|&&x| x).count(); - - tracing::info!("Gateways: {}/{} subscribed received the update ({:.1}%)", - updated_gw_count, - subscribed_gw_count, - if subscribed_gw_count > 0 { - (updated_gw_count as f64 / subscribed_gw_count as f64) * 100.0 - } else { - 0.0 - }); - - // Summary for regular nodes - let subscribed_node_count = subscribed_nodes.iter().filter(|&&x| x).count(); - let updated_node_count = nodes_received_update.iter().filter(|&&x| x).count(); - - tracing::info!("Regular nodes: {}/{} subscribed received the update ({:.1}%)", - updated_node_count, - subscribed_node_count, - if subscribed_node_count > 0 { - (updated_node_count as f64 / subscribed_node_count as f64) * 100.0 - } else { - 0.0 - }); - - // Check nodes that didn't receive updates - for (node_idx, (subscribed, updated)) in subscribed_nodes.iter().zip(nodes_received_update.iter()).enumerate() { - if *subscribed && !updated { - tracing::warn!("Node {} was subscribed but did not receive the update!", node_idx); - - // Get the node connectivity info - let connections = node_connections[node_idx]; - tracing::warn!("Node {} is connected to {} other regular nodes", node_idx, connections); - } - } + tokio::time::sleep(Duration::from_millis(100)).await; + } - // Verify that updates have propagated to at least some nodes - assert!( - updated_node_count > 0, - "No nodes received the update, subscription propagation failed" - ); + // Analyze update propagation results + tracing::info!("Final update propagation results:"); - // Verify that if we have multiple gateways, at least some received the update - if NUM_GATEWAYS > 1 && subscribed_gw_count > 1 { - assert!( - updated_gw_count > 0, - "No gateways received the update, gateway subscription propagation failed" - ); + // Summary for gateways + let subscribed_gw_count = subscribed_gateways.iter().filter(|&&x| x).count(); + let updated_gw_count = gateways_received_update.iter().filter(|&&x| x).count(); + + tracing::info!( + "Gateways: {}/{} subscribed received the update ({:.1}%)", + updated_gw_count, + subscribed_gw_count, + if subscribed_gw_count > 0 { + (updated_gw_count as f64 / subscribed_gw_count as f64) * 100.0 + } else { + 0.0 } + ); - // Calculate and assert a minimum expected update propagation rate - let min_expected_rate = 0.5; // At least 50% of subscribed nodes should get updates + // Summary for regular nodes + let subscribed_node_count = subscribed_nodes.iter().filter(|&&x| x).count(); + let updated_node_count = nodes_received_update.iter().filter(|&&x| x).count(); - let actual_rate = if subscribed_node_count > 0 { - updated_node_count as f64 / subscribed_node_count as f64 + tracing::info!( + "Regular nodes: {}/{} subscribed received the update ({:.1}%)", + updated_node_count, + subscribed_node_count, + if subscribed_node_count > 0 { + (updated_node_count as f64 / subscribed_node_count as f64) * 100.0 } else { 0.0 - }; + } + ); + // Check nodes that didn't receive updates + for (node_idx, (subscribed, updated)) in subscribed_nodes + .iter() + .zip(nodes_received_update.iter()) + .enumerate() + { + if *subscribed && !updated { + tracing::warn!( + "Node {} was subscribed but did not receive the update!", + node_idx + ); + } + } + + // Verify that updates have propagated to at least some nodes + assert!( + updated_node_count > 0, + "No nodes received the update, subscription propagation failed" + ); + + // Verify that if we have multiple gateways, at least some received the update + if num_gateways > 1 && subscribed_gw_count > 1 { assert!( - actual_rate >= min_expected_rate, - "Update propagation rate too low: {:.1}% (expected at least {:.1}%)", - actual_rate * 100.0, - min_expected_rate * 100.0 + updated_gw_count > 0, + "No gateways received the update, gateway subscription propagation failed" ); + } - tracing::info!("Subscription propagation test completed successfully!"); - - Ok::<_, anyhow::Error>(()) - }) - .instrument(span!(Level::INFO, "test_ping_partially_connected_network")); + // Calculate and assert a minimum expected update propagation rate + let min_expected_rate = 0.5; // At least 50% of subscribed nodes should get updates - // Wait for test completion or node failures - select! { - (r, _remaining) = &mut gateway_monitor => { - if let Some(r) = r { - match r { - Err(err) => return Err(anyhow!("Gateway node failed: {}", err).into()), - Ok(_) => panic!("Gateway node unexpectedly terminated successfully"), - } - } - } - (r, _remaining) = &mut regular_node_monitor => { - if let Some(r) = r { - match r { - Err(err) => return Err(anyhow!("Regular node failed: {}", err).into()), - Ok(_) => panic!("Regular node unexpectedly terminated successfully"), - } - } - } - r = test => { - r??; - } - } + let actual_rate = if subscribed_node_count > 0 { + updated_node_count as f64 / subscribed_node_count as f64 + } else { + 0.0 + }; - // Keep presets alive until here - tracing::debug!( - "Test complete, dropping {} gateway presets and {} node presets", - gateway_presets.len(), - node_presets.len() + assert!( + actual_rate >= min_expected_rate, + "Update propagation rate too low: {:.1}% (expected at least {:.1}%)", + actual_rate * 100.0, + min_expected_rate * 100.0 ); + tracing::info!("Subscription propagation test completed successfully!"); + Ok(()) } diff --git a/crates/core/tests/connectivity.rs b/crates/core/tests/connectivity.rs index bbd99a71f..0fa2f1d4d 100644 --- a/crates/core/tests/connectivity.rs +++ b/crates/core/tests/connectivity.rs @@ -18,7 +18,6 @@ use tokio_tungstenite::connect_async; /// connecting to the gateway. #[freenet_test( nodes = ["gateway", "peer"], - auto_connect_peers = true, timeout_secs = 180, startup_wait_secs = 15, aggregate_events = "always", @@ -251,7 +250,6 @@ async fn test_basic_gateway_connectivity(ctx: &mut TestContext) -> TestResult { /// #[freenet_test( nodes = ["gateway", "peer1", "peer2"], - auto_connect_peers = true, timeout_secs = 180, startup_wait_secs = 30, aggregate_events = "always", diff --git a/crates/core/tests/operations.rs b/crates/core/tests/operations.rs index d97966173..a68bbb4cd 100644 --- a/crates/core/tests/operations.rs +++ b/crates/core/tests/operations.rs @@ -234,7 +234,6 @@ async fn send_put_with_retry( /// Test PUT operation across two peers (gateway and peer) #[freenet_test( nodes = ["gateway", "peer-a"], - auto_connect_peers = true, timeout_secs = 180, startup_wait_secs = 15, tokio_flavor = "multi_thread", @@ -342,7 +341,6 @@ async fn test_put_contract(ctx: &mut TestContext) -> TestResult { #[freenet_test( nodes = ["gateway", "peer-a"], - auto_connect_peers = true, timeout_secs = 180, startup_wait_secs = 20, tokio_flavor = "multi_thread", @@ -513,7 +511,6 @@ async fn test_update_contract(ctx: &mut TestContext) -> TestResult { /// This is a regression test for issue #1995. #[freenet_test( nodes = ["gateway", "peer-a"], - auto_connect_peers = true, timeout_secs = 180, startup_wait_secs = 15, tokio_flavor = "multi_thread", @@ -664,7 +661,6 @@ async fn test_put_merge_persists_state(ctx: &mut TestContext) -> TestResult { #[ignore] #[freenet_test( nodes = ["gateway", "node-a", "node-b"], - auto_connect_peers = true, timeout_secs = 600, startup_wait_secs = 40, tokio_flavor = "multi_thread", @@ -1238,7 +1234,6 @@ async fn test_multiple_clients_subscription(ctx: &mut TestContext) -> TestResult #[freenet_test( nodes = ["gateway", "node-a"], - auto_connect_peers = true, timeout_secs = 120, startup_wait_secs = 20, tokio_flavor = "multi_thread", @@ -1466,7 +1461,6 @@ async fn test_get_with_subscribe_flag(ctx: &mut TestContext) -> TestResult { // FIXME Update notification is not received #[freenet_test( nodes = ["gateway", "node-a"], - auto_connect_peers = true, timeout_secs = 180, startup_wait_secs = 20, tokio_flavor = "multi_thread", @@ -1756,7 +1750,6 @@ async fn test_put_with_subscribe_flag(ctx: &mut TestContext) -> TestResult { #[freenet_test( nodes = ["gateway", "client-node"], - auto_connect_peers = true, timeout_secs = 180, startup_wait_secs = 20, tokio_flavor = "multi_thread", @@ -2553,7 +2546,6 @@ async fn wait_for_subscribe_response( #[freenet_test( nodes = ["gateway", "peer-node"], - auto_connect_peers = true, timeout_secs = 180, startup_wait_secs = 10, tokio_flavor = "multi_thread", @@ -2627,7 +2619,6 @@ async fn test_subscription_introspection(ctx: &mut TestContext) -> TestResult { #[freenet_test( nodes = ["gateway", "peer-a"], - auto_connect_peers = true, timeout_secs = 180, startup_wait_secs = 20, tokio_flavor = "multi_thread", diff --git a/crates/core/tests/test_macro_example.rs b/crates/core/tests/test_macro_example.rs index 8d81c4336..707014061 100644 --- a/crates/core/tests/test_macro_example.rs +++ b/crates/core/tests/test_macro_example.rs @@ -212,7 +212,6 @@ async fn test_multiple_gateways(ctx: &mut TestContext) -> TestResult { /// Test with auto_connect_peers enabled #[freenet_test( nodes = ["gateway", "peer-1", "peer-2"], - auto_connect_peers = true, timeout_secs = 120, startup_wait_secs = 15 )] @@ -242,7 +241,6 @@ async fn test_auto_connect_peers(ctx: &mut TestContext) -> TestResult { #[freenet_test( nodes = ["gw-1", "gw-2", "peer-1", "peer-2"], gateways = ["gw-1", "gw-2"], - auto_connect_peers = true, timeout_secs = 120, startup_wait_secs = 15 )] diff --git a/crates/core/tests/test_network_integration.rs b/crates/core/tests/test_network_integration.rs index f433ec932..cf0324823 100644 --- a/crates/core/tests/test_network_integration.rs +++ b/crates/core/tests/test_network_integration.rs @@ -7,24 +7,16 @@ use freenet_test_network::TestNetwork; use testresult::TestResult; use tokio_tungstenite::connect_async; -// Helper to get or create network -async fn get_network() -> &'static TestNetwork { - use tokio::sync::OnceCell; - static NETWORK: OnceCell = OnceCell::const_new(); - - NETWORK - .get_or_init(|| async { - TestNetwork::builder() - .gateways(1) - .peers(2) - .binary(freenet_test_network::FreenetBinary::CurrentCrate( - freenet_test_network::BuildProfile::Debug, - )) - .build() - .await - .expect("Failed to start test network") - }) +async fn get_network() -> TestNetwork { + TestNetwork::builder() + .gateways(1) + .peers(2) + .binary(freenet_test_network::FreenetBinary::CurrentCrate( + freenet_test_network::BuildProfile::Debug, + )) + .build() .await + .expect("Failed to start test network") } #[tokio::test] diff --git a/crates/freenet-macros/README.md b/crates/freenet-macros/README.md index 9e81de254..dc9cca3c3 100644 --- a/crates/freenet-macros/README.md +++ b/crates/freenet-macros/README.md @@ -29,19 +29,18 @@ async fn test_basic_gateway(ctx: &mut TestContext) -> TestResult { } ``` -### Multi-Node Test with Auto-Connect +### Multi-Node Test ```rust #[freenet_test( nodes = ["gateway", "peer-1", "peer-2"], - auto_connect_peers = true, aggregate_events = "on_failure" )] async fn test_network_operations(ctx: &mut TestContext) -> TestResult { let gateway = ctx.gateway()?; let peers = ctx.peers(); - // All peers are automatically configured to connect to the gateway + // Peers are automatically configured to connect to the gateway (default behavior) assert_eq!(peers.len(), 2); // Your test logic here... @@ -147,16 +146,22 @@ async fn test_with_node_configs(ctx: &mut TestContext) -> TestResult { #### `auto_connect_peers` Automatically configure all peer nodes to connect to all gateway nodes. +**Default:** `true` + ```rust +// Default behavior - peers auto-connect +#[freenet_test(nodes = ["gateway", "peer-1", "peer-2"])] + +// Explicitly disable auto-connection if needed #[freenet_test( nodes = ["gateway", "peer-1", "peer-2"], - auto_connect_peers = true // Peers auto-connect to gateway + auto_connect_peers = false )] ``` **Behavior:** -- When `true`: Peers are pre-configured with gateway connection info -- When `false` (default): You must manually configure peer connections +- When `true` (default): Peers are pre-configured with gateway connection info +- When `false`: You must manually configure peer connections - Works with multiple gateways (peers connect to all gateways) #### `aggregate_events` @@ -267,6 +272,32 @@ Logging level for the test. **Values:** `"trace"`, `"debug"`, `"info"`, `"warn"`, `"error"` +#### `peer_connectivity_ratio` +Controls the connectivity ratio between peer nodes (0.0-1.0) for testing partially connected networks. + +```rust +#[freenet_test( + nodes = ["gw-0", "gw-1", "node-0", "node-1", "node-2", "node-3"], + gateways = ["gw-0", "gw-1"], + auto_connect_peers = true, // Peers connect to all gateways + peer_connectivity_ratio = 0.5 // 50% connectivity between peers +)] +``` + +**How it works:** +- A ratio of `1.0` means full connectivity between all peers +- A ratio of `0.5` means approximately 50% of peer-to-peer connections are blocked +- A ratio of `0.0` means no direct peer-to-peer connections (only via gateways) +- The blocking pattern is deterministic based on node indices +- Gateway connectivity is not affected - this only controls peer-to-peer connections + +**Use cases:** +- Testing subscription propagation in partially connected networks +- Simulating network partitions or unreliable peer connections +- Verifying that updates propagate through gateways when direct peer routes are unavailable + +**Note:** When this is set, `auto_connect_peers` should typically be `true` to ensure peers can reach gateways. + ## TestContext API The macro provides a `TestContext` parameter to your test function with these methods: @@ -324,7 +355,7 @@ use freenet_stdlib::prelude::*; #[freenet_test( nodes = ["gateway", "peer-1", "peer-2"], - auto_connect_peers = true, + timeout_secs = 180, startup_wait_secs = 15, aggregate_events = "on_failure", @@ -474,7 +505,7 @@ EVENT LOG SUMMARY #[freenet_test( nodes = ["gw-1", "gw-2", "peer-1", "peer-2", "peer-3", "peer-4"], gateways = ["gw-1", "gw-2"], - auto_connect_peers = true, + startup_wait_secs = 20 // More time for connections to establish )] ``` diff --git a/crates/freenet-macros/src/codegen.rs b/crates/freenet-macros/src/codegen.rs index d41158940..93efbc185 100644 --- a/crates/freenet-macros/src/codegen.rs +++ b/crates/freenet-macros/src/codegen.rs @@ -135,15 +135,13 @@ pub fn generate_test_code(args: FreenetTestArgs, input_fn: ItemFn) -> Result freenet::test_utils::TestResult { use freenet::test_utils::{TestContext, TestLogger, NodeInfo}; use std::time::{Duration, Instant}; - use tokio::select; use anyhow::anyhow; // 1. Setup TestLogger - let mut __test_logger = TestLogger::new().with_json().with_level(#log_level); - if std::env::var_os("FREENET_TEST_LOG_DISABLE_JSON").is_some() { - __test_logger = __test_logger.with_pretty(); - } - let _logger = __test_logger.init(); + let _logger = TestLogger::new() + .with_json() + .with_level(#log_level) + .init(); tracing::info!("Starting test: {}", stringify!(#test_fn_name)); @@ -160,21 +158,22 @@ pub fn generate_test_code(args: FreenetTestArgs, input_fn: ItemFn) -> Result TokenStream { key.save(&transport_keypair)?; key.public().save(temp_dir.path().join("public.pem"))?; - let network_port = freenet::test_utils::reserve_local_port()?; - let ws_port = freenet::test_utils::reserve_local_port()?; + let network_socket = std::net::TcpListener::bind("127.0.0.1:0")?; + let ws_socket = std::net::TcpListener::bind("127.0.0.1:0")?; + let network_port = network_socket.local_addr()?.port(); + let ws_port = ws_socket.local_addr()?.port(); + + std::mem::drop(network_socket); + std::mem::drop(ws_socket); let location: f64 = #location_expr; @@ -267,6 +271,35 @@ fn generate_node_setup(args: &FreenetTestArgs) -> TokenStream { } } + // Pre-compute peer network ports if we need partial connectivity + let peer_network_ports_setup = if args.peer_connectivity_ratio.is_some() { + let peer_indices: Vec<_> = args + .nodes + .iter() + .enumerate() + .filter(|(idx, node_label)| !is_gateway(args, node_label, *idx)) + .map(|(idx, _)| idx) + .collect(); + + let peer_port_vars: Vec<_> = peer_indices + .iter() + .map(|idx| format_ident!("peer_network_port_{}", idx)) + .collect(); + + quote! { + // Pre-bind sockets for all peers to get their network ports + #( + let peer_socket = std::net::TcpListener::bind("127.0.0.1:0")?; + let #peer_port_vars = peer_socket.local_addr()?.port(); + std::mem::drop(peer_socket); + )* + } + } else { + quote! {} + }; + + setup_code.push(peer_network_ports_setup); + // Third pass: Generate peer configurations (non-gateway nodes) for (idx, node_label) in args.nodes.iter().enumerate() { let config_var = format_ident!("config_{}", idx); @@ -308,6 +341,61 @@ fn generate_node_setup(args: &FreenetTestArgs) -> TokenStream { } }; + // Compute blocked addresses for this peer if partial connectivity is enabled + let blocked_addresses_code = if let Some(ratio) = args.peer_connectivity_ratio { + // Build mapping from node index to peer index (for deterministic blocking) + let peer_indices: Vec<(usize, usize)> = args + .nodes + .iter() + .enumerate() + .filter(|(node_idx, label)| !is_gateway(args, label, *node_idx)) + .enumerate() + .map(|(peer_idx, (node_idx, _))| (node_idx, peer_idx)) + .collect(); + + // Find this peer's relative index + let this_peer_idx = peer_indices + .iter() + .find(|(node_idx, _)| *node_idx == idx) + .map(|(_, peer_idx)| *peer_idx) + .expect("Current node must be in peer list"); + + let peer_checks: Vec<_> = args + .nodes + .iter() + .enumerate() + .filter(|(other_idx, other_label)| !is_gateway(args, other_label, *other_idx) && *other_idx != idx) + .map(|(other_idx, _)| { + // Find the other peer's relative index + let other_peer_idx = peer_indices.iter() + .find(|(node_idx, _)| *node_idx == other_idx) + .map(|(_, peer_idx)| *peer_idx) + .expect("Other node must be in peer list"); + + let port_var = format_ident!("peer_network_port_{}", other_idx); + quote! { + // Use ordered pair and better hash distribution for deterministic connectivity + // Use relative peer indices (not absolute node indices) for consistent blocking + let (a, b) = if #this_peer_idx < #other_peer_idx { (#this_peer_idx, #other_peer_idx) } else { (#other_peer_idx, #this_peer_idx) }; + let hash_value = (a * 17 + b * 31 + a * b * 7) % 100; + if hash_value >= (#ratio * 100.0) as usize { + blocked_addresses.push(std::net::SocketAddr::from((std::net::Ipv4Addr::LOCALHOST, #port_var))); + } + } + }) + .collect(); + + quote! { + let mut blocked_addresses = Vec::new(); + #(#peer_checks)* + let blocked_addresses = Some(blocked_addresses); + } + } else { + quote! { + let blocked_addresses = None; + } + }; + // Peer node configuration setup_code.push(quote! { let (#config_var, #temp_var) = { @@ -317,11 +405,18 @@ fn generate_node_setup(args: &FreenetTestArgs) -> TokenStream { key.save(&transport_keypair)?; key.public().save(temp_dir.path().join("public.pem"))?; - let network_port = freenet::test_utils::reserve_local_port()?; - let ws_port = freenet::test_utils::reserve_local_port()?; + let network_socket = std::net::TcpListener::bind("127.0.0.1:0")?; + let network_port = network_socket.local_addr()?.port(); + std::mem::drop(network_socket); + + let ws_socket = std::net::TcpListener::bind("127.0.0.1:0")?; + let ws_port = ws_socket.local_addr()?.port(); + std::mem::drop(ws_socket); let location: f64 = #location_expr; + #blocked_addresses_code + let config = freenet::config::ConfigArgs { ws_api: freenet::config::WebsocketApiArgs { address: Some(std::net::Ipv4Addr::LOCALHOST.into()), @@ -340,7 +435,7 @@ fn generate_node_setup(args: &FreenetTestArgs) -> TokenStream { address: Some(std::net::Ipv4Addr::LOCALHOST.into()), network_port: Some(network_port), bandwidth_limit: None, - blocked_addresses: None, + blocked_addresses, transient_budget: None, transient_ttl_secs: None, }, @@ -414,27 +509,18 @@ fn generate_node_builds(args: &FreenetTestArgs) -> TokenStream { fn generate_node_tasks(args: &FreenetTestArgs) -> TokenStream { let mut tasks = Vec::new(); - for (idx, node_label) in args.nodes.iter().enumerate() { + for (idx, _node_label) in args.nodes.iter().enumerate() { let task_var = format_ident!("node_task_{}", idx); let node_var = format_ident!("node_{}", idx); tasks.push(quote! { - let #task_var = { - let node = #node_var; - async move { - tracing::info!("Node running: {}", #node_label); - node.run().await - } - .instrument(tracing::info_span!("test_peer", test_node = #node_label)) - .boxed_local() - }; + let #task_var = tokio::task::spawn_local(#node_var.run()); + // Small delay to ensure proper task startup ordering + tokio::time::sleep(tokio::time::Duration::from_millis(10)).await; }); } quote! { - use futures::FutureExt; - use tracing::Instrument; - #(#tasks)* } } @@ -498,45 +584,24 @@ fn generate_context_creation_with_handles(args: &FreenetTestArgs) -> TokenStream } } -/// Generate test coordination code with select! +/// Generate test coordination code with spawned tasks fn generate_test_coordination(args: &FreenetTestArgs, inner_fn_name: &syn::Ident) -> TokenStream { let timeout_secs = args.timeout_secs; let startup_wait_secs = args.startup_wait_secs; - // Generate select! arms for each node - let mut select_arms = Vec::new(); - for (idx, node_label) in args.nodes.iter().enumerate() { - let task_var = format_ident!("node_task_{}", idx); - select_arms.push(quote! { - result = #task_var => { - Err(anyhow!("Node '{}' exited unexpectedly: {:?}", #node_label, result)) - } - }); - } - - // Add test arm - select_arms.push(quote! { - result = test_future => { - match result { - Ok(Ok(val)) => { - // Give event loggers time to flush their batches - // The EventRegister is cloned multiple times, so all senders need to be dropped - // before the record_logs task will exit and flush remaining events - tokio::time::sleep(Duration::from_secs(5)).await; - Ok(val) - }, - Ok(Err(e)) => { - // Also flush on error - tokio::time::sleep(Duration::from_secs(5)).await; - Err(e) - }, - Err(_) => Err(anyhow!("Test timed out after {} seconds", #timeout_secs)), - } - } - }); + // Collect all node task variables + let task_vars: Vec<_> = (0..args.nodes.len()) + .map(|idx| format_ident!("node_task_{}", idx)) + .collect(); + let node_labels = &args.nodes; quote! { - let test_future = tokio::time::timeout( + // Store node handles for monitoring (optional) + let _node_handles = vec![#(#task_vars),*]; + let _node_labels = vec![#(#node_labels),*]; + + // Run test with timeout + let test_result = tokio::time::timeout( Duration::from_secs(#timeout_secs), async { // Wait for nodes to start @@ -547,10 +612,21 @@ fn generate_test_coordination(args: &FreenetTestArgs, inner_fn_name: &syn::Ident // Run user's test #inner_fn_name(&mut ctx).await } - ); - - select! { - #(#select_arms),* + ).await; + + // Check test result + match test_result { + Ok(Ok(val)) => { + // Give event loggers time to flush their batches + tokio::time::sleep(Duration::from_secs(5)).await; + Ok(val) + }, + Ok(Err(e)) => { + // Also flush on error + tokio::time::sleep(Duration::from_secs(5)).await; + Err(e) + }, + Err(_) => Err(anyhow!("Test timed out after {} seconds", #timeout_secs)), } } } diff --git a/crates/freenet-macros/src/lib.rs b/crates/freenet-macros/src/lib.rs index 988b3c38e..94a68ed9e 100644 --- a/crates/freenet-macros/src/lib.rs +++ b/crates/freenet-macros/src/lib.rs @@ -86,15 +86,14 @@ use parser::FreenetTestArgs; /// } /// ``` /// -/// ## Auto-Connect Peers to Gateways +/// ## Auto-Connect Peers to Gateways (Default Behavior) /// ```ignore /// #[freenet_test( /// nodes = ["gateway", "peer-1", "peer-2"], -/// auto_connect_peers = true, // Peers will connect to gateway /// timeout_secs = 120 /// )] /// async fn test_with_connections(ctx: &mut TestContext) -> TestResult { -/// // Peers are configured to discover and connect to the gateway +/// // Peers are automatically configured to connect to the gateway (default: auto_connect_peers = true) /// let gateway = ctx.gateway()?; /// let peers = ctx.peers(); /// // Test peer-gateway interactions... diff --git a/crates/freenet-macros/src/parser.rs b/crates/freenet-macros/src/parser.rs index e16ba5183..3c207566c 100644 --- a/crates/freenet-macros/src/parser.rs +++ b/crates/freenet-macros/src/parser.rs @@ -29,6 +29,8 @@ pub struct FreenetTestArgs { pub tokio_flavor: TokioFlavor, /// Tokio worker threads pub tokio_worker_threads: Option, + /// Connectivity ratio between peers (0.0-1.0), controlling partial connectivity + pub peer_connectivity_ratio: Option, } #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -50,14 +52,19 @@ impl syn::parse::Parse for FreenetTestArgs { let mut gateways = None; let mut node_locations = None; let mut node_locations_fn = None; - let mut auto_connect_peers = false; + let mut auto_connect_peers = true; let mut timeout_secs = 180; let mut startup_wait_secs = 15; let mut aggregate_events = AggregateEventsMode::OnFailure; - let mut log_level = "freenet=debug,info".to_string(); + // Default log level: freenet=debug for general debugging, + // transport=warn to reduce keep-alive/connection noise, + // p2p_protoc=info to reduce connection timeout spam, + // info as global default + let mut log_level = "freenet=debug,freenet_core::transport=warn,freenet::node::network_bridge::p2p_protoc=info,info".to_string(); let mut tokio_flavor = TokioFlavor::CurrentThread; let mut tokio_worker_threads = None; let mut node_configs = HashMap::new(); + let mut peer_connectivity_ratio = None; // Parse key-value pairs while !input.is_empty() { @@ -259,6 +266,17 @@ impl syn::parse::Parse for FreenetTestArgs { let lit: syn::LitBool = input.parse()?; auto_connect_peers = lit.value; } + "peer_connectivity_ratio" => { + let lit: syn::LitFloat = input.parse()?; + let ratio: f64 = lit.base10_parse()?; + if !(0.0..=1.0).contains(&ratio) { + return Err(syn::Error::new( + lit.span(), + "peer_connectivity_ratio must be between 0.0 and 1.0", + )); + } + peer_connectivity_ratio = Some(ratio); + } _ => { return Err(syn::Error::new( key.span(), @@ -340,6 +358,7 @@ impl syn::parse::Parse for FreenetTestArgs { log_level, tokio_flavor, tokio_worker_threads, + peer_connectivity_ratio, }) } } @@ -357,9 +376,11 @@ mod tests { let args: FreenetTestArgs = syn::parse2(tokens).unwrap(); assert_eq!(args.nodes, vec!["gateway", "peer-1"]); + assert!(args.auto_connect_peers); // Verify default is true assert_eq!(args.timeout_secs, 180); assert_eq!(args.startup_wait_secs, 15); assert_eq!(args.aggregate_events, AggregateEventsMode::OnFailure); + assert_eq!(args.log_level, "freenet=debug,freenet_core::transport=warn,freenet::node::network_bridge::p2p_protoc=info,info"); } #[test] @@ -400,6 +421,30 @@ mod tests { let result: Result = syn::parse2(tokens); assert!(result.is_err()); } + + #[test] + fn test_auto_connect_peers_explicit_false() { + let tokens = quote! { + nodes = ["gateway", "peer-1"], + auto_connect_peers = false + }; + + let args: FreenetTestArgs = syn::parse2(tokens).unwrap(); + assert_eq!(args.nodes, vec!["gateway", "peer-1"]); + assert!(!args.auto_connect_peers); // Verify explicit false works + } + + #[test] + fn test_auto_connect_peers_explicit_true() { + let tokens = quote! { + nodes = ["gateway", "peer-1"], + auto_connect_peers = true + }; + + let args: FreenetTestArgs = syn::parse2(tokens).unwrap(); + assert_eq!(args.nodes, vec!["gateway", "peer-1"]); + assert!(args.auto_connect_peers); + } } #[derive(Debug, Clone, Default)] pub struct NodeConfigOverride { diff --git a/docs/debugging/testing-logging-guide.md b/docs/debugging/testing-logging-guide.md index 8367c4dde..5bbc0757e 100644 --- a/docs/debugging/testing-logging-guide.md +++ b/docs/debugging/testing-logging-guide.md @@ -72,7 +72,6 @@ use freenet_macros::freenet_test; #[freenet_test( nodes = ["gateway", "peer-1", "peer-2"], - auto_connect_peers = true, aggregate_events = "on_failure" // Automatic event aggregation! )] async fn test_network_operation(ctx: &mut TestContext) -> TestResult { @@ -156,7 +155,6 @@ async fn test_gateway_starts(ctx: &mut TestContext) -> TestResult { ```rust #[freenet_test( nodes = ["gateway", "peer-1", "peer-2"], - auto_connect_peers = true, timeout_secs = 180, startup_wait_secs = 15 )]