From c1acef9bc8321b56a08f1306d0d28a05a6867fcf Mon Sep 17 00:00:00 2001 From: Drazen Urch Date: Tue, 24 Jun 2025 21:28:07 +0200 Subject: [PATCH] Check gateway supported versions (#5860) * Check gateway supported versions * Fix boxed errors * Fmt * feat(client-core): integrate gateway protocol validation into SDK Enable protocol version checking for all SDK-based clients by using gateways_for_init_with_protocol_validation in MixnetClientBuilder. This ensures clients only connect to gateways with compatible protocol versions, preventing potential communication issues. - Replace gateways_for_init with gateways_for_init_with_protocol_validation - Add import for the new validation function - Protocol validation now active for network monitor and all SDK users * refactor(client-core): allow gateways with newer protocol versions Change protocol validation to be more permissive - instead of rejecting gateways with newer protocol versions, now logs a warning and continues. This enables graceful degradation when gateways upgrade, relying on their backward compatibility while signaling users to update their clients. Changes: - Accept gateways with protocol version > client version - Log warning about version mismatch suggesting client update - Update log messages from "validation" to "check" for clarity - Add trace logging showing both gateway and client versions This prevents connectivity issues when gateways upgrade before clients, improving overall network resilience. * feat(nym-network-monitor): add diagnostic logging for ConnectionRefused debugging - Add detailed logging for client rotation lifecycle with [CLIENT_ROTATION_*] tags - Add request tracking with unique IDs using the random message as identifier - Add HTTP connection acceptance logging with [HTTP_REQUEST] tags - Improve locust script with connection error handling and backoff strategy - Add TCP backlog configuration support (default 1024) - Add socket configuration with SO_REUSEADDR and configurable backlog - Add HTTP timeout and tracing layers for better observability These changes help diagnose when and why ConnectionRefused errors occur during load testing, particularly around client rotation periods. * fix(nym-api): calculate route average reliability as node mean instead of route-based - Changed route average reliability calculation to use mean of all node reliabilities - Added median calculation alongside mean for better statistical representation - Fixed null average reliability for old method which doesn't analyze routes - Rounded all float values to 2 decimal places in API responses for cleaner display - Store median values in analysis_parameters JSON field --- Cargo.lock | 782 +++++++++++---------- common/client-core/src/error.rs | 3 + common/client-core/src/init/helpers.rs | 184 +++++ nym-api/src/epoch_operations/simulation.rs | 79 ++- nym-api/src/simulation_api/handlers/mod.rs | 32 +- nym-api/src/simulation_api/models.rs | 22 +- nym-network-monitor/Cargo.toml | 4 + nym-network-monitor/locustfile.py | 18 +- nym-network-monitor/src/handlers.rs | 10 +- nym-network-monitor/src/http.rs | 51 +- nym-network-monitor/src/main.rs | 30 +- sdk/rust/nym-sdk/src/mixnet/client.rs | 4 +- 12 files changed, 780 insertions(+), 439 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fb3c22f5e4..7743805484 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11,7 +11,7 @@ dependencies = [ "macroific", "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -35,9 +35,9 @@ dependencies = [ [[package]] name = "adler2" -version = "2.0.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" [[package]] name = "aead" @@ -168,9 +168,9 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" [[package]] name = "anstream" -version = "0.6.18" +version = "0.6.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" +checksum = "301af1932e46185686725e0fad2f8f2aa7da69dd70bf6ecc44d6b703844a3933" dependencies = [ "anstyle", "anstyle-parse", @@ -183,33 +183,33 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" +checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" [[package]] name = "anstyle-parse" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" +checksum = "6c8bdeb6047d8983be085bab0ba1472e6dc604e7041dbf6fcd5e71523014fae9" dependencies = [ "windows-sys 0.59.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.8" +version = "3.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6680de5231bd6ee4c6191b8a1325daa282b415391ec9d3a37bd34f2060dc73fa" +checksum = "403f75924867bb1033c59fbf0797484329750cfbe3c4325cd33127941fabc882" dependencies = [ "anstyle", "once_cell_polyfill", @@ -409,7 +409,7 @@ dependencies = [ "rustc-hash", "serde", "serde_derive", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -447,9 +447,9 @@ dependencies = [ [[package]] name = "async-compression" -version = "0.4.23" +version = "0.4.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b37fc50485c4f3f736a4fb14199f6d5f5ba008d7f28fe710306c92780f004c07" +checksum = "40f6024f3f856663b45fd0c9b6f2024034a702f453549449e0d84a305900dad4" dependencies = [ "brotli", "flate2", @@ -491,7 +491,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -502,7 +502,7 @@ checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -545,9 +545,9 @@ checksum = "3c1e7e457ea78e524f48639f551fd79703ac3f2237f5ecccdf4708f8a75ad373" [[package]] name = "autocfg" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "autodoc" @@ -701,7 +701,7 @@ checksum = "57d123550fa8d071b7255cb0cc04dc302baa6c8c4a79f55701552684d8399bce" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -775,9 +775,9 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "base64ct" -version = "1.7.3" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89e25b6adfb930f02d1981565a6e5d9c547ac15a96606256d3b59040e5cd4ca3" +checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba" [[package]] name = "base85rs" @@ -828,9 +828,9 @@ dependencies = [ [[package]] name = "bip39" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33415e24172c1b7d6066f6d999545375ab8e1d95421d6784bdfff9496f292387" +checksum = "43d193de1f7487df1914d3a568b772458861d33f9c54249612cc2893d6915054" dependencies = [ "bitcoin_hashes", "rand 0.8.5", @@ -1010,9 +1010,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.17.0" +version = "3.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" [[package]] name = "byte-tools" @@ -1053,9 +1053,9 @@ checksum = "2e93abca9e28e0a1b9877922aacb20576e05d4679ffa78c3d6dc22a26a216659" [[package]] name = "camino" -version = "1.1.9" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b96ec4966b5813e2c0507c1f86115c8c5abaadc3980879c3424042a02fd1ad3" +checksum = "0da45bc31171d8d6960122e222a67740df867c1dd53b4d51caa297084c185cab" dependencies = [ "serde", ] @@ -1111,9 +1111,9 @@ checksum = "a2698f953def977c68f935bb0dfa959375ad4638570e969e2f1e9f433cbf1af6" [[package]] name = "cc" -version = "1.2.24" +version = "1.2.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16595d3be041c03b09d08d0858631facccee9221e579704070e6e9e4915d3bc7" +checksum = "d487aa071b5f64da6f19a3e848e3578944b726ee5a4854b82172f02aa876bfdc" dependencies = [ "jobserver", "libc", @@ -1132,9 +1132,9 @@ dependencies = [ [[package]] name = "cfg-if" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" [[package]] name = "cfg_aliases" @@ -1240,9 +1240,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.38" +version = "4.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed93b9805f8ba930df42c2590f05453d5ec36cbb85d018868a5b24d31f6ac000" +checksum = "40b6887a1d8685cebccf115538db5c0efe625ccac9696ad45c409d96566e910f" dependencies = [ "clap_builder", "clap_derive", @@ -1250,9 +1250,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.38" +version = "4.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "379026ff283facf611b0ea629334361c4211d1b12ee01024eec1591133b04120" +checksum = "e0c66c08ce9f0c698cbce5c0279d0bb6ac936d8674174fe48f736533b964f59e" dependencies = [ "anstream", "anstyle", @@ -1262,9 +1262,9 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.5.50" +version = "4.5.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c91d3baa3bcd889d60e6ef28874126a0b384fd225ab83aa6d8a801c519194ce1" +checksum = "aad5b1b4de04fead402672b48897030eec1f3bfe1550776322f59f6d6e6a5677" dependencies = [ "clap", ] @@ -1281,27 +1281,27 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.32" +version = "4.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7" +checksum = "d2c7947ae4cc3d851207c1adb5b5e260ff0cca11446b1d6d1423788e442257ce" dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] name = "clap_lex" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" +checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" [[package]] name = "colorchoice" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" [[package]] name = "colored" @@ -1321,7 +1321,7 @@ checksum = "4a65ebfec4fb190b6f90e944a817d60499ee0744e582530e2c9900a22e591d9a" dependencies = [ "crossterm 0.28.1", "unicode-segmentation", - "unicode-width 0.2.0", + "unicode-width 0.2.1", ] [[package]] @@ -1342,7 +1342,7 @@ dependencies = [ "encode_unicode", "libc", "once_cell", - "unicode-width 0.2.0", + "unicode-width 0.2.1", "windows-sys 0.59.0", ] @@ -1525,7 +1525,7 @@ checksum = "a782b93fae93e57ca8ad3e9e994e784583f5933aeaaa5c80a545c4b437be2047" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -1535,7 +1535,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6984ab21b47a096e17ae4c73cea2123a704d4b6686c39421247ad67020d76f95" dependencies = [ "cosmwasm-schema-derive", - "schemars", + "schemars 0.8.22", "serde", "serde_json", "thiserror 1.0.69", @@ -1549,7 +1549,7 @@ checksum = "e01c9214319017f6ebd8e299036e1f717fa9bb6724e758f7d6fb2477599d1a29" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -1568,7 +1568,7 @@ dependencies = [ "hex", "rand_core 0.6.4", "rmp-serde", - "schemars", + "schemars 0.8.22", "serde", "serde-json-wasm", "sha2 0.10.9", @@ -1793,7 +1793,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" dependencies = [ "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -1838,9 +1838,9 @@ dependencies = [ [[package]] name = "curl" -version = "0.4.47" +version = "0.4.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9fb4d13a1be2b58f14d60adba57c9834b78c62fd86c3e76a148f732686e9265" +checksum = "9e2d5c8f48d9c0c23250e52b55e82a6ab4fdba6650c931f5a0a57a43abda812b" dependencies = [ "curl-sys", "libc", @@ -1848,14 +1848,14 @@ dependencies = [ "openssl-sys", "schannel", "socket2", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "curl-sys" -version = "0.4.80+curl-8.12.1" +version = "0.4.82+curl-8.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55f7df2eac63200c3ab25bde3b2268ef2ee56af3d238e76d61f01c3c49bff734" +checksum = "c4d63638b5ec65f1a4ae945287b3fd035be4554bbaf211901159c9a2a74fb5be" dependencies = [ "cc", "libc", @@ -1863,7 +1863,7 @@ dependencies = [ "openssl-sys", "pkg-config", "vcpkg", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -1891,7 +1891,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -1917,7 +1917,7 @@ dependencies = [ "cosmwasm-std", "cw-storage-plus", "cw-utils", - "schemars", + "schemars 0.8.22", "serde", "thiserror 1.0.69", ] @@ -1929,7 +1929,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f13360e9007f51998d42b1bc6b7fa0141f74feae61ed5fd1e5b0a89eec7b5de1" dependencies = [ "cosmwasm-std", - "schemars", + "schemars 0.8.22", "serde", ] @@ -1941,7 +1941,7 @@ checksum = "07dfee7f12f802431a856984a32bce1cb7da1e6c006b5409e3981035ce562dec" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "schemars", + "schemars 0.8.22", "serde", "thiserror 1.0.69", ] @@ -1955,7 +1955,7 @@ dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus", - "schemars", + "schemars 0.8.22", "semver 1.0.26", "serde", "thiserror 1.0.69", @@ -1970,7 +1970,7 @@ dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-utils", - "schemars", + "schemars 0.8.22", "serde", ] @@ -1984,7 +1984,7 @@ dependencies = [ "cosmwasm-std", "cw-utils", "cw20", - "schemars", + "schemars 0.8.22", "serde", "thiserror 1.0.69", ] @@ -1998,7 +1998,7 @@ dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus", - "schemars", + "schemars 0.8.22", "serde", ] @@ -2023,7 +2023,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -2034,7 +2034,7 @@ checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" dependencies = [ "darling_core", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -2087,7 +2087,7 @@ dependencies = [ "macroific", "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -2130,7 +2130,7 @@ checksum = "30542c1ad912e0e3d22a1935c290e12e8a29d704a420177a31faad4a601a0800" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -2159,7 +2159,7 @@ checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", "unicode-xid", ] @@ -2171,7 +2171,7 @@ checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", "unicode-xid", ] @@ -2240,7 +2240,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -2449,7 +2449,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -2492,12 +2492,12 @@ checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "errno" -version = "0.3.12" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cea14ef9355e3beab063703aa9dab15afd25f0667c341310c1e5274bb1d0da18" +checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] @@ -2588,7 +2588,7 @@ dependencies = [ "macroific", "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -2642,9 +2642,9 @@ checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" [[package]] name = "flate2" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ced92e76e966ca2fd84c8f7aa01a4aea65b0eb6648d72f7c8f3e2764a67fece" +checksum = "4a3d7db9596fecd151c5f638c0ee5d5bd487b6e0ea232e5dc96d5250f6f94b1d" dependencies = [ "crc32fast", "miniz_oxide", @@ -2812,7 +2812,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -2862,7 +2862,7 @@ dependencies = [ "libc", "log", "rustversion", - "windows 0.61.1", + "windows 0.61.3", ] [[package]] @@ -2895,7 +2895,7 @@ dependencies = [ "cfg-if", "js-sys", "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi 0.11.1+wasi-snapshot-preview1", "wasm-bindgen", ] @@ -2915,14 +2915,14 @@ dependencies = [ [[package]] name = "getset" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3586f256131df87204eb733da72e3d3eb4f343c639f4b7be279ac7c48baeafe" +checksum = "9cf0fc11e47561d47397154977bc219f4cf809b2974facc3ccb3b89e2436f912" dependencies = [ "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -3117,9 +3117,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.3" +version = "0.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84b26c544d002229e640969970a2e74021aadf6e2f96372b9c58eff97de08eb3" +checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5" [[package]] name = "hashlink" @@ -3145,11 +3145,11 @@ dependencies = [ [[package]] name = "headers" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "322106e6bd0cba2d5ead589ddb8150a13d7c4217cf80d7c4f682ca994ccc6aa9" +checksum = "b3314d5adb5d94bcdf56771f2e50dbbc80bb4bdf88967526706205ac9eff24eb" dependencies = [ - "base64 0.21.7", + "base64 0.22.1", "bytes", "headers-core", "http 1.3.1", @@ -3193,15 +3193,9 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hermit-abi" -version = "0.3.9" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" - -[[package]] -name = "hermit-abi" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f154ce46856750ed433c8649605bf7ed2de3bc35fd9d2a9f30cddd873c80cb08" +checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" [[package]] name = "hex" @@ -3242,7 +3236,7 @@ dependencies = [ "once_cell", "rand 0.9.1", "ring", - "rustls 0.23.27", + "rustls 0.23.28", "thiserror 2.0.12", "tinyvec", "tokio", @@ -3267,7 +3261,7 @@ dependencies = [ "parking_lot", "rand 0.9.1", "resolv-conf", - "rustls 0.23.27", + "rustls 0.23.28", "smallvec", "thiserror 2.0.12", "tokio", @@ -3493,19 +3487,19 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.27.6" +version = "0.27.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03a01595e11bdcec50946522c32dde3fc6914743000a68b93000965f2f02406d" +checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" dependencies = [ "http 1.3.1", "hyper 1.6.0", "hyper-util", - "rustls 0.23.27", + "rustls 0.23.28", "rustls-pki-types", "tokio", "tokio-rustls 0.26.2", "tower-service", - "webpki-roots 1.0.0", + "webpki-roots 1.0.1", ] [[package]] @@ -3522,17 +3516,21 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.12" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9f1e950e0d9d1d3c47184416723cf29c0d1f93bd8cccf37e4beb6b44f31710" +checksum = "dc2fdfdbff08affe55bb779f33b053aa1fe5dd5b54c257343c17edfa55711bdb" dependencies = [ + "base64 0.22.1", "bytes", "futures-channel", + "futures-core", "futures-util", "http 1.3.1", "http-body 1.0.1", "hyper 1.6.0", + "ipnet", "libc", + "percent-encoding", "pin-project-lite", "socket2", "tokio", @@ -3685,7 +3683,7 @@ checksum = "0ab604ee7085efba6efc65e4ebca0e9533e3aff6cb501d7d77b211e3a781c6d5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -3754,7 +3752,7 @@ dependencies = [ "macroific", "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -3775,7 +3773,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" dependencies = [ "equivalent", - "hashbrown 0.15.3", + "hashbrown 0.15.4", "serde", ] @@ -3788,7 +3786,7 @@ dependencies = [ "console", "number_prefix", "portable-atomic", - "unicode-width 0.2.0", + "unicode-width 0.2.1", "vt100", "web-time", ] @@ -3896,13 +3894,23 @@ dependencies = [ "serde", ] +[[package]] +name = "iri-string" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2" +dependencies = [ + "memchr", + "serde", +] + [[package]] name = "is-terminal" version = "0.4.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9" dependencies = [ - "hermit-abi 0.5.1", + "hermit-abi", "libc", "windows-sys 0.59.0", ] @@ -3964,9 +3972,9 @@ checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "jiff" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a194df1107f33c79f4f93d02c80798520551949d59dfad22b6157048a88cca93" +checksum = "be1f93b8b1eb69c77f24bbb0afdf66f54b632ee39af40ca21c4365a1d7347e49" dependencies = [ "jiff-static", "log", @@ -3977,13 +3985,13 @@ dependencies = [ [[package]] name = "jiff-static" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c6e1db7ed32c6c71b759497fae34bf7933636f75a251b9e736555da426f6442" +checksum = "03343451ff899767262ec32146f6d559dd759fdadf42ff0e227c7c48f72594b4" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -4094,9 +4102,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.172" +version = "0.2.174" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" +checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" [[package]] name = "libm" @@ -4170,9 +4178,9 @@ checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" [[package]] name = "lock_api" -version = "0.4.12" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" dependencies = [ "autocfg", "scopeguard", @@ -4229,7 +4237,7 @@ dependencies = [ "proc-macro2", "quote", "sealed", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -4241,7 +4249,7 @@ dependencies = [ "proc-macro2", "quote", "sealed", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -4254,7 +4262,7 @@ dependencies = [ "macroific_core", "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -4265,9 +4273,9 @@ checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" [[package]] name = "markup5ever" -version = "0.16.1" +version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0a8096766c229e8c88a3900c9b44b7e06aa7f7343cc229158c3e58ef8f9973a" +checksum = "2e4cd8c02f18a011991a039855480c64d74291c5792fcc160d55d77dc4de4a39" dependencies = [ "log", "tendril", @@ -4282,7 +4290,7 @@ checksum = "88a9689d8d44bf9964484516275f5cd4c9b59457a6940c1d5d0ecbb94510a36b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -4312,9 +4320,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.4" +version = "2.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" [[package]] name = "memoffset" @@ -4359,9 +4367,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.8.8" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" dependencies = [ "adler2", ] @@ -4374,7 +4382,7 @@ checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" dependencies = [ "libc", "log", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi 0.11.1+wasi-snapshot-preview1", "windows-sys 0.48.0", ] @@ -4385,7 +4393,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" dependencies = [ "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi 0.11.1+wasi-snapshot-preview1", "windows-sys 0.59.0", ] @@ -4706,11 +4714,11 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b" dependencies = [ - "hermit-abi 0.3.9", + "hermit-abi", "libc", ] @@ -4793,8 +4801,8 @@ dependencies = [ "pin-project", "rand 0.8.5", "rand_chacha 0.3.1", - "reqwest 0.12.15", - "schemars", + "reqwest 0.12.20", + "schemars 0.8.22", "semver 1.0.26", "serde", "serde_json", @@ -4807,7 +4815,7 @@ dependencies = [ "tokio", "tokio-stream", "tokio-util", - "tower-http", + "tower-http 0.5.2", "tracing", "ts-rs", "url", @@ -4840,7 +4848,7 @@ dependencies = [ "nym-serde-helpers", "nym-ticketbooks-merkle", "rand_chacha 0.3.1", - "schemars", + "schemars 0.8.22", "serde", "serde_json", "sha2 0.10.9", @@ -4957,7 +4965,7 @@ dependencies = [ "log", "opentelemetry", "opentelemetry-jaeger", - "schemars", + "schemars 0.8.22", "serde", "serde_json", "tracing", @@ -5060,7 +5068,7 @@ dependencies = [ "thiserror 2.0.12", "time", "tokio", - "toml 0.8.22", + "toml 0.8.23", "url", "zeroize", ] @@ -5291,7 +5299,7 @@ dependencies = [ "nym-network-defaults", "serde", "thiserror 2.0.12", - "toml 0.8.22", + "toml 0.8.23", "url", ] @@ -5303,7 +5311,7 @@ dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus", - "schemars", + "schemars 0.8.22", "serde", "serde_json", "thiserror 2.0.12", @@ -5352,7 +5360,7 @@ dependencies = [ "nym-network-defaults", "nym-validator-client", "rand 0.8.5", - "reqwest 0.12.15", + "reqwest 0.12.20", "serde", "serde_json", "sqlx", @@ -5364,7 +5372,7 @@ dependencies = [ "tokio", "tokio-util", "tower 0.5.2", - "tower-http", + "tower-http 0.5.2", "tracing", "url", "utoipa", @@ -5383,8 +5391,8 @@ dependencies = [ "nym-http-api-client", "nym-http-api-common", "nym-serde-helpers", - "reqwest 0.12.15", - "schemars", + "reqwest 0.12.20", + "schemars 0.8.22", "serde", "serde_json", "time", @@ -5579,7 +5587,7 @@ dependencies = [ name = "nym-exit-policy" version = "0.1.0" dependencies = [ - "reqwest 0.12.15", + "reqwest 0.12.20", "serde", "serde_json", "thiserror 2.0.12", @@ -5775,7 +5783,7 @@ dependencies = [ "cosmwasm-schema", "cw-controllers", "cw4", - "schemars", + "schemars 0.8.22", "serde", ] @@ -5793,7 +5801,7 @@ dependencies = [ "nym-bin-common", "nym-http-api-common", "once_cell", - "reqwest 0.12.15", + "reqwest 0.12.20", "serde", "serde_json", "thiserror 2.0.12", @@ -5909,7 +5917,7 @@ dependencies = [ "nym-wireguard", "nym-wireguard-types", "rand 0.8.5", - "reqwest 0.12.15", + "reqwest 0.12.20", "serde", "serde_json", "thiserror 2.0.12", @@ -5968,7 +5976,7 @@ dependencies = [ "humantime-serde", "nym-contracts-common", "rand_chacha 0.3.1", - "schemars", + "schemars 0.8.22", "semver 1.0.26", "serde", "serde-json-wasm", @@ -6016,7 +6024,7 @@ dependencies = [ "cw-utils", "cw3", "cw4", - "schemars", + "schemars 0.8.22", "serde", "thiserror 2.0.12", ] @@ -6029,7 +6037,7 @@ dependencies = [ "dotenvy", "log", "regex", - "schemars", + "schemars 0.8.22", "serde", "url", "utoipa", @@ -6058,12 +6066,16 @@ dependencies = [ "petgraph", "rand 0.8.5", "rand_chacha 0.3.1", - "reqwest 0.12.15", + "reqwest 0.12.20", "serde", "serde_json", + "socket2", "tokio", "tokio-postgres", "tokio-util", + "tower 0.5.2", + "tower-http 0.5.2", + "tracing", "utoipa", "utoipa-swagger-ui", ] @@ -6104,7 +6116,7 @@ dependencies = [ "publicsuffix", "rand 0.8.5", "regex", - "reqwest 0.12.15", + "reqwest 0.12.20", "serde", "serde_json", "sqlx", @@ -6187,8 +6199,8 @@ dependencies = [ "time", "tokio", "tokio-util", - "toml 0.8.22", - "tower-http", + "toml 0.8.23", + "tower-http 0.5.2", "tracing", "tracing-indicatif", "tracing-subscriber", @@ -6226,7 +6238,7 @@ dependencies = [ "nym-http-api-client", "nym-wireguard-types", "rand_chacha 0.3.1", - "schemars", + "schemars 0.8.22", "serde", "serde_json", "strum 0.26.3", @@ -6284,7 +6296,7 @@ dependencies = [ "rand 0.8.5", "rand_chacha 0.3.1", "regex", - "reqwest 0.12.15", + "reqwest 0.12.20", "serde", "serde_json", "serde_json_path", @@ -6295,7 +6307,7 @@ dependencies = [ "time", "tokio", "tokio-util", - "tower-http", + "tower-http 0.5.2", "tracing", "tracing-log 0.2.0", "tracing-subscriber", @@ -6313,7 +6325,7 @@ dependencies = [ "chrono", "nym-crypto", "nym-http-api-client", - "reqwest 0.12.15", + "reqwest 0.12.20", "serde", "serde_json", "tracing", @@ -6461,7 +6473,7 @@ dependencies = [ "nym-validator-client", "parking_lot", "rand 0.8.5", - "reqwest 0.12.15", + "reqwest 0.12.20", "serde", "tap", "tempfile", @@ -6469,7 +6481,7 @@ dependencies = [ "tokio", "tokio-stream", "tokio-util", - "toml 0.8.22", + "toml 0.8.23", "tracing", "tracing-subscriber", "url", @@ -6570,8 +6582,8 @@ dependencies = [ "nym-validator-client", "pin-project", "rand 0.8.5", - "reqwest 0.12.15", - "schemars", + "reqwest 0.12.20", + "schemars 0.8.22", "serde", "tap", "thiserror 2.0.12", @@ -6835,7 +6847,7 @@ dependencies = [ "rand 0.8.5", "rand_chacha 0.3.1", "rs_merkle", - "schemars", + "schemars 0.8.22", "serde", "serde_json", "sha2 0.10.9", @@ -6856,7 +6868,7 @@ dependencies = [ "nym-sphinx-routing", "nym-sphinx-types", "rand 0.8.5", - "reqwest 0.12.15", + "reqwest 0.12.20", "serde", "serde_json", "thiserror 2.0.12", @@ -6894,8 +6906,8 @@ dependencies = [ "nym-mixnet-contract-common", "nym-validator-client", "nym-vesting-contract-common", - "reqwest 0.12.15", - "schemars", + "reqwest 0.12.20", + "schemars 0.8.22", "serde", "serde_json", "sha2 0.10.9", @@ -6942,7 +6954,7 @@ dependencies = [ "nym-serde-helpers", "nym-vesting-contract-common", "prost 0.13.5", - "reqwest 0.12.15", + "reqwest 0.12.20", "serde", "serde_json", "sha2 0.10.9", @@ -7137,7 +7149,7 @@ dependencies = [ "nym-bin-common", "nym-config", "nym-task", - "reqwest 0.12.15", + "reqwest 0.12.20", "serde", "serde_json", "sha2 0.10.9", @@ -7164,15 +7176,15 @@ dependencies = [ "nym-task", "nym-validator-client", "nyxd-scraper", - "reqwest 0.12.15", - "schemars", + "reqwest 0.12.20", + "schemars 0.8.22", "serde", "sqlx", "thiserror 2.0.12", "time", "tokio", "tokio-util", - "tower-http", + "tower-http 0.5.2", "tracing", "tracing-subscriber", "utoipa", @@ -7255,9 +7267,9 @@ checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" [[package]] name = "openssl-sys" -version = "0.9.108" +version = "0.9.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e145e1651e858e820e4860f7b9c5e169bc1d8ce1c86043be79fa7b7634821847" +checksum = "90096e2e47630d78b7d1c20952dc621f957103f8bc2c8359ec81290d75238571" dependencies = [ "cc", "libc", @@ -7405,9 +7417,9 @@ checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" [[package]] name = "parking_lot" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" dependencies = [ "lock_api", "parking_lot_core", @@ -7415,9 +7427,9 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.10" +version = "0.9.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" dependencies = [ "cfg-if", "libc", @@ -7498,9 +7510,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.8.0" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "198db74531d58c70a361c42201efde7e2591e976d518caf7662a47dc5720e7b6" +checksum = "1db05f56d34358a8b1066f67cbb203ee3e7ed2ba674a6263a1d5ec6db2204323" dependencies = [ "memchr", "thiserror 2.0.12", @@ -7509,9 +7521,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.8.0" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d725d9cfd79e87dccc9341a2ef39d1b6f6353d68c4b33c177febbe1a402c97c5" +checksum = "bb056d9e8ea77922845ec74a1c4e8fb17e7c218cc4fc11a15c5d25e189aa40bc" dependencies = [ "pest", "pest_generator", @@ -7519,24 +7531,23 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.8.0" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db7d01726be8ab66ab32f9df467ae8b1148906685bbe75c82d1e65d7f5b3f841" +checksum = "87e404e638f781eb3202dc82db6760c8ae8a1eeef7fb3fa8264b2ef280504966" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] name = "pest_meta" -version = "2.8.0" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f9f832470494906d1fca5329f8ab5791cc60beb230c74815dff541cbd2b5ca0" +checksum = "edd1101f170f5903fde0914f899bb503d9ff5271d7ba76bbb70bea63690cc0d5" dependencies = [ - "once_cell", "pest", "sha2 0.10.9", ] @@ -7591,7 +7602,7 @@ dependencies = [ "phf_shared", "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -7620,7 +7631,7 @@ checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -7737,9 +7748,9 @@ dependencies = [ [[package]] name = "portable-atomic" -version = "1.11.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e" +checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" [[package]] name = "portable-atomic-util" @@ -7847,7 +7858,7 @@ dependencies = [ "proc-macro-error-attr2", "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -7917,7 +7928,7 @@ dependencies = [ "itertools 0.14.0", "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -7951,9 +7962,9 @@ dependencies = [ [[package]] name = "psl" -version = "2.1.112" +version = "2.1.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c6b4c497a0c6bfb466f75167c728b1a861b0cdc39de9c35b877208a270a9590" +checksum = "98426d83dcbac622be1c1146e8763ccb4a2fe9bca707dd7446a842e186fa91aa" dependencies = [ "psl-types", ] @@ -7992,7 +8003,7 @@ dependencies = [ "quinn-proto", "quinn-udp", "rustc-hash", - "rustls 0.23.27", + "rustls 0.23.28", "socket2", "thiserror 2.0.12", "tokio", @@ -8012,7 +8023,7 @@ dependencies = [ "rand 0.9.1", "ring", "rustc-hash", - "rustls 0.23.27", + "rustls 0.23.28", "rustls-pki-types", "slab", "thiserror 2.0.12", @@ -8023,9 +8034,9 @@ dependencies = [ [[package]] name = "quinn-udp" -version = "0.5.12" +version = "0.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee4e529991f949c5e25755532370b8af5d114acae52326361d68d47af64aa842" +checksum = "fcebb1209ee276352ef14ff8732e24cc2b02bbac986cd74a4c81bcb2f9881970" dependencies = [ "cfg_aliases", "libc", @@ -8046,9 +8057,9 @@ dependencies = [ [[package]] name = "r-efi" -version = "5.2.0" +version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" [[package]] name = "radium" @@ -8147,9 +8158,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.12" +version = "0.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "928fca9cf2aa042393a8325b9ead81d2f0df4cb12e1e24cef072922ccd99c5af" +checksum = "0d04b7d0ee6b4a0207a0a7adb104d23ecb0b47d6beae7152d0fa34b692b29fd6" dependencies = [ "bitflags 2.9.1", ] @@ -8165,6 +8176,26 @@ dependencies = [ "thiserror 1.0.69", ] +[[package]] +name = "ref-cast" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a0ae411dbe946a674d89546582cea4ba2bb8defac896622d6496f14c23ba5cf" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1165225c21bff1f3bbce98f5a1f889949bc902d3575308cc7b0de30b4f6d27c7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + [[package]] name = "regex" version = "1.11.1" @@ -8252,9 +8283,9 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.12.15" +version = "0.12.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d19c46a6fdd48bc4dab94b6103fccc55d34c67cc0ad04653aad4ea2a07cd7bbb" +checksum = "eabf4c97d9130e2bf606614eb937e86edac8292eaa6f422f995d7e8de1eb1813" dependencies = [ "async-compression", "base64 0.22.1", @@ -8265,18 +8296,14 @@ dependencies = [ "http-body 1.0.1", "http-body-util", "hyper 1.6.0", - "hyper-rustls 0.27.6", + "hyper-rustls 0.27.7", "hyper-util", - "ipnet", "js-sys", "log", - "mime", - "once_cell", "percent-encoding", "pin-project-lite", "quinn", - "rustls 0.23.27", - "rustls-pemfile 2.2.0", + "rustls 0.23.28", "rustls-pki-types", "serde", "serde_json", @@ -8284,24 +8311,23 @@ dependencies = [ "sync_wrapper 1.0.2", "tokio", "tokio-rustls 0.26.2", - "tokio-socks", "tokio-util", "tower 0.5.2", + "tower-http 0.6.6", "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", "wasm-streams", "web-sys", - "webpki-roots 0.26.11", - "windows-registry", + "webpki-roots 1.0.1", ] [[package]] name = "reserve-port" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3747658ee2585ecf5607fa9887c92eff61b362ff5253dbf797dfeb73d33d78" +checksum = "21918d6644020c6f6ef1993242989bf6d4952d2e025617744f184c02df51c356" dependencies = [ "thiserror 2.0.12", ] @@ -8416,7 +8442,7 @@ dependencies = [ "proc-macro2", "quote", "rust-embed-utils", - "syn 2.0.101", + "syn 2.0.104", "walkdir", ] @@ -8448,9 +8474,9 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.24" +version = "0.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" +checksum = "989e6739f80c4ad5b13e0fd7fe89531180375b18520cc8c82080e4dc4035b84f" [[package]] name = "rustc-hash" @@ -8530,9 +8556,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.27" +version = "0.23.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "730944ca083c1c233a75c09f199e973ca499344a2b7ba9e755c457e86fb4a321" +checksum = "7160e3e10bf4535308537f3c4e1641468cd0e485175d6163087c0393c7d46643" dependencies = [ "log", "once_cell", @@ -8672,6 +8698,18 @@ dependencies = [ "uuid", ] +[[package]] +name = "schemars" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd191f9397d57d581cddd31014772520aa448f65ef991055d7f61582c65165f" +dependencies = [ + "dyn-clone", + "ref-cast", + "serde", + "serde_json", +] + [[package]] name = "schemars_derive" version = "0.8.22" @@ -8681,7 +8719,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals 0.29.1", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -8713,7 +8751,7 @@ checksum = "1783eabc414609e28a5ba76aee5ddd52199f7107a0b24c2e9746a1ecc34a683d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -8734,7 +8772,7 @@ checksum = "22f968c5ea23d555e670b449c1c5e7b2fc399fdaec1d304a17cd48e288abc107" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -8874,7 +8912,7 @@ checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -8885,7 +8923,7 @@ checksum = "e578a843d40b4189a4d66bba51d7684f57da5bd7c304c64e14bd63efbef49509" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -8896,7 +8934,7 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -8958,7 +8996,7 @@ checksum = "aafbefbe175fa9bf03ca83ef89beecff7d2a95aaacd5732325b90ac8c3bd7b90" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -8979,14 +9017,14 @@ checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] name = "serde_spanned" -version = "0.6.8" +version = "0.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" +checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" dependencies = [ "serde", ] @@ -9005,15 +9043,16 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.12.0" +version = "3.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6b6f7f2fcb69f747921f79f3926bd1e203fce4fef62c268dd3abfb6d86029aa" +checksum = "bf65a400f8f66fb7b0552869ad70157166676db75ed8181f8104ea91cf9d0b42" dependencies = [ "base64 0.22.1", "chrono", "hex", "indexmap 1.9.3", "indexmap 2.9.0", + "schemars 0.9.0", "serde", "serde_derive", "serde_json", @@ -9023,14 +9062,14 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.12.0" +version = "3.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d00caa5193a3c8362ac2b73be6b9e768aa5a4b2f721d8f4b339600c3cb51f8e" +checksum = "81679d9ed988d5e9a5e6531dc3f2c28efbd639cbd1dfb628df08edea6004da77" dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -9182,12 +9221,9 @@ checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" [[package]] name = "slab" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" -dependencies = [ - "autocfg", -] +checksum = "04dc19736151f35336d325007ac991178d504a119863a2fcb3758cdb5e52c50d" [[package]] name = "sluice" @@ -9202,9 +9238,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.15.0" +version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] name = "smawk" @@ -9609,7 +9645,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -9652,9 +9688,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.101" +version = "2.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf" +checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" dependencies = [ "proc-macro2", "quote", @@ -9684,7 +9720,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -9798,7 +9834,7 @@ dependencies = [ "serde", "serde_json", "tendermint", - "toml 0.8.22", + "toml 0.8.23", "url", ] @@ -9904,7 +9940,7 @@ dependencies = [ "thiserror 2.0.12", "time", "tokio", - "toml 0.8.22", + "toml 0.8.23", "tracing", "url", "zeroize", @@ -9945,7 +9981,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -9956,17 +9992,16 @@ checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] name = "thread_local" -version = "1.1.8" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" dependencies = [ "cfg-if", - "once_cell", ] [[package]] @@ -10097,7 +10132,7 @@ checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -10153,19 +10188,7 @@ version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" dependencies = [ - "rustls 0.23.27", - "tokio", -] - -[[package]] -name = "tokio-socks" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d4770b8024672c1101b3f6733eab95b18007dbe0847a8afe341fcf79e06043f" -dependencies = [ - "either", - "futures-util", - "thiserror 1.0.69", + "rustls 0.23.28", "tokio", ] @@ -10231,7 +10254,7 @@ dependencies = [ "futures-core", "futures-sink", "futures-util", - "hashbrown 0.15.3", + "hashbrown 0.15.4", "pin-project-lite", "slab", "tokio", @@ -10248,9 +10271,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.22" +version = "0.8.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05ae329d1f08c4d17a59bed7ff5b5a769d062e64a62d34a3261b219e62cd5aae" +checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" dependencies = [ "serde", "serde_spanned", @@ -10260,18 +10283,18 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.9" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3da5db5a963e24bc68be8b17b6fa82814bb22ee8660f192bb182771d498f09a3" +checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" dependencies = [ "serde", ] [[package]] name = "toml_edit" -version = "0.22.26" +version = "0.22.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "310068873db2c5b3e7659d2cc35d21855dbafa50d1ce336397c666e3cb08137e" +checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" dependencies = [ "indexmap 2.9.0", "serde", @@ -10283,9 +10306,9 @@ dependencies = [ [[package]] name = "toml_write" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfb942dfe1d8e29a7ee7fcbde5bd2b9a25fb89aa70caea2eba3bee836ff41076" +checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" [[package]] name = "tonic" @@ -10378,6 +10401,24 @@ dependencies = [ "tracing", ] +[[package]] +name = "tower-http" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" +dependencies = [ + "bitflags 2.9.1", + "bytes", + "futures-util", + "http 1.3.1", + "http-body 1.0.1", + "iri-string", + "pin-project-lite", + "tower 0.5.2", + "tower-layer", + "tower-service", +] + [[package]] name = "tower-layer" version = "0.3.3" @@ -10404,20 +10445,20 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.28" +version = "0.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" +checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] name = "tracing-core" -version = "0.1.33" +version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" +checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" dependencies = [ "once_cell", "valuable", @@ -10580,7 +10621,7 @@ checksum = "0e9d8656589772eeec2cf7a8264d9cda40fb28b9bc53118ceb9e8c07f8f38730" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", "termcolor", ] @@ -10607,7 +10648,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals 0.28.0", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -10684,9 +10725,9 @@ checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" [[package]] name = "unicode-normalization" -version = "0.1.22" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" dependencies = [ "tinyvec", ] @@ -10711,9 +10752,9 @@ checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" [[package]] name = "unicode-width" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" +checksum = "4a1a07cc7db3810833284e8d372ccdc6da29741639ecc70c9ec107df0fa6154c" [[package]] name = "unicode-xid" @@ -10729,9 +10770,9 @@ checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" [[package]] name = "uniffi" -version = "0.29.2" +version = "0.29.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dcd1d240101ba3b9d7532ae86d9cb64d9a7ff63e13a2b7b9e94a32a601d8233" +checksum = "b334fd69b3cf198b63616c096aabf9820ab21ed9b2aa1367ddd4b411068bf520" dependencies = [ "anyhow", "camino", @@ -10746,9 +10787,9 @@ dependencies = [ [[package]] name = "uniffi_bindgen" -version = "0.29.2" +version = "0.29.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d0525f06d749ea80d8049dc0bb038bb87941e3d909eefa76b6f0a5589b59ac5" +checksum = "2ff0132b533483cf19abb30bba5c72c24d9f3e4d9a2ff71cb3e22e73899fd46e" dependencies = [ "anyhow", "askama", @@ -10772,9 +10813,9 @@ dependencies = [ [[package]] name = "uniffi_build" -version = "0.29.2" +version = "0.29.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aed2f0204e942bb9c11c9f11a323b4abf70cf11b2e5957d60b3f2728430f6c6f" +checksum = "0d84d607076008df3c32dd2100ee4e727269f11d3faa35691af70d144598f666" dependencies = [ "anyhow", "camino", @@ -10783,9 +10824,9 @@ dependencies = [ [[package]] name = "uniffi_core" -version = "0.29.2" +version = "0.29.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3fa8eb4d825b4ed095cb13483cba6927c3002b9eb603cef9b7688758cc3772e" +checksum = "53e3b997192dc15ef1778c842001811ec7f241a093a693ac864e1fc938e64fa9" dependencies = [ "anyhow", "bytes", @@ -10795,22 +10836,22 @@ dependencies = [ [[package]] name = "uniffi_internal_macros" -version = "0.29.2" +version = "0.29.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83b547d69d699e52f2129fde4b57ae0d00b5216e59ed5b56097c95c86ba06095" +checksum = "f64bec2f3a33f2f08df8150e67fa45ba59a2ca740bf20c1beb010d4d791f9a1b" dependencies = [ "anyhow", "indexmap 2.9.0", "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] name = "uniffi_macros" -version = "0.29.2" +version = "0.29.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00f1de72edc8cb9201c7d650e3678840d143e4499004571aac49e6cb1b17da43" +checksum = "5d8708716d2582e4f3d7e9f320290b5966eb951ca421d7630571183615453efc" dependencies = [ "camino", "fs-err", @@ -10818,16 +10859,16 @@ dependencies = [ "proc-macro2", "quote", "serde", - "syn 2.0.101", + "syn 2.0.104", "toml 0.5.11", "uniffi_meta", ] [[package]] name = "uniffi_meta" -version = "0.29.2" +version = "0.29.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acc9204632f6a555b2cba7c8852c5523bc1aa5f3eff605c64af5054ea28b72e" +checksum = "3d226fc167754ce548c5ece9828c8a06f03bf1eea525d2659ba6bd648bd8e2f3" dependencies = [ "anyhow", "siphasher 0.3.11", @@ -10837,9 +10878,9 @@ dependencies = [ [[package]] name = "uniffi_pipeline" -version = "0.29.2" +version = "0.29.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54b5336a9a925b358183837d31541d12590b7fcec373256d3770de02dff24c69" +checksum = "b925b6421df15cf4bedee27714022cd9626fb4d7eee0923522a608b274ba4371" dependencies = [ "anyhow", "heck 0.5.0", @@ -10850,9 +10891,9 @@ dependencies = [ [[package]] name = "uniffi_udl" -version = "0.29.2" +version = "0.29.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f95e73373d85f04736bc51997d3e6855721144ec4384cae9ca8513c80615e129" +checksum = "9c42649b721df759d9d4692a376b82b62ce3028ec9fc466f4780fb8cdf728996" dependencies = [ "anyhow", "textwrap", @@ -10920,9 +10961,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "utoipa" -version = "5.3.1" +version = "5.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "435c6f69ef38c9017b4b4eea965dfb91e71e53d869e896db40d1cf2441dd75c0" +checksum = "2fcc29c80c21c31608227e0912b2d7fddba57ad76b606890627ba8ee7964e993" dependencies = [ "indexmap 2.9.0", "serde", @@ -10932,14 +10973,14 @@ dependencies = [ [[package]] name = "utoipa-gen" -version = "5.3.1" +version = "5.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a77d306bc75294fd52f3e99b13ece67c02c1a2789190a6f31d32f736624326f7" +checksum = "6d79d08d92ab8af4c5e8a6da20c47ae3f61a0f1dabc1997cdf2d082b757ca08b" dependencies = [ "proc-macro2", "quote", "regex", - "syn 2.0.101", + "syn 2.0.104", "uuid", ] @@ -10978,7 +11019,7 @@ checksum = "268d76aaebb80eba79240b805972e52d7d410d4bcc52321b951318b0f440cd60" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -10989,7 +11030,7 @@ checksum = "382673bda1d05c85b4550d32fd4192ccd4cffe9a908543a0795d1e7682b36246" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", "utoipauto-core", ] @@ -11116,9 +11157,9 @@ dependencies = [ [[package]] name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" +version = "0.11.1+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasi" @@ -11157,7 +11198,7 @@ dependencies = [ "log", "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", "wasm-bindgen-shared", ] @@ -11192,7 +11233,7 @@ checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -11227,7 +11268,7 @@ checksum = "17d5042cc5fa009658f9a7333ef24291b1291a25b6382dd68862a7f3b969f69b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -11310,9 +11351,9 @@ dependencies = [ [[package]] name = "wasmtimer" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0048ad49a55b9deb3953841fa1fc5858f0efbcb7a18868c899a360269fac1b23" +checksum = "d8d49b5d6c64e8558d9b1b065014426f35c18de636895d24893dbbd329743446" dependencies = [ "futures", "js-sys", @@ -11344,9 +11385,9 @@ dependencies = [ [[package]] name = "web_atoms" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b9c5f0bc545ea3b20b423e33b9b457764de0b3730cd957f6c6aa6c301785f6e" +checksum = "57ffde1dc01240bdf9992e3205668b235e59421fd085e8a317ed98da0178d414" dependencies = [ "phf", "phf_codegen", @@ -11375,14 +11416,14 @@ version = "0.26.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9" dependencies = [ - "webpki-roots 1.0.0", + "webpki-roots 1.0.1", ] [[package]] name = "webpki-roots" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2853738d1cc4f2da3a225c18ec6c3721abb31961096e9dbf5ab35fa88b19cfdb" +checksum = "8782dd5a41a24eed3a4f40b606249b3e236ca61adf1f25ea4d45c73de122b502" dependencies = [ "rustls-pki-types", ] @@ -11456,9 +11497,9 @@ dependencies = [ [[package]] name = "windows" -version = "0.61.1" +version = "0.61.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5ee8f3d025738cb02bad7868bbb5f8a6327501e870bf51f1b455b0a2454a419" +checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893" dependencies = [ "windows-collections", "windows-core 0.61.2", @@ -11498,7 +11539,7 @@ dependencies = [ "windows-interface 0.59.1", "windows-link", "windows-result 0.3.4", - "windows-strings 0.4.2", + "windows-strings", ] [[package]] @@ -11520,7 +11561,7 @@ checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -11531,7 +11572,7 @@ checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -11542,7 +11583,7 @@ checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -11553,14 +11594,14 @@ checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] name = "windows-link" -version = "0.1.1" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" [[package]] name = "windows-numerics" @@ -11572,17 +11613,6 @@ dependencies = [ "windows-link", ] -[[package]] -name = "windows-registry" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4286ad90ddb45071efd1a66dfa43eb02dd0dfbae1545ad6cc3c51cf34d7e8ba3" -dependencies = [ - "windows-result 0.3.4", - "windows-strings 0.3.1", - "windows-targets 0.53.0", -] - [[package]] name = "windows-result" version = "0.1.2" @@ -11601,15 +11631,6 @@ dependencies = [ "windows-link", ] -[[package]] -name = "windows-strings" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319" -dependencies = [ - "windows-link", -] - [[package]] name = "windows-strings" version = "0.4.2" @@ -11655,6 +11676,15 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.2", +] + [[package]] name = "windows-targets" version = "0.42.2" @@ -11703,9 +11733,9 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.53.0" +version = "0.53.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1e4c7e8ceaaf9cb7d7507c974735728ab453b67ef8f18febdd7c11fe59dca8b" +checksum = "c66f69fcc9ce11da9966ddb31a40968cad001c5bedeb5c2b82ede4253ab48aef" dependencies = [ "windows_aarch64_gnullvm 0.53.0", "windows_aarch64_msvc 0.53.0", @@ -11908,9 +11938,9 @@ checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" [[package]] name = "winnow" -version = "0.7.10" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06928c8748d81b05c9be96aad92e1b6ff01833332f281e8cfca3be4b35fc9ec" +checksum = "74c7b26e3480b707944fc872477815d29a8e429d2f93a1ce000f5fa84a15cbcd" dependencies = [ "memchr", ] @@ -11997,28 +12027,28 @@ checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", "synstructure", ] [[package]] name = "zerocopy" -version = "0.8.25" +version = "0.8.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1702d9583232ddb9174e01bb7c15a2ab8fb1bc6f227aa1233858c351a3ba0cb" +checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.25" +version = "0.8.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28a6e20d751156648aa063f3800b706ee209a32c0b4d9f24be3d980b01be55ef" +checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -12038,7 +12068,7 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", "synstructure", ] @@ -12059,7 +12089,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -12092,7 +12122,7 @@ checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -12127,7 +12157,7 @@ dependencies = [ "nym-crypto", "nym-http-api-client", "rand 0.8.5", - "reqwest 0.12.15", + "reqwest 0.12.20", "serde", "thiserror 2.0.12", "tokio", diff --git a/common/client-core/src/error.rs b/common/client-core/src/error.rs index 0cf2a88b6b..fe5381a2aa 100644 --- a/common/client-core/src/error.rs +++ b/common/client-core/src/error.rs @@ -166,6 +166,9 @@ pub enum ClientCoreError { #[error("there are no gateways supporting the wss protocol available")] NoWssGateways, + #[error("there are no gateways with compatible protocol versions available")] + NoGatewaysWithCompatibleProtocol, + #[error("the specified gateway '{gateway}' does not support the wss protocol")] UnsupportedWssProtocol { gateway: String }, diff --git a/common/client-core/src/init/helpers.rs b/common/client-core/src/init/helpers.rs index b007243ce6..1a005c1871 100644 --- a/common/client-core/src/init/helpers.rs +++ b/common/client-core/src/init/helpers.rs @@ -7,6 +7,7 @@ use futures::{SinkExt, StreamExt}; use log::{debug, info, trace, warn}; use nym_crypto::asymmetric::ed25519; use nym_gateway_client::GatewayClient; +use nym_gateway_requests::{ClientControlRequest, ServerResponse, CURRENT_PROTOCOL_VERSION}; use nym_topology::node::RoutingNode; use nym_validator_client::client::IdentityKeyRef; use nym_validator_client::UserAgent; @@ -131,6 +132,63 @@ pub async fn gateways_for_init( Ok(valid_gateways) } +pub async fn gateways_for_init_with_protocol_validation( + rng: &mut R, + nym_apis: &[Url], + user_agent: Option, + minimum_performance: u8, + ignore_epoch_roles: bool, +) -> Result, ClientCoreError> { + // First get the initial list of gateways + let gateways = gateways_for_init( + rng, + nym_apis, + user_agent, + minimum_performance, + ignore_epoch_roles, + ) + .await?; + + info!( + "Checking protocol compatibility for {} gateways...", + gateways.len() + ); + + // Filter out gateways with invalid protocols concurrently + let validated_gateways = Arc::new(tokio::sync::Mutex::new(Vec::new())); + + futures::stream::iter(&gateways) + .for_each_concurrent(CONCURRENT_GATEWAYS_MEASURED, |gateway| async { + let id = gateway.identity(); + trace!("validating protocol compatibility with {id}..."); + + match validate_gateway_protocol(gateway).await { + Ok(()) => { + debug!("{id}: protocol check successful"); + validated_gateways.lock().await.push(gateway.clone()); + } + Err(err) => { + warn!("failed to check protocol for {id}: {err}"); + } + } + }) + .await; + + let validated_gateways = validated_gateways.lock().await; + + info!( + "Protocol check complete: {}/{} gateways responded successfully", + validated_gateways.len(), + gateways.len() + ); + + if validated_gateways.is_empty() { + return Err(ClientCoreError::NoGatewaysWithCompatibleProtocol); + } + + Ok(validated_gateways.clone()) +} + #[cfg(not(target_arch = "wasm32"))] async fn connect(endpoint: &str) -> Result { match tokio::time::timeout(CONN_TIMEOUT, connect_async(endpoint)).await { @@ -210,6 +268,132 @@ where Ok(GatewayWithLatency::new(gateway, avg)) } +async fn validate_gateway_protocol(gateway: &G) -> Result<(), ClientCoreError> +where + G: ConnectableGateway, +{ + let Some(addr) = gateway.clients_address(false) else { + return Err(ClientCoreError::UnsupportedEntry { + id: gateway.node_id(), + identity: gateway.identity().to_string(), + }); + }; + + trace!( + "validating protocol compatibility with {} ({addr})...", + gateway.identity(), + ); + + let mut stream = connect(&addr).await?; + + // Send protocol version request + let protocol_request = ClientControlRequest::SupportedProtocol {}; + + // Send the request as JSON text message + stream.send(Message::from(protocol_request)).await?; + + // Wait for response with timeout + let protocol_timeout = Duration::from_millis(2000); + let response_future = stream.next(); + + match tokio::time::timeout(protocol_timeout, response_future).await { + Err(_) => { + warn!("Gateway {} protocol check timed out", gateway.identity()); + Err(ClientCoreError::GatewayConnectionTimeout) + } + Ok(Some(Ok(Message::Text(response_text)))) => { + // Try to deserialize the response + let response = ServerResponse::try_from(response_text).map_err(|_| { + ClientCoreError::GatewayClientError { + gateway_id: gateway.identity().to_base58_string(), + source: *Box::new( + nym_gateway_client::error::GatewayClientError::MalformedResponse, + ), + } + })?; + + match response { + ServerResponse::SupportedProtocol { version } => { + debug!( + "Gateway {} supports protocol version {}, ours: {}", + gateway.identity(), + version, + CURRENT_PROTOCOL_VERSION + ); + + // Check protocol compatibility + if version > CURRENT_PROTOCOL_VERSION { + warn!( + "Gateway {} uses newer protocol version {} (client supports {}). \ + Gateway should gracefully degrade, but consider updating your client.", + gateway.identity(), + version, + CURRENT_PROTOCOL_VERSION + ); + } + + trace!( + "Gateway {} protocol validation successful (gateway: v{}, client: v{})", + gateway.identity(), + version, + CURRENT_PROTOCOL_VERSION + ); + Ok(()) + } + ServerResponse::Error { message } => { + warn!( + "Gateway {} returned error during protocol check: {}", + gateway.identity(), + message + ); + Err(ClientCoreError::GatewayClientError { + gateway_id: gateway.identity().to_base58_string(), + source: *Box::new( + nym_gateway_client::error::GatewayClientError::GatewayError(message), + ), + }) + } + _ => { + warn!( + "Gateway {} returned unexpected response during protocol check", + gateway.identity() + ); + Err(ClientCoreError::GatewayClientError { + gateway_id: gateway.identity().to_base58_string(), + source: *Box::new( + nym_gateway_client::error::GatewayClientError::UnexpectedResponse { + name: response.name().to_string(), + }, + ), + }) + } + } + } + Ok(Some(Ok(_))) => { + warn!( + "Gateway {} sent non-text response during protocol check", + gateway.identity() + ); + Err(ClientCoreError::GatewayConnectionAbruptlyClosed) + } + Ok(Some(Err(e))) => { + warn!( + "WebSocket error during protocol check with {}: {}", + gateway.identity(), + e + ); + Err(e.into()) + } + Ok(None) => { + warn!( + "Gateway {} closed connection during protocol check", + gateway.identity() + ); + Err(ClientCoreError::GatewayConnectionAbruptlyClosed) + } + } +} + pub async fn choose_gateway_by_latency( rng: &mut R, gateways: &[G], diff --git a/nym-api/src/epoch_operations/simulation.rs b/nym-api/src/epoch_operations/simulation.rs index ab0906823c..8d3a7d73b7 100644 --- a/nym-api/src/epoch_operations/simulation.rs +++ b/nym-api/src/epoch_operations/simulation.rs @@ -189,6 +189,20 @@ impl<'a> SimulationCoordinator<'a> { ) .await; + // Calculate average reliability for old method (mean of all node reliabilities) + let node_reliabilities: Vec = performance_map.values() + .map(|p| p.naive_to_f64() * 100.0) + .filter(|&r| r > 0.0) // Only include nodes with non-zero reliability + .collect(); + + let (mean_reliability, median_reliability) = if !node_reliabilities.is_empty() { + let mean = node_reliabilities.iter().sum::() / node_reliabilities.len() as f64; + let median = calculate_median(&node_reliabilities); + (Some((mean * 100.0).round() / 100.0), Some((median * 100.0).round() / 100.0)) + } else { + (None, None) + }; + // Create route analysis for old method let route_analysis = SimulatedRouteAnalysis { id: 0, // Will be set by database @@ -197,11 +211,13 @@ impl<'a> SimulationCoordinator<'a> { total_routes_analyzed: 0, // Old method doesn't use route data successful_routes: 0, failed_routes: 0, - average_route_reliability: None, + average_route_reliability: mean_reliability, time_window_hours: 24, // Old method uses 24h - analysis_parameters: Some( - "{\"method\":\"cache_based\",\"data_source\":\"status_cache\"}".to_string(), - ), + analysis_parameters: Some(format!( + "{{\"method\":\"cache_based\",\"data_source\":\"status_cache\",\"median_reliability\":{},\"nodes_analyzed\":{}}}", + median_reliability.unwrap_or(0.0), + node_reliabilities.len() + )), calculated_at: OffsetDateTime::now_utc().unix_timestamp(), }; @@ -265,23 +281,16 @@ impl<'a> SimulationCoordinator<'a> { let mut route_reliability_map = HashMap::new(); let mut total_routes = 0u32; let mut successful_routes = 0u32; - let mut reliability_sum = 0.0; - let mut reliability_count = 0u32; for node_reliability in &corrected_reliabilities { let total_samples = node_reliability.pos_samples_in_interval + node_reliability.neg_samples_in_interval; total_routes += total_samples; successful_routes += node_reliability.pos_samples_in_interval; - - if total_samples > 0 { - reliability_sum += node_reliability.reliability; - reliability_count += 1; - } - performance_map.insert( node_reliability.node_id, - Performance::naive_try_from_f64(node_reliability.reliability).unwrap_or_default(), + Performance::naive_try_from_f64(node_reliability.reliability / 100.0) + .unwrap_or_default(), ); // Store sample counts for detailed performance records @@ -298,6 +307,7 @@ impl<'a> SimulationCoordinator<'a> { let rewarded_nodes = self.calculate_rewards_for_nodes(rewarded_set, reward_params, &performance_map); + // Convert to simulation data structures let node_performance = self .convert_to_simulated_performance( @@ -320,6 +330,20 @@ impl<'a> SimulationCoordinator<'a> { ) .await; + // Calculate average reliability for new method (mean of all node reliabilities) + let node_reliabilities: Vec = corrected_reliabilities.iter() + .filter(|n| n.pos_samples_in_interval + n.neg_samples_in_interval > 0) + .map(|n| n.reliability) + .collect(); + + let (mean_reliability, median_reliability) = if !node_reliabilities.is_empty() { + let mean = node_reliabilities.iter().sum::() / node_reliabilities.len() as f64; + let median = calculate_median(&node_reliabilities); + (Some((mean * 100.0).round() / 100.0), Some((median * 100.0).round() / 100.0)) + } else { + (None, None) + }; + // Create route analysis for new method let route_analysis = SimulatedRouteAnalysis { id: 0, // Will be set by database @@ -328,16 +352,14 @@ impl<'a> SimulationCoordinator<'a> { total_routes_analyzed: total_routes, successful_routes, failed_routes: total_routes - successful_routes, - average_route_reliability: if reliability_count > 0 { - Some(reliability_sum * 100.0 / reliability_count as f64) - } else { - None - }, + average_route_reliability: mean_reliability, time_window_hours: self.config.new_method_time_window_hours, analysis_parameters: Some(format!( - "{{\"method\":\"route_based\",\"time_window_hours\":{},\"corrected_routes\":{}}}", + "{{\"method\":\"route_based\",\"time_window_hours\":{},\"corrected_routes\":{},\"median_reliability\":{},\"nodes_analyzed\":{}}}", self.config.new_method_time_window_hours, - corrected_reliabilities.len() + corrected_reliabilities.len(), + median_reliability.unwrap_or(0.0), + node_reliabilities.len() )), calculated_at: OffsetDateTime::now_utc().unix_timestamp(), }; @@ -652,3 +674,20 @@ impl EpochAdvancer { } } } + +/// Calculate median of a vector of f64 values +fn calculate_median(values: &[f64]) -> f64 { + if values.is_empty() { + return 0.0; + } + + let mut sorted = values.to_vec(); + sorted.sort_by(|a, b| a.partial_cmp(b).unwrap_or(std::cmp::Ordering::Equal)); + + let len = sorted.len(); + if len % 2 == 0 { + (sorted[len / 2 - 1] + sorted[len / 2]) / 2.0 + } else { + sorted[len / 2] + } +} diff --git a/nym-api/src/simulation_api/handlers/mod.rs b/nym-api/src/simulation_api/handlers/mod.rs index c1ad045230..f2c3e79e15 100644 --- a/nym-api/src/simulation_api/handlers/mod.rs +++ b/nym-api/src/simulation_api/handlers/mod.rs @@ -594,13 +594,13 @@ fn build_node_comparisons_with_rankings( // Calculate differences let reliability_difference = match (&old_perf, &new_perf) { - (Some(old), Some(new)) => Some(new.reliability_score - old.reliability_score), + (Some(old), Some(new)) => Some(((new.reliability_score - old.reliability_score) * 100.0).round() / 100.0), _ => None, }; let performance_delta_percentage = match (&old_perf, &new_perf) { (Some(old), Some(new)) if old.reliability_score != 0.0 => Some( - (new.reliability_score - old.reliability_score) / old.reliability_score * 100.0, + (((new.reliability_score - old.reliability_score) / old.reliability_score * 100.0) * 100.0).round() / 100.0, ), _ => None, }; @@ -707,14 +707,14 @@ fn calculate_summary_statistics(comparisons: &[NodeMethodComparison]) -> Compari nodes_improved: improvements, nodes_degraded: degradations, nodes_unchanged: unchanged, - average_reliability_old, - average_reliability_new, - median_reliability_old, - median_reliability_new, - reliability_std_dev_old, - reliability_std_dev_new, - max_improvement, - max_degradation, + average_reliability_old: (average_reliability_old * 100.0).round() / 100.0, + average_reliability_new: (average_reliability_new * 100.0).round() / 100.0, + median_reliability_old: (median_reliability_old * 100.0).round() / 100.0, + median_reliability_new: (median_reliability_new * 100.0).round() / 100.0, + reliability_std_dev_old: (reliability_std_dev_old * 100.0).round() / 100.0, + reliability_std_dev_new: (reliability_std_dev_new * 100.0).round() / 100.0, + max_improvement: (max_improvement * 100.0).round() / 100.0, + max_degradation: (max_degradation * 100.0).round() / 100.0, } } @@ -769,11 +769,13 @@ async fn get_route_analysis_comparison( _ => 0, }; - let success_rate_difference = match (&old_analysis, &new_analysis) { + // For comparison, we now look at the average reliability difference between methods + let reliability_difference = match (&old_analysis, &new_analysis) { (Some(old), Some(new)) => { - let old_rate = old.successful_routes as f64 / old.total_routes_analyzed as f64; - let new_rate = new.successful_routes as f64 / new.total_routes_analyzed as f64; - Some(new_rate - old_rate) + match (old.average_route_reliability, new.average_route_reliability) { + (Some(old_avg), Some(new_avg)) => Some(((new_avg - old_avg) * 100.0).round() / 100.0), + _ => None + } } _ => None, }; @@ -783,7 +785,7 @@ async fn get_route_analysis_comparison( new_method: new_analysis, time_window_difference_hours, route_coverage_difference, - success_rate_difference, + success_rate_difference: reliability_difference, }) } diff --git a/nym-api/src/simulation_api/models.rs b/nym-api/src/simulation_api/models.rs index 8a018ac7dd..75d1be1061 100644 --- a/nym-api/src/simulation_api/models.rs +++ b/nym-api/src/simulation_api/models.rs @@ -80,10 +80,10 @@ impl From for NodePerformanceData { node_id: perf.node_id, node_type: perf.node_type, identity_key: perf.identity_key, - reliability_score: perf.reliability_score, + reliability_score: (perf.reliability_score * 100.0).round() / 100.0, positive_samples: perf.positive_samples, negative_samples: perf.negative_samples, - work_factor: perf.work_factor, + work_factor: perf.work_factor.map(|w| (w * 100.0).round() / 100.0), calculation_method: perf.calculation_method, calculated_at: perf.calculated_at, } @@ -109,12 +109,12 @@ impl From for PerformanceComparisonData { Self { node_id: comparison.node_id, node_type: comparison.node_type, - performance_score: comparison.performance_score, - work_factor: comparison.work_factor, + performance_score: (comparison.performance_score * 100.0).round() / 100.0, + work_factor: (comparison.work_factor * 100.0).round() / 100.0, calculation_method: comparison.calculation_method, positive_samples: comparison.positive_samples, negative_samples: comparison.negative_samples, - route_success_rate: comparison.route_success_rate, + route_success_rate: comparison.route_success_rate.map(|r| (r * 100.0).round() / 100.0), calculated_at: comparison.calculated_at, } } @@ -128,6 +128,7 @@ pub struct RouteAnalysisData { pub successful_routes: u32, pub failed_routes: u32, pub average_route_reliability: Option, + pub median_route_reliability: Option, pub time_window_hours: u32, pub analysis_parameters: Option, pub calculated_at: i64, @@ -135,12 +136,19 @@ pub struct RouteAnalysisData { impl From for RouteAnalysisData { fn from(analysis: SimulatedRouteAnalysis) -> Self { + // Extract median from analysis_parameters JSON if available + let median_route_reliability = analysis.analysis_parameters.as_ref() + .and_then(|params| serde_json::from_str::(params).ok()) + .and_then(|json| json.get("median_reliability").and_then(|v| v.as_f64())) + .map(|m| (m * 100.0).round() / 100.0); + Self { calculation_method: analysis.calculation_method, total_routes_analyzed: analysis.total_routes_analyzed, successful_routes: analysis.successful_routes, failed_routes: analysis.failed_routes, - average_route_reliability: analysis.average_route_reliability, + average_route_reliability: analysis.average_route_reliability.map(|a| (a * 100.0).round() / 100.0), + median_route_reliability, time_window_hours: analysis.time_window_hours, analysis_parameters: analysis.analysis_parameters, calculated_at: analysis.calculated_at, @@ -197,7 +205,7 @@ pub struct RouteAnalysisComparison { pub new_method: Option, pub time_window_difference_hours: i32, // new - old pub route_coverage_difference: i32, // new total routes - old total routes - pub success_rate_difference: Option, // new success rate - old success rate + pub success_rate_difference: Option, // new average reliability - old average reliability } /// Export format options diff --git a/nym-network-monitor/Cargo.toml b/nym-network-monitor/Cargo.toml index c213995b4b..c5b6ebf398 100644 --- a/nym-network-monitor/Cargo.toml +++ b/nym-network-monitor/Cargo.toml @@ -23,11 +23,15 @@ rand_chacha = { workspace = true } reqwest = { workspace = true, features = ["json"] } serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true } +socket2 = "0.5" tokio = { workspace = true, features = ["macros", "time"] } tokio-util = { workspace = true } +tower = { workspace = true } +tower-http = { workspace = true, features = ["timeout", "trace"] } utoipa = { workspace = true, features = ["axum_extras"] } utoipa-swagger-ui = { workspace = true, features = ["axum"] } tokio-postgres = { workspace = true } +tracing = { workspace = true } # internal nym-bin-common = { path = "../common/bin-common", features = ["basic_tracing"] } diff --git a/nym-network-monitor/locustfile.py b/nym-network-monitor/locustfile.py index de59b514a6..eb7dc84e54 100644 --- a/nym-network-monitor/locustfile.py +++ b/nym-network-monitor/locustfile.py @@ -1,5 +1,11 @@ import time +import logging from locust import HttpUser, task +from requests.exceptions import ConnectionError + +# Configure logging to see what's happening +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger(__name__) class SendMsg(HttpUser): @@ -8,8 +14,14 @@ class SendMsg(HttpUser): try: response = self.client.post("/v1/send") if response.status_code == 503: + logger.warning(f"Got 503 Service Unavailable, sleeping for 1 second") time.sleep(1) response.raise_for_status() # Raise an exception for bad status codes (4xx or 5xx) - except Exception: # Catch other exceptions, including those raised by raise_for_status() - # You might want to log this error or handle it differently - pass + except ConnectionError as e: + # This catches ConnectionRefused errors + logger.error(f"Connection refused, backing off for 5 seconds: {e}") + time.sleep(5) # Longer pause for connection errors + except Exception as e: + # Log other errors but don't sleep as long + logger.warning(f"Request failed: {type(e).__name__}: {e}") + time.sleep(0.5) # Brief pause for other errors diff --git a/nym-network-monitor/src/handlers.rs b/nym-network-monitor/src/handlers.rs index f5131c6543..ca255990cf 100644 --- a/nym-network-monitor/src/handlers.rs +++ b/nym-network-monitor/src/handlers.rs @@ -197,12 +197,14 @@ async fn send_receive_mixnet(state: AppState) -> Result { .collect(); let sent_msg = msg.clone(); + debug!("[REQUEST_START] Processing send request {}", msg); + let client = { let mut clients = state.clients().write().await; if let Some(client) = clients.make_contiguous().choose(&mut rand::thread_rng()) { Arc::clone(client) } else { - error!("No clients currently available"); + error!("No clients currently available - this may cause connection refused errors"); return Err(StatusCode::SERVICE_UNAVAILABLE); } }; @@ -249,12 +251,16 @@ async fn send_receive_mixnet(state: AppState) -> Result { match result { Ok(_) => {} Err(e) => { - error!("Failed to send/receive message: {e}"); + error!( + "[REQUEST_ERROR] {} - Failed to send/receive message: {e}", + sent_msg + ); return Err(StatusCode::GATEWAY_TIMEOUT); } } } + debug!("[REQUEST_SUCCESS] {} - Message sent successfully", sent_msg); Ok(sent_msg) } diff --git a/nym-network-monitor/src/http.rs b/nym-network-monitor/src/http.rs index f88694f267..bc24af84a3 100644 --- a/nym-network-monitor/src/http.rs +++ b/nym-network-monitor/src/http.rs @@ -5,12 +5,15 @@ use crate::handlers::{ FragmentsSent, }; use axum::routing::{get, post}; -use axum::Router; -use log::info; +use axum::{Router}; +use log::{debug, info, warn}; use nym_sphinx::chunking::fragment::FragmentHeader; use nym_sphinx::chunking::{ReceivedFragment, SentFragment}; use std::net::SocketAddr; use tokio_util::sync::CancellationToken; +use tower::ServiceBuilder; +use tower_http::timeout::TimeoutLayer; +use tower_http::trace::TraceLayer; use utoipa::OpenApi; use utoipa_swagger_ui::SwaggerUi; @@ -19,6 +22,7 @@ use crate::ClientsWrapper; pub struct HttpServer { listener: SocketAddr, cancel: CancellationToken, + tcp_backlog: i32, } #[derive(OpenApi)] @@ -59,8 +63,12 @@ impl AppState { } impl HttpServer { - pub fn new(listener: SocketAddr, cancel: CancellationToken) -> Self { - HttpServer { listener, cancel } + pub fn new(listener: SocketAddr, cancel: CancellationToken, tcp_backlog: i32) -> Self { + HttpServer { + listener, + cancel, + tcp_backlog, + } } pub async fn run(self, clients: ClientsWrapper) -> anyhow::Result<()> { @@ -78,15 +86,46 @@ impl HttpServer { .route("/v1/node_stats/:mix_id", get(node_stats_handler)) .route("/v1/node_stats", get(all_nodes_stats_handler)) .route("/v1/received", get(recv_handler)) + .layer( + ServiceBuilder::new() + // Add request tracing + .layer( + TraceLayer::new_for_http() + .on_request(|_request: &axum::http::Request<_>, _span: &tracing::Span| { + debug!("[HTTP_REQUEST] New connection accepted"); + }) + .on_failure(|error: tower_http::classify::ServerErrorsFailureClass, latency: std::time::Duration, _span: &tracing::Span| { + warn!("[HTTP_ERROR] Request failed with error: {:?}, latency: {:?}", error, latency); + }) + ) + // Add a timeout layer to prevent hanging connections + .layer(TimeoutLayer::new(std::time::Duration::from_secs(30))) + ) .with_state(state); - let listener = tokio::net::TcpListener::bind(self.listener).await?; + // Configure socket with higher backlog to handle more concurrent connections + let socket = socket2::Socket::new( + socket2::Domain::for_address(self.listener), + socket2::Type::STREAM, + Some(socket2::Protocol::TCP), + )?; + + // Enable SO_REUSEADDR to avoid "Address already in use" errors + socket.set_reuse_address(true)?; + + // Set a higher backlog (default is often 128) + socket.bind(&self.listener.into())?; + socket.listen(self.tcp_backlog)?; // Use configurable backlog + + let listener = tokio::net::TcpListener::from_std(socket.into())?; let server_future = axum::serve(listener, app).with_graceful_shutdown(self.cancel.cancelled_owned()); info!("##########################################################################################"); - info!("######################### HTTP server running, with {} clients ############################################", n_clients); + info!("######################### HTTP server running on {} with {} clients ############################################", self.listener, n_clients); + info!("######################### TCP backlog set to {} connections ############################################", self.tcp_backlog); info!("##########################################################################################"); + info!("[HTTP_SERVER] Server started and ready to accept connections"); server_future.await?; diff --git a/nym-network-monitor/src/main.rs b/nym-network-monitor/src/main.rs index 27fbcbd044..4fb7d6854a 100644 --- a/nym-network-monitor/src/main.rs +++ b/nym-network-monitor/src/main.rs @@ -50,8 +50,12 @@ async fn make_clients( if spawned_clients >= n_clients { info!("New client will be spawned in {} seconds", lifetime); tokio::time::sleep(tokio::time::Duration::from_secs(lifetime)).await; - info!("Removing oldest client"); + info!("[CLIENT_ROTATION_START] Beginning client rotation"); if let Some(dropped_client) = clients.write().await.pop_front() { + info!( + "[CLIENT_ROTATION] Popped client from queue, current ref count: {}", + Arc::strong_count(&dropped_client) + ); const CLIENT_DROP_TIMEOUT: Duration = Duration::from_secs(30); let start = tokio::time::Instant::now(); @@ -60,18 +64,23 @@ async fn make_clients( Ok(client) => { let client_handle = client.into_inner(); client_handle.disconnect().await; - info!("Successfully disconnected client immediately"); + info!("[CLIENT_ROTATION_END] Successfully disconnected client immediately"); } Err(dropped_client) => { // Fallback: wait with timeout for references to drop - info!("Client still has references, waiting for cleanup with timeout"); + info!("[CLIENT_ROTATION_BLOCKING] Client still has {} references, waiting for cleanup with timeout", Arc::strong_count(&dropped_client)); while start.elapsed() < CLIENT_DROP_TIMEOUT { - if Arc::strong_count(&dropped_client) == 1 { + let elapsed = start.elapsed(); + let ref_count = Arc::strong_count(&dropped_client); + if elapsed.as_secs() % 5 == 0 && elapsed.subsec_millis() < 100 { + info!("[CLIENT_ROTATION_WAITING] Still waiting for client cleanup, elapsed: {:?}, ref_count: {}", elapsed, ref_count); + } + if ref_count == 1 { match Arc::try_unwrap(dropped_client) { Ok(client) => { let client_handle = client.into_inner(); client_handle.disconnect().await; - info!("Successfully disconnected client after waiting"); + info!("[CLIENT_ROTATION_END] Successfully disconnected client after waiting {:?}", start.elapsed()); break; } Err(_) => { @@ -85,7 +94,7 @@ async fn make_clients( if start.elapsed() >= CLIENT_DROP_TIMEOUT { warn!( - "Client drop timed out after {:?}, forcing drop", + "[CLIENT_ROTATION_TIMEOUT] Client drop timed out after {:?}, forcing drop.", CLIENT_DROP_TIMEOUT ); // Client will be dropped when Arc goes out of scope @@ -94,7 +103,7 @@ async fn make_clients( } } } - info!("Spawning new client"); + info!("[CLIENT_SPAWN_START] Spawning new client"); let client = match make_client(topology.clone()).await { Ok(client) => client, Err(err) => { @@ -106,6 +115,7 @@ async fn make_clients( .write() .await .push_back(Arc::new(RwLock::new(client))); + info!("[CLIENT_SPAWN_END] New client added to pool"); } } @@ -165,6 +175,9 @@ struct Args { #[arg(long, env = "NYM_APIS", value_delimiter = ',')] nym_apis: Option>, + + #[arg(long, env = "TCP_BACKLOG", default_value_t = 1024)] + tcp_backlog: i32, } fn generate_key_pair() -> Result<()> { @@ -273,9 +286,10 @@ async fn main() -> Result<()> { let clients_server = clients.clone(); + let tcp_backlog = args.tcp_backlog; let server_handle = tokio::spawn(async move { let socket = SocketAddr::new(IpAddr::V4(Ipv4Addr::from_str(&args.host)?), args.port); - let server = HttpServer::new(socket, server_cancel_token); + let server = HttpServer::new(socket, server_cancel_token, tcp_backlog); server.run(clients_server).await }); diff --git a/sdk/rust/nym-sdk/src/mixnet/client.rs b/sdk/rust/nym-sdk/src/mixnet/client.rs index 47e958cb38..414894c7f9 100644 --- a/sdk/rust/nym-sdk/src/mixnet/client.rs +++ b/sdk/rust/nym-sdk/src/mixnet/client.rs @@ -25,7 +25,7 @@ use nym_client_core::client::{ }; use nym_client_core::config::{DebugConfig, ForgetMe, RememberMe, StatsReporting}; use nym_client_core::error::ClientCoreError; -use nym_client_core::init::helpers::gateways_for_init; +use nym_client_core::init::helpers::gateways_for_init_with_protocol_validation; use nym_client_core::init::setup_gateway; use nym_client_core::init::types::{GatewaySelectionSpecification, GatewaySetup}; use nym_credentials_interface::TicketType; @@ -546,7 +546,7 @@ where let topology_cfg = &self.config.debug_config.topology; let mut rng = OsRng; - let available_gateways = gateways_for_init( + let available_gateways = gateways_for_init_with_protocol_validation( &mut rng, &nym_api_endpoints, user_agent,