diff --git a/Cargo.lock b/Cargo.lock index 29cf1e36e18..3118c459bd7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -54,14 +54,14 @@ dependencies = [ [[package]] name = "ahash" -version = "0.8.11" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" dependencies = [ "cfg-if", "once_cell", "version_check", - "zerocopy 0.7.35", + "zerocopy", ] [[package]] @@ -137,9 +137,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.97" +version = "1.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f" +checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" [[package]] name = "arbitrary" @@ -199,7 +199,7 @@ checksum = "965c2d33e53cb6b267e148a4cb0760bc01f4904c1cd4bb4002a085bb016d1490" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", "synstructure", ] @@ -211,7 +211,7 @@ checksum = "3109e49b1e4909e9db6515a30c633684d68cdeaa252f215214cb4fa1a5bfee2c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", "synstructure", ] @@ -223,7 +223,7 @@ checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -267,14 +267,15 @@ dependencies = [ [[package]] name = "async-executor" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30ca9a001c1e8ba5149f91a74362376cc6bc5b919d92d988668657bd570bdcec" +checksum = "bb812ffb58524bdd10860d7d974e2f01cc0950c2438a74ee5ec2e2280c6c4ffa" dependencies = [ "async-task", "concurrent-queue", "fastrand", "futures-lite", + "pin-project-lite", "slab", ] @@ -372,7 +373,7 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -455,7 +456,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -472,7 +473,7 @@ checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -595,9 +596,9 @@ dependencies = [ [[package]] name = "backtrace" -version = "0.3.74" +version = "0.3.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" +checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" dependencies = [ "addr2line", "cfg-if", @@ -655,9 +656,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.9.0" +version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" +checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" [[package]] name = "blake2" @@ -791,9 +792,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.19" +version = "1.2.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e3a13707ac958681c13b39b458c073d0d9bc8a22cb1b2f4c8e55eb72c13f362" +checksum = "5f4ac86a9e5bc1e2b3449ab9d7d3a6a405e3d1bb28d7b9be8614f55846ae3766" dependencies = [ "shlex", ] @@ -896,9 +897,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.35" +version = "4.5.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8aa86934b44c19c50f87cc2790e19f54f7a67aedb64101c2e1a2e5ecfb73944" +checksum = "ed93b9805f8ba930df42c2590f05453d5ec36cbb85d018868a5b24d31f6ac000" dependencies = [ "clap_builder", "clap_derive", @@ -906,9 +907,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.35" +version = "4.5.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2414dbb2dd0695280da6ea9261e327479e9d37b0630f6b53ba2a11c60c679fd9" +checksum = "379026ff283facf611b0ea629334361c4211d1b12ee01024eec1591133b04120" dependencies = [ "anstream", "anstyle", @@ -925,7 +926,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -1015,9 +1016,9 @@ dependencies = [ [[package]] name = "crc" -version = "3.2.1" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636" +checksum = "9710d3b3739c2e349eb44fe848ad0b7c8cb1e42bd87ee49371df2f7acaf3e675" dependencies = [ "crc-catalog", ] @@ -1173,20 +1174,20 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] name = "data-encoding" -version = "2.8.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "575f75dfd25738df5b91b8e43e14d44bda14637a58fae779fd2b064f8bf3e010" +checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" [[package]] name = "data-encoding-macro" -version = "0.1.17" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f9724adfcf41f45bf652b3995837669d73c4d49a1b5ac1ff82905ac7d9b5558" +checksum = "47ce6c96ea0102f01122a185683611bd5ac8d99e62bc59dd12e6bda344ee673d" dependencies = [ "data-encoding", "data-encoding-macro-internal", @@ -1194,12 +1195,12 @@ dependencies = [ [[package]] name = "data-encoding-macro-internal" -version = "0.1.15" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18e4fdb82bd54a12e42fb58a800dcae6b9e13982238ce2296dc3570b92148e1f" +checksum = "8d162beedaa69905488a8da94f5ac3edb4dd4788b732fadb7bd120b2625c1976" dependencies = [ "data-encoding", - "syn 1.0.109", + "syn 2.0.101", ] [[package]] @@ -1217,9 +1218,9 @@ dependencies = [ [[package]] name = "der" -version = "0.7.9" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" +checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" dependencies = [ "const-oid", "pem-rfc7468", @@ -1277,23 +1278,23 @@ dependencies = [ [[package]] name = "dirs" -version = "5.0.1" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" +checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e" dependencies = [ "dirs-sys", ] [[package]] name = "dirs-sys" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab" dependencies = [ "libc", "option-ext", "redox_users", - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] @@ -1304,7 +1305,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -1407,7 +1408,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -1451,9 +1452,9 @@ checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "errno" -version = "0.3.11" +version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "976dd42dc7e85965fe702eb8164f21f450704bdde31faefd6471dba214cb594e" +checksum = "cea14ef9355e3beab063703aa9dab15afd25f0667c341310c1e5274bb1d0da18" dependencies = [ "libc", "windows-sys 0.59.0", @@ -1636,7 +1637,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -1704,15 +1705,16 @@ dependencies = [ [[package]] name = "generator" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc6bd114ceda131d3b1d665eba35788690ad37f5916457286b32ab6fd3c438dd" +checksum = "d18470a76cb7f8ff746cf1f7470914f900252ec36bbc40b569d74b1258446827" dependencies = [ + "cc", "cfg-if", "libc", "log", "rustversion", - "windows 0.58.0", + "windows 0.61.1", ] [[package]] @@ -1739,9 +1741,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" dependencies = [ "cfg-if", "js-sys", @@ -1752,9 +1754,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0" +checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" dependencies = [ "cfg-if", "js-sys", @@ -1836,9 +1838,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.8" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5017294ff4bb30944501348f6f8e42e6ad28f42c8bbef7a74029aff064a4e3c2" +checksum = "a9421a676d1b147b16b82c9225157dc629087ef8ec4d5e2960f9437a90dac0a5" dependencies = [ "atomic-waker", "bytes", @@ -1880,9 +1882,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.2" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +checksum = "84b26c544d002229e640969970a2e74021aadf6e2f96372b9c58eff97de08eb3" dependencies = [ "allocator-api2", "equivalent", @@ -1918,9 +1920,9 @@ checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" [[package]] name = "hermit-abi" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbd780fe5cc30f81464441920d82ac8740e2e46b29a6fad543ddd075229ce37e" +checksum = "f154ce46856750ed433c8649605bf7ed2de3bc35fd9d2a9f30cddd873c80cb08" [[package]] name = "hex" @@ -1957,7 +1959,7 @@ dependencies = [ "idna", "ipnet", "once_cell", - "rand 0.9.0", + "rand 0.9.1", "socket2", "thiserror 2.0.12", "tinyvec", @@ -1979,7 +1981,7 @@ dependencies = [ "moka", "once_cell", "parking_lot", - "rand 0.9.0", + "rand 0.9.1", "resolv-conf", "smallvec", "thiserror 2.0.12", @@ -2021,17 +2023,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "hostname" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56f203cd1c76362b69e3863fd987520ac36cf70a8c92627449b2f64a8cf7d65" -dependencies = [ - "cfg-if", - "libc", - "windows-link", -] - [[package]] name = "http" version = "0.2.12" @@ -2131,7 +2122,7 @@ dependencies = [ "tokio", "tokio-rustls", "tower-service", - "webpki-roots", + "webpki-roots 0.26.11", ] [[package]] @@ -2165,9 +2156,9 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.11" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497bbc33a26fdd4af9ed9c70d63f61cf56a938375fbb32df34db9b1cd6d643f2" +checksum = "cf9f1e950e0d9d1d3c47184416723cf29c0d1f93bd8cccf37e4beb6b44f31710" dependencies = [ "bytes", "futures-channel", @@ -2185,21 +2176,22 @@ dependencies = [ [[package]] name = "icu_collections" -version = "1.5.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" dependencies = [ "displaydoc", + "potential_utf", "yoke", "zerofrom", "zerovec", ] [[package]] -name = "icu_locid" -version = "1.5.0" +name = "icu_locale_core" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" dependencies = [ "displaydoc", "litemap", @@ -2208,31 +2200,11 @@ dependencies = [ "zerovec", ] -[[package]] -name = "icu_locid_transform" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" -dependencies = [ - "displaydoc", - "icu_locid", - "icu_locid_transform_data", - "icu_provider", - "tinystr", - "zerovec", -] - -[[package]] -name = "icu_locid_transform_data" -version = "1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7515e6d781098bf9f7205ab3fc7e9709d34554ae0b21ddbcb5febfa4bc7df11d" - [[package]] name = "icu_normalizer" -version = "1.5.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" dependencies = [ "displaydoc", "icu_collections", @@ -2240,67 +2212,54 @@ dependencies = [ "icu_properties", "icu_provider", "smallvec", - "utf16_iter", - "utf8_iter", - "write16", "zerovec", ] [[package]] name = "icu_normalizer_data" -version = "1.5.1" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5e8338228bdc8ab83303f16b797e177953730f601a96c25d10cb3ab0daa0cb7" +checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" [[package]] name = "icu_properties" -version = "1.5.1" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b" dependencies = [ "displaydoc", "icu_collections", - "icu_locid_transform", + "icu_locale_core", "icu_properties_data", "icu_provider", - "tinystr", + "potential_utf", + "zerotrie", "zerovec", ] [[package]] name = "icu_properties_data" -version = "1.5.1" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85fb8799753b75aee8d2a21d7c14d9f38921b54b3dbda10f5a3c7a7b82dba5e2" +checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632" [[package]] name = "icu_provider" -version = "1.5.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" dependencies = [ "displaydoc", - "icu_locid", - "icu_provider_macros", + "icu_locale_core", "stable_deref_trait", "tinystr", "writeable", "yoke", "zerofrom", + "zerotrie", "zerovec", ] -[[package]] -name = "icu_provider_macros" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.100", -] - [[package]] name = "identify-example" version = "0.1.0" @@ -2324,9 +2283,9 @@ dependencies = [ [[package]] name = "idna_adapter" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" dependencies = [ "icu_normalizer", "icu_properties", @@ -2381,7 +2340,7 @@ dependencies = [ "hyper", "hyper-util", "log", - "rand 0.9.0", + "rand 0.9.1", "tokio", "url", "xmltree", @@ -2404,7 +2363,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" dependencies = [ "equivalent", - "hashbrown 0.15.2", + "hashbrown 0.15.3", ] [[package]] @@ -2523,7 +2482,7 @@ version = "0.4.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9" dependencies = [ - "hermit-abi 0.5.0", + "hermit-abi 0.5.1", "libc", "windows-sys 0.59.0", ] @@ -2560,9 +2519,9 @@ checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "jiff" -version = "0.2.6" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f33145a5cbea837164362c7bd596106eb7c5198f97d1ba6f6ebb3223952e488" +checksum = "f02000660d30638906021176af16b17498bd0d12813dbfe7b276d8bc7f3c0806" dependencies = [ "jiff-static", "log", @@ -2573,13 +2532,13 @@ dependencies = [ [[package]] name = "jiff-static" -version = "0.2.6" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43ce13c40ec6956157a3635d97a1ee2df323b263f09ea14165131289cb0f5c19" +checksum = "f3c30758ddd7188629c6713fc45d1188af4f44c90582311d0c8d8c9907f60c48" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -2644,9 +2603,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.171" +version = "0.2.172" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6" +checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" [[package]] name = "libp2p" @@ -2657,7 +2616,7 @@ dependencies = [ "either", "futures", "futures-timer", - "getrandom 0.2.15", + "getrandom 0.2.16", "libp2p-allow-block-list", "libp2p-autonat", "libp2p-connection-limits", @@ -2886,7 +2845,7 @@ dependencies = [ "fnv", "futures", "futures-timer", - "getrandom 0.2.15", + "getrandom 0.2.16", "hashlink", "hex_fmt", "libp2p-core 0.43.0", @@ -3381,7 +3340,7 @@ dependencies = [ "fnv", "futures", "futures-timer", - "getrandom 0.2.15", + "getrandom 0.2.16", "libp2p-core 0.43.1", "libp2p-identify", "libp2p-identity", @@ -3410,7 +3369,7 @@ version = "0.35.1" dependencies = [ "heck", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -3579,7 +3538,7 @@ version = "0.4.0" dependencies = [ "bytes", "futures", - "getrandom 0.2.15", + "getrandom 0.2.16", "hex", "js-sys", "libp2p-core 0.43.1", @@ -3613,7 +3572,7 @@ dependencies = [ "thiserror 2.0.12", "tracing", "url", - "webpki-roots", + "webpki-roots 0.26.11", ] [[package]] @@ -3666,7 +3625,7 @@ dependencies = [ "tokio", "tracing", "yamux 0.12.1", - "yamux 0.13.4", + "yamux 0.13.5", ] [[package]] @@ -3681,7 +3640,7 @@ dependencies = [ "thiserror 2.0.12", "tracing", "yamux 0.12.1", - "yamux 0.13.4", + "yamux 0.13.5", ] [[package]] @@ -3690,7 +3649,7 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", "libc", ] @@ -3708,9 +3667,9 @@ checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" [[package]] name = "litemap" -version = "0.7.5" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856" +checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" [[package]] name = "lock_api" @@ -3750,9 +3709,15 @@ version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" dependencies = [ - "hashbrown 0.15.2", + "hashbrown 0.15.3", ] +[[package]] +name = "lru-slab" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" + [[package]] name = "matchers" version = "0.1.0" @@ -4191,7 +4156,7 @@ version = "0.10.72" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fedfea7d58a1f73118430a55da6a286e7b044961736ce96a16a17068ea25e5da" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", "cfg-if", "foreign-types", "libc", @@ -4208,7 +4173,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -4219,9 +4184,9 @@ checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" [[package]] name = "openssl-sys" -version = "0.9.107" +version = "0.9.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8288979acd84749c744a9014b4382d42b8f7b2592847b5afb2ed29e5d16ede07" +checksum = "e145e1651e858e820e4860f7b9c5e169bc1d8ce1c86043be79fa7b7634821847" dependencies = [ "cc", "libc", @@ -4489,7 +4454,7 @@ checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -4622,6 +4587,15 @@ dependencies = [ "portable-atomic", ] +[[package]] +name = "potential_utf" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585" +dependencies = [ + "zerovec", +] + [[package]] name = "powerfmt" version = "0.2.0" @@ -4634,7 +4608,7 @@ version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" dependencies = [ - "zerocopy 0.8.24", + "zerocopy", ] [[package]] @@ -4648,9 +4622,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.94" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" dependencies = [ "unicode-ident", ] @@ -4687,7 +4661,7 @@ checksum = "440f724eba9f6996b75d63681b0a92b06947f1457076d503a4d2e2c8f56442b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -4710,7 +4684,7 @@ dependencies = [ "itertools 0.14.0", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -4770,9 +4744,9 @@ dependencies = [ [[package]] name = "quinn" -version = "0.11.7" +version = "0.11.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3bd15a6f2967aef83887dcb9fec0014580467e33720d073560cf015a5683012" +checksum = "626214629cda6781b6dc1d316ba307189c85ba657213ce642d9c77670f8202c8" dependencies = [ "async-io", "async-std", @@ -4793,13 +4767,14 @@ dependencies = [ [[package]] name = "quinn-proto" -version = "0.11.10" +version = "0.11.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b820744eb4dc9b57a3398183639c511b5a26d2ed702cedd3febaa1393caa22cc" +checksum = "49df843a9161c85bb8aae55f101bc0bac8bcafd637a620d9122fd7e0b2f7422e" dependencies = [ "bytes", - "getrandom 0.3.2", - "rand 0.9.0", + "getrandom 0.3.3", + "lru-slab", + "rand 0.9.1", "ring", "rustc-hash", "rustls", @@ -4813,9 +4788,9 @@ dependencies = [ [[package]] name = "quinn-udp" -version = "0.5.11" +version = "0.5.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "541d0f57c6ec747a90738a52741d3221f7960e8ac2f0ff4b1a63680e033b4ab5" +checksum = "ee4e529991f949c5e25755532370b8af5d114acae52326361d68d47af64aa842" dependencies = [ "cfg_aliases", "libc", @@ -4866,13 +4841,12 @@ dependencies = [ [[package]] name = "rand" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94" +checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97" dependencies = [ "rand_chacha 0.9.0", "rand_core 0.9.3", - "zerocopy 0.8.24", ] [[package]] @@ -4920,7 +4894,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.15", + "getrandom 0.2.16", ] [[package]] @@ -4929,7 +4903,7 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" dependencies = [ - "getrandom 0.3.2", + "getrandom 0.3.3", ] [[package]] @@ -4996,22 +4970,22 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.11" +version = "0.5.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2f103c6d277498fbceb16e84d317e2a400f160f46904d5f5410848c829511a3" +checksum = "928fca9cf2aa042393a8325b9ead81d2f0df4cb12e1e24cef072922ccd99c5af" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", ] [[package]] name = "redox_users" -version = "0.4.6" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" +checksum = "dd6f9d3d47bdd2ad6945c5015a226ec6155d0bcdfd8f7cd29f86b71f8de99d2b" dependencies = [ - "getrandom 0.2.15", + "getrandom 0.2.16", "libredox", - "thiserror 1.0.69", + "thiserror 2.0.12", ] [[package]] @@ -5125,18 +5099,15 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "webpki-roots", + "webpki-roots 0.26.11", "windows-registry", ] [[package]] name = "resolv-conf" -version = "0.7.1" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48375394603e3dd4b2d64371f7148fd8c7baa2680e28741f2cb8d23b59e3d4c4" -dependencies = [ - "hostname", -] +checksum = "95325155c684b1c89f7765e30bc1c42e4a6da51ca513615660cb8a62ef9a88e3" [[package]] name = "rfc6979" @@ -5156,7 +5127,7 @@ checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" dependencies = [ "cc", "cfg-if", - "getrandom 0.2.15", + "getrandom 0.2.16", "libc", "untrusted", "windows-sys 0.52.0", @@ -5240,9 +5211,9 @@ dependencies = [ [[package]] name = "rust-embed" -version = "8.7.0" +version = "8.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5fbc0ee50fcb99af7cebb442e5df7b5b45e9460ffa3f8f549cd26b862bec49d" +checksum = "025908b8682a26ba8d12f6f2d66b987584a4a87bc024abc5bbc12553a8cd178a" dependencies = [ "rust-embed-impl", "rust-embed-utils", @@ -5251,23 +5222,23 @@ dependencies = [ [[package]] name = "rust-embed-impl" -version = "8.7.0" +version = "8.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bf418c9a2e3f6663ca38b8a7134cc2c2167c9d69688860e8961e3faa731702e" +checksum = "6065f1a4392b71819ec1ea1df1120673418bf386f50de1d6f54204d836d4349c" dependencies = [ "proc-macro2", "quote", "rust-embed-utils", "shellexpand", - "syn 2.0.100", + "syn 2.0.101", "walkdir", ] [[package]] name = "rust-embed-utils" -version = "8.7.0" +version = "8.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d55b95147fe01265d06b3955db798bdaed52e60e2211c41137701b3aba8e21" +checksum = "f6cc0c81648b20b70c491ff8cce00c1c3b223bb8ed2b5d41f0e54c6c4c0a3594" dependencies = [ "globset", "sha2", @@ -5310,7 +5281,7 @@ version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", "errno", "libc", "linux-raw-sys 0.4.15", @@ -5319,11 +5290,11 @@ dependencies = [ [[package]] name = "rustix" -version = "1.0.5" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d97817398dd4bb2e6da002002db259209759911da105da92bec29ccb12cf58bf" +checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", "errno", "libc", "linux-raw-sys 0.9.4", @@ -5332,9 +5303,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.26" +version = "0.23.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df51b5869f3a441595eac5e8ff14d486ff285f7b8c0df8770e49c3b56351f0f0" +checksum = "730944ca083c1c233a75c09f199e973ca499344a2b7ba9e755c457e86fb4a321" dependencies = [ "once_cell", "ring", @@ -5355,18 +5326,19 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c" +checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79" dependencies = [ "web-time 1.1.0", + "zeroize", ] [[package]] name = "rustls-webpki" -version = "0.103.1" +version = "0.103.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fef8b8769aaccf73098557a87cd1816b4f9c7c16811c9c77142aa695c16f2c03" +checksum = "e4a72fe2bcf7a6ac6fd7d0b9e5cb68aeb7d4c0a0271730218b3e92d43b4eb435" dependencies = [ "ring", "rustls-pki-types", @@ -5477,7 +5449,7 @@ version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", "core-foundation", "core-foundation-sys", "libc", @@ -5532,7 +5504,7 @@ checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -5566,7 +5538,7 @@ checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -5603,9 +5575,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.8" +version = "0.10.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ "cfg-if", "cpufeatures", @@ -5633,9 +5605,9 @@ dependencies = [ [[package]] name = "shellexpand" -version = "3.1.0" +version = "3.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da03fa3b94cc19e3ebfc88c4229c49d8f08cdbd1228870a45f0ffdf84988e14b" +checksum = "8b1fdf65dd6331831494dd616b30351c38e96e45921a27745cf98490458b90bb" dependencies = [ "dirs", ] @@ -5648,9 +5620,9 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "signal-hook-registry" -version = "1.4.2" +version = "1.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" +checksum = "9203b8055f63a2a00e2f593bb0510367fe707d7ff1e5c872de2f537b339e5410" dependencies = [ "libc", ] @@ -5818,7 +5790,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -5868,9 +5840,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.100" +version = "2.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" +checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf" dependencies = [ "proc-macro2", "quote", @@ -5888,13 +5860,13 @@ dependencies = [ [[package]] name = "synstructure" -version = "0.13.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -5917,7 +5889,7 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", "core-foundation", "system-configuration-sys", ] @@ -5946,14 +5918,14 @@ checksum = "1ac9aa371f599d22256307c24a9d748c041e548cbf599f35d890f9d365361790" [[package]] name = "tempfile" -version = "3.19.1" +version = "3.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7437ac7763b9b123ccf33c338a5cc1bac6f69b45a136c19bdd8a65e3916435bf" +checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1" dependencies = [ "fastrand", - "getrandom 0.3.2", + "getrandom 0.3.3", "once_cell", - "rustix 1.0.5", + "rustix 1.0.7", "windows-sys 0.59.0", ] @@ -6000,7 +5972,7 @@ checksum = "b72d056365e368fc57a56d0cec9e41b02fb4a3474a61c8735262b1cfebe67425" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -6029,7 +6001,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -6040,7 +6012,7 @@ checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -6108,9 +6080,9 @@ dependencies = [ [[package]] name = "tinystr" -version = "0.7.6" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" dependencies = [ "displaydoc", "zerovec", @@ -6143,9 +6115,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.44.2" +version = "1.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6b88822cbe49de4185e3a4cbf8321dd487cf5fe0c5c65695fef6346371e9c48" +checksum = "2513ca694ef9ede0fb23fe71a4ee4107cb102b9dc1930f6d0fd77aae068ae165" dependencies = [ "backtrace", "bytes", @@ -6167,7 +6139,7 @@ checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -6203,9 +6175,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.14" +version = "0.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b9590b93e6fcc1739458317cccd391ad3955e2bde8913edf6f95f9e65a8f034" +checksum = "66a539a9ad6d5d281510d5bd368c973d636c02dbf8a67300bfb6b950696ad7df" dependencies = [ "bytes", "futures-core", @@ -6217,9 +6189,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.20" +version = "0.8.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd87a5cdd6ffab733b2f74bc4fd7ee5fff6634124999ac278c35fc78c6120148" +checksum = "05ae329d1f08c4d17a59bed7ff5b5a769d062e64a62d34a3261b219e62cd5aae" dependencies = [ "serde", "serde_spanned", @@ -6229,26 +6201,33 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.8" +version = "0.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" +checksum = "3da5db5a963e24bc68be8b17b6fa82814bb22ee8660f192bb182771d498f09a3" dependencies = [ "serde", ] [[package]] name = "toml_edit" -version = "0.22.24" +version = "0.22.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17b4795ff5edd201c7cd6dca065ae59972ce77d1b80fa0a84d94950ece7d1474" +checksum = "310068873db2c5b3e7659d2cc35d21855dbafa50d1ce336397c666e3cb08137e" dependencies = [ "indexmap 2.9.0", "serde", "serde_spanned", "toml_datetime", + "toml_write", "winnow", ] +[[package]] +name = "toml_write" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfb942dfe1d8e29a7ee7fcbde5bd2b9a25fb89aa70caea2eba3bee836ff41076" + [[package]] name = "tonic" version = "0.12.3" @@ -6321,7 +6300,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", "bytes", "futures-util", "http 1.3.1", @@ -6372,7 +6351,7 @@ checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -6469,9 +6448,9 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "trybuild" -version = "1.0.104" +version = "1.0.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ae08be68c056db96f0e6c6dd820727cca756ced9e1f4cc7fdd20e2a55e23898" +checksum = "1c9bf9513a2f4aeef5fdac8677d7d349c79fdbcc03b9c86da6e9d254f1e43be2" dependencies = [ "glob", "serde", @@ -6592,12 +6571,6 @@ version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" -[[package]] -name = "utf16_iter" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" - [[package]] name = "utf8_iter" version = "1.0.4" @@ -6616,7 +6589,7 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "458f7a779bf54acc9f347480ac654f68407d3aab21269a6e3c9f922acd9e2da9" dependencies = [ - "getrandom 0.3.2", + "getrandom 0.3.3", ] [[package]] @@ -6714,7 +6687,7 @@ dependencies = [ "log", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", "wasm-bindgen-shared", ] @@ -6749,7 +6722,7 @@ checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -6784,7 +6757,7 @@ checksum = "17d5042cc5fa009658f9a7333ef24291b1291a25b6382dd68862a7f3b969f69b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -6830,9 +6803,18 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.26.8" +version = "0.26.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9" +dependencies = [ + "webpki-roots 1.0.0", +] + +[[package]] +name = "webpki-roots" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2210b291f7ea53617fbafcc4939f10914214ec15aace5ba62293a668f322c5c9" +checksum = "2853738d1cc4f2da3a225c18ec6c3721abb31961096e9dbf5ab35fa88b19cfdb" dependencies = [ "rustls-pki-types", ] @@ -7053,7 +7035,7 @@ name = "webtransport-tests" version = "0.1.0" dependencies = [ "futures", - "getrandom 0.2.15", + "getrandom 0.2.16", "libp2p-core 0.43.1", "libp2p-identity", "libp2p-noise", @@ -7094,7 +7076,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] @@ -7125,12 +7107,24 @@ dependencies = [ [[package]] name = "windows" -version = "0.58.0" +version = "0.61.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" +checksum = "c5ee8f3d025738cb02bad7868bbb5f8a6327501e870bf51f1b455b0a2454a419" dependencies = [ - "windows-core 0.58.0", - "windows-targets 0.52.6", + "windows-collections", + "windows-core 0.61.2", + "windows-future", + "windows-link", + "windows-numerics", +] + +[[package]] +name = "windows-collections" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8" +dependencies = [ + "windows-core 0.61.2", ] [[package]] @@ -7157,15 +7151,26 @@ dependencies = [ [[package]] name = "windows-core" -version = "0.58.0" +version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" +checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" dependencies = [ - "windows-implement 0.58.0", - "windows-interface 0.58.0", - "windows-result 0.2.0", - "windows-strings 0.1.0", - "windows-targets 0.52.6", + "windows-implement 0.60.0", + "windows-interface 0.59.1", + "windows-link", + "windows-result 0.3.4", + "windows-strings 0.4.2", +] + +[[package]] +name = "windows-future" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e" +dependencies = [ + "windows-core 0.61.2", + "windows-link", + "windows-threading", ] [[package]] @@ -7176,18 +7181,18 @@ checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] name = "windows-implement" -version = "0.58.0" +version = "0.60.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" +checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -7198,18 +7203,18 @@ checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] name = "windows-interface" -version = "0.58.0" +version = "0.59.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" +checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -7218,13 +7223,23 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" +[[package]] +name = "windows-numerics" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1" +dependencies = [ + "windows-core 0.61.2", + "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.2", + "windows-result 0.3.4", "windows-strings 0.3.1", "windows-targets 0.53.0", ] @@ -7240,37 +7255,27 @@ dependencies = [ [[package]] name = "windows-result" -version = "0.2.0" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" -dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-result" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252" +checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" dependencies = [ "windows-link", ] [[package]] name = "windows-strings" -version = "0.1.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319" dependencies = [ - "windows-result 0.2.0", - "windows-targets 0.52.6", + "windows-link", ] [[package]] name = "windows-strings" -version = "0.3.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319" +checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" dependencies = [ "windows-link", ] @@ -7349,6 +7354,15 @@ dependencies = [ "windows_x86_64_msvc 0.53.0", ] +[[package]] +name = "windows-threading" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6" +dependencies = [ + "windows-link", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.48.5" @@ -7489,9 +7503,9 @@ checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" [[package]] name = "winnow" -version = "0.7.6" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63d3fcd9bba44b03821e7d699eeee959f3126dcc4aa8e4ae18ec617c2a5cea10" +checksum = "c06928c8748d81b05c9be96aad92e1b6ff01833332f281e8cfca3be4b35fc9ec" dependencies = [ "memchr", ] @@ -7512,20 +7526,14 @@ version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", ] -[[package]] -name = "write16" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" - [[package]] name = "writeable" -version = "0.5.5" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" +checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" [[package]] name = "x25519-dalek" @@ -7606,16 +7614,16 @@ dependencies = [ [[package]] name = "yamux" -version = "0.13.4" +version = "0.13.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17610762a1207ee816c6fadc29220904753648aba0a9ed61c7b8336e80a559c4" +checksum = "3da1acad1c2dc53f0dde419115a38bd8221d8c3e47ae9aeceaf453266d29307e" dependencies = [ "futures", "log", "nohash-hasher", "parking_lot", "pin-project", - "rand 0.8.5", + "rand 0.9.1", "static_assertions", "web-time 1.1.0", ] @@ -7631,9 +7639,9 @@ dependencies = [ [[package]] name = "yoke" -version = "0.7.5" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" +checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" dependencies = [ "serde", "stable_deref_trait", @@ -7643,54 +7651,34 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.7.5" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" +checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", "synstructure", ] [[package]] name = "zerocopy" -version = "0.7.35" +version = "0.8.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +checksum = "a1702d9583232ddb9174e01bb7c15a2ab8fb1bc6f227aa1233858c351a3ba0cb" dependencies = [ - "zerocopy-derive 0.7.35", -] - -[[package]] -name = "zerocopy" -version = "0.8.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2586fea28e186957ef732a5f8b3be2da217d65c5969d4b1e17f973ebbe876879" -dependencies = [ - "zerocopy-derive 0.8.24", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.100", + "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.24" +version = "0.8.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a996a8f63c5c4448cd959ac1bab0aaa3306ccfd060472f85943ee0750f0169be" +checksum = "28a6e20d751156648aa063f3800b706ee209a32c0b4d9f24be3d980b01be55ef" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -7710,7 +7698,7 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", "synstructure", ] @@ -7731,14 +7719,25 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", +] + +[[package]] +name = "zerotrie" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", ] [[package]] name = "zerovec" -version = "0.10.4" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +checksum = "4a05eb080e015ba39cc9e23bbe5e7fb04d5fb040350f99f34e338d5fdd294428" dependencies = [ "yoke", "zerofrom", @@ -7747,11 +7746,11 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.10.3" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] diff --git a/protocols/gossipsub/CHANGELOG.md b/protocols/gossipsub/CHANGELOG.md index 875fe257a60..1411bcec0bb 100644 --- a/protocols/gossipsub/CHANGELOG.md +++ b/protocols/gossipsub/CHANGELOG.md @@ -1,4 +1,7 @@ ## 0.49.0 +- switch the internal `async-channel` used to dispatch messages from `NetworkBehaviour` to the `ConnectionHandler` + with an internal priority queue. See [PR XXXX](https://github.com/libp2p/rust-libp2p/pull/XXXX) + - Send IDONTWANT before Publishing a new message. See [PR 6017](https://github.com/libp2p/rust-libp2p/pull/6017) diff --git a/protocols/gossipsub/src/behaviour.rs b/protocols/gossipsub/src/behaviour.rs index 60d1561b69b..51b4f63a362 100644 --- a/protocols/gossipsub/src/behaviour.rs +++ b/protocols/gossipsub/src/behaviour.rs @@ -59,7 +59,7 @@ use crate::{ metrics::{Churn, Config as MetricsConfig, Inclusion, Metrics, Penalty}, peer_score::{PeerScore, PeerScoreParams, PeerScoreThresholds, RejectReason}, protocol::SIGNING_PREFIX, - rpc::Sender, + queue::Queue, rpc_proto::proto, subscription_filter::{AllowAllSubscriptionFilter, TopicSubscriptionFilter}, time_cache::DuplicateCache, @@ -765,6 +765,7 @@ where if self.send_message( *peer_id, RpcOut::Publish { + message_id: msg_id.clone(), message: raw_message.clone(), timeout: Delay::new(self.config.publish_queue_duration()), }, @@ -1360,6 +1361,7 @@ where self.send_message( *peer_id, RpcOut::Forward { + message_id: id.clone(), message: msg, timeout: Delay::new(self.config.forward_queue_duration()), }, @@ -2083,9 +2085,8 @@ where // before we add all the gossip from this heartbeat in order to gain a true measure of // steady-state size of the queues. if let Some(m) = &mut self.metrics { - for sender_queue in self.connected_peers.values().map(|v| &v.sender) { - m.observe_priority_queue_size(sender_queue.priority_queue_len()); - m.observe_non_priority_queue_size(sender_queue.non_priority_queue_len()); + for sender_queue in self.connected_peers.values().map(|v| &v.messages) { + m.observe_priority_queue_size(sender_queue.len()); } } @@ -2729,6 +2730,7 @@ where self.send_message( *peer_id, RpcOut::Forward { + message_id: msg_id.clone(), message: message.clone(), timeout: Delay::new(self.config.forward_queue_duration()), }, @@ -2857,7 +2859,12 @@ where } // Try sending the message to the connection handler. - match peer.sender.send_message(rpc) { + if rpc.high_priority() { + peer.messages.push(rpc); + return true; + } + + match peer.messages.try_push(rpc) { Ok(()) => true, Err(rpc) => { // Sending failed because the channel is full. @@ -2865,25 +2872,7 @@ where // Update failed message counter. let failed_messages = self.failed_messages.entry(peer_id).or_default(); - match rpc { - RpcOut::Publish { .. } => { - failed_messages.priority += 1; - failed_messages.publish += 1; - } - RpcOut::Forward { .. } => { - failed_messages.non_priority += 1; - failed_messages.forward += 1; - } - RpcOut::IWant(_) | RpcOut::IHave(_) | RpcOut::IDontWant(_) => { - failed_messages.non_priority += 1; - } - RpcOut::Graft(_) - | RpcOut::Prune(_) - | RpcOut::Subscribe(_) - | RpcOut::Unsubscribe(_) => { - unreachable!("Channel for highpriority control messages is unbounded and should always be open.") - } - } + failed_messages.queue_full += 1; // Update peer score. if let Some((peer_score, ..)) = &mut self.peer_score { @@ -3105,18 +3094,20 @@ where // occur. let connected_peer = self.connected_peers.entry(peer_id).or_insert(PeerDetails { kind: PeerKind::Floodsub, - connections: vec![], outbound: false, - sender: Sender::new(self.config.connection_handler_queue_len()), + connections: vec![], topics: Default::default(), dont_send: LinkedHashMap::new(), + messages: Queue::new(self.config.connection_handler_queue_len()), }); // Add the new connection connected_peer.connections.push(connection_id); + // This clones a reference to the Queue so any new handlers reference the same underlying queue. + // No data is actually cloned here. Ok(Handler::new( self.config.protocol_config(), - connected_peer.sender.new_receiver(), + connected_peer.messages.clone(), )) } @@ -3130,20 +3121,22 @@ where ) -> Result, ConnectionDenied> { let connected_peer = self.connected_peers.entry(peer_id).or_insert(PeerDetails { kind: PeerKind::Floodsub, - connections: vec![], // Diverging from the go implementation we only want to consider a peer as outbound peer // if its first connection is outbound. outbound: !self.px_peers.contains(&peer_id), - sender: Sender::new(self.config.connection_handler_queue_len()), + connections: vec![], topics: Default::default(), dont_send: LinkedHashMap::new(), + messages: Queue::new(self.config.connection_handler_queue_len()), }); // Add the new connection connected_peer.connections.push(connection_id); + // This clones a reference to the Queue so any new handlers reference the same underlying queue. + // No data is actually cloned here. Ok(Handler::new( self.config.protocol_config(), - connected_peer.sender.new_receiver(), + connected_peer.messages.clone(), )) } @@ -3184,7 +3177,7 @@ where } } } - HandlerEvent::MessageDropped(rpc) => { + HandlerEvent::MessagesDropped(rpc) => { // Account for this in the scoring logic if let Some((peer_score, _, _)) = &mut self.peer_score { peer_score.failed_message_slow_peer(&propagation_source); @@ -3193,28 +3186,9 @@ where // Keep track of expired messages for the application layer. let failed_messages = self.failed_messages.entry(propagation_source).or_default(); failed_messages.timeout += 1; - match rpc { - RpcOut::Publish { .. } => { - failed_messages.publish += 1; - } - RpcOut::Forward { .. } => { - failed_messages.forward += 1; - } - _ => {} - } - - // Record metrics on the failure. if let Some(metrics) = self.metrics.as_mut() { - match rpc { - RpcOut::Publish { message, .. } => { - metrics.publish_msg_dropped(&message.topic); - metrics.timeout_msg_dropped(&message.topic); - } - RpcOut::Forward { message, .. } => { - metrics.forward_msg_dropped(&message.topic); - metrics.timeout_msg_dropped(&message.topic); - } - _ => {} + if let RpcOut::Publish { message, .. } | RpcOut::Forward { message, .. } = rpc { + metrics.timeout_msg_dropped(&message.topic); } } } @@ -3317,6 +3291,16 @@ where if let Some(metrics) = self.metrics.as_mut() { metrics.register_idontwant(message_ids.len()); } + + // Remove messages from the queue. + peer.messages.retain(|rpc| match rpc { + RpcOut::Publish { message_id, .. } + | RpcOut::Forward { message_id, .. } => { + !message_ids.contains(message_id) + } + _ => true, + }); + for message_id in message_ids { peer.dont_send.insert(message_id, Instant::now()); // Don't exceed capacity. diff --git a/protocols/gossipsub/src/behaviour/tests.rs b/protocols/gossipsub/src/behaviour/tests.rs index 533891d9f58..5fc50facbd0 100644 --- a/protocols/gossipsub/src/behaviour/tests.rs +++ b/protocols/gossipsub/src/behaviour/tests.rs @@ -20,7 +20,7 @@ // Collection of tests for the gossipsub network behaviour -use std::{future, net::Ipv4Addr, thread::sleep}; +use std::{net::Ipv4Addr, thread::sleep}; use asynchronous_codec::{Decoder, Encoder}; use byteorder::{BigEndian, ByteOrder}; @@ -32,7 +32,6 @@ use super::*; use crate::{ config::{ConfigBuilder, TopicMeshConfig}, protocol::GossipsubCodec, - rpc::Receiver, subscription_filter::WhitelistSubscriptionFilter, types::Rpc, IdentTopic as Topic, @@ -63,7 +62,7 @@ where ) -> ( Behaviour, Vec, - HashMap, + HashMap>, Vec, ) { let keypair = libp2p_identity::Keypair::generate_ed25519(); @@ -182,7 +181,7 @@ fn add_peer( topic_hashes: &[TopicHash], outbound: bool, explicit: bool, -) -> (PeerId, Receiver) +) -> (PeerId, Queue) where D: DataTransform + Default + Clone + Send + 'static, F: TopicSubscriptionFilter + Clone + Default + Send + 'static, @@ -196,7 +195,7 @@ fn add_peer_with_addr( outbound: bool, explicit: bool, address: Multiaddr, -) -> (PeerId, Receiver) +) -> (PeerId, Queue) where D: DataTransform + Default + Clone + Send + 'static, F: TopicSubscriptionFilter + Clone + Default + Send + 'static, @@ -218,7 +217,7 @@ fn add_peer_with_addr_and_kind( explicit: bool, address: Multiaddr, kind: Option, -) -> (PeerId, Receiver) +) -> (PeerId, Queue) where D: DataTransform + Default + Clone + Send + 'static, F: TopicSubscriptionFilter + Clone + Default + Send + 'static, @@ -237,8 +236,8 @@ where } }; - let sender = Sender::new(gs.config.connection_handler_queue_len()); - let receiver = sender.new_receiver(); + let queue = Queue::new(gs.config.connection_handler_queue_len()); + let receiver_queue = queue.clone(); let connection_id = ConnectionId::new_unchecked(0); gs.connected_peers.insert( peer, @@ -247,7 +246,7 @@ where outbound, connections: vec![connection_id], topics: Default::default(), - sender, + messages: queue, dont_send: LinkedHashMap::new(), }, ); @@ -282,7 +281,7 @@ where &peer, ); } - (peer, receiver) + (peer, receiver_queue) } fn disconnect_peer(gs: &mut Behaviour, peer_id: &PeerId) @@ -443,17 +442,17 @@ fn test_subscribe() { ); // collect all the subscriptions - let subscriptions = receivers - .into_values() - .fold(0, |mut collected_subscriptions, c| { - let priority = c.priority.get_ref(); - while !priority.is_empty() { - if let Ok(RpcOut::Subscribe(_)) = priority.try_recv() { - collected_subscriptions += 1 + let subscriptions = + receivers + .into_values() + .fold(0, |mut collected_subscriptions, mut queue| { + while !queue.is_empty() { + if let Ok(RpcOut::Subscribe(_)) = queue.try_pop() { + collected_subscriptions += 1 + } } - } - collected_subscriptions - }); + collected_subscriptions + }); // we sent a subscribe to all known peers assert_eq!(subscriptions, 20); @@ -504,17 +503,17 @@ fn test_unsubscribe() { ); // collect all the subscriptions - let subscriptions = receivers - .into_values() - .fold(0, |mut collected_subscriptions, c| { - let priority = c.priority.get_ref(); - while !priority.is_empty() { - if let Ok(RpcOut::Subscribe(_)) = priority.try_recv() { - collected_subscriptions += 1 + let subscriptions = + receivers + .into_values() + .fold(0, |mut collected_subscriptions, mut queue| { + while !queue.is_empty() { + if let Ok(RpcOut::Subscribe(_)) = queue.try_pop() { + collected_subscriptions += 1 + } } - } - collected_subscriptions - }); + collected_subscriptions + }); // we sent a unsubscribe to all known peers, for two topics assert_eq!(subscriptions, 40); @@ -577,27 +576,21 @@ fn test_join() { "Should have added 6 nodes to the mesh" ); - fn count_grafts(receivers: HashMap) -> (usize, HashMap) { - let mut new_receivers = HashMap::new(); + fn count_grafts( + queues: HashMap>, + ) -> (usize, HashMap>) { + let mut new_queues = HashMap::new(); let mut acc = 0; - for (peer_id, c) in receivers.into_iter() { - let priority = c.priority.get_ref(); - while !priority.is_empty() { - if let Ok(RpcOut::Graft(_)) = priority.try_recv() { + for (peer_id, mut queue) in queues.into_iter() { + while !queue.is_empty() { + if let Ok(RpcOut::Graft(_)) = queue.try_pop() { acc += 1; } } - new_receivers.insert( - peer_id, - Receiver { - priority_queue_len: c.priority_queue_len, - priority: c.priority, - non_priority: c.non_priority, - }, - ); + new_queues.insert(peer_id, queue); } - (acc, new_receivers) + (acc, new_queues) } // there should be mesh_n GRAFT messages. @@ -625,8 +618,8 @@ fn test_join() { &address, ) .unwrap(); - let sender = Sender::new(gs.config.connection_handler_queue_len()); - let receiver = sender.new_receiver(); + let queue = Queue::new(gs.config.connection_handler_queue_len()); + let receiver_queue = queue.clone(); let connection_id = ConnectionId::new_unchecked(0); gs.connected_peers.insert( random_peer, @@ -635,11 +628,11 @@ fn test_join() { outbound: false, connections: vec![connection_id], topics: Default::default(), - sender, + messages: queue, dont_send: LinkedHashMap::new(), }, ); - receivers.insert(random_peer, receiver); + receivers.insert(random_peer, receiver_queue); gs.on_swarm_event(FromSwarm::ConnectionEstablished(ConnectionEstablished { peer_id: random_peer, @@ -727,10 +720,9 @@ fn test_publish_without_flood_publishing() { // Collect all publish messages let publishes = receivers .into_values() - .fold(vec![], |mut collected_publish, c| { - let priority = c.priority.get_ref(); - while !priority.is_empty() { - if let Ok(RpcOut::Publish { message, .. }) = priority.try_recv() { + .fold(vec![], |mut collected_publish, mut queue| { + while !queue.is_empty() { + if let Ok(RpcOut::Publish { message, .. }) = queue.try_pop() { collected_publish.push(message); } } @@ -812,10 +804,9 @@ fn test_fanout() { // Collect all publish messages let publishes = receivers .into_values() - .fold(vec![], |mut collected_publish, c| { - let priority = c.priority.get_ref(); - while !priority.is_empty() { - if let Ok(RpcOut::Publish { message, .. }) = priority.try_recv() { + .fold(vec![], |mut collected_publish, mut queue| { + while !queue.is_empty() { + if let Ok(RpcOut::Publish { message, .. }) = queue.try_pop() { collected_publish.push(message); } } @@ -860,10 +851,9 @@ fn test_inject_connected() { // collect all the SendEvents let subscriptions = receivers.into_iter().fold( HashMap::>::new(), - |mut collected_subscriptions, (peer, c)| { - let priority = c.priority.get_ref(); - while !priority.is_empty() { - if let Ok(RpcOut::Subscribe(topic)) = priority.try_recv() { + |mut collected_subscriptions, (peer, mut queue)| { + while !queue.is_empty() { + if let Ok(RpcOut::Subscribe(topic)) = queue.try_pop() { let mut peer_subs = collected_subscriptions.remove(&peer).unwrap_or_default(); peer_subs.push(topic.into_string()); collected_subscriptions.insert(peer, peer_subs); @@ -1032,7 +1022,7 @@ fn test_get_random_peers() { connections: vec![ConnectionId::new_unchecked(0)], outbound: false, topics: topics.clone(), - sender: Sender::new(gs.config.connection_handler_queue_len()), + messages: Queue::new(gs.config.connection_handler_queue_len()), dont_send: LinkedHashMap::new(), }, ); @@ -1094,17 +1084,17 @@ fn test_handle_iwant_msg_cached() { gs.handle_iwant(&peers[7], vec![msg_id.clone()]); // the messages we are sending - let sent_messages = receivers - .into_values() - .fold(vec![], |mut collected_messages, c| { - let non_priority = c.non_priority.get_ref(); - while !non_priority.is_empty() { - if let Ok(RpcOut::Forward { message, .. }) = non_priority.try_recv() { - collected_messages.push(message) + let sent_messages = + receivers + .into_values() + .fold(vec![], |mut collected_messages, mut queue| { + while !queue.is_empty() { + if let Ok(RpcOut::Forward { message, .. }) = queue.try_pop() { + collected_messages.push(message) + } } - } - collected_messages - }); + collected_messages + }); assert!( sent_messages @@ -1152,28 +1142,23 @@ fn test_handle_iwant_msg_cached_shifted() { // is the message is being sent? let mut message_exists = false; - receivers = receivers.into_iter().map(|(peer_id, c)| { - let non_priority = c.non_priority.get_ref(); - while !non_priority.is_empty() { - if matches!(non_priority.try_recv(), Ok(RpcOut::Forward{message, timeout: _ }) if + receivers = receivers + .into_iter() + .map(|(peer_id, mut queue)| { + while !queue.is_empty() { + if matches!(queue.try_pop(), Ok(RpcOut::Forward{message, ..}) if gs.config.message_id( &gs.data_transform .inbound_transform(message.clone()) .unwrap(), ) == msg_id) - { - message_exists = true; + { + message_exists = true; + } } - } - ( - peer_id, - Receiver { - priority_queue_len: c.priority_queue_len, - priority: c.priority, - non_priority: c.non_priority, - }, - ) - }).collect(); + (peer_id, queue) + }) + .collect(); // default history_length is 5, expect no messages after shift > 5 if shift < 5 { assert!( @@ -1257,7 +1242,7 @@ fn test_handle_iwant_msg_but_already_sent_idontwant() { // Check that no messages are sent. receivers.iter().for_each(|(_, receiver)| { - assert!(receiver.non_priority.get_ref().is_empty()); + assert!(receiver.is_empty()); }); } @@ -1277,10 +1262,9 @@ fn test_handle_ihave_subscribed_and_msg_not_cached() { // check that we sent an IWANT request for `unknown id` let mut iwant_exists = false; - let receiver = receivers.remove(&peers[7]).unwrap(); - let non_priority = receiver.non_priority.get_ref(); - while !non_priority.is_empty() { - if let Ok(RpcOut::IWant(IWant { message_ids })) = non_priority.try_recv() { + let mut receiver_queue = receivers.remove(&peers[7]).unwrap(); + while !receiver_queue.is_empty() { + if let Ok(RpcOut::IWant(IWant { message_ids })) = receiver_queue.try_pop() { if message_ids .iter() .any(|m| *m == MessageId::new(b"unknown id")) @@ -1450,59 +1434,35 @@ fn test_handle_prune_peer_in_mesh() { } fn count_control_msgs( - receivers: HashMap, + receivers: HashMap>, mut filter: impl FnMut(&PeerId, &RpcOut) -> bool, -) -> (usize, HashMap) { +) -> (usize, HashMap>) { let mut new_receivers = HashMap::new(); let mut collected_messages = 0; - for (peer_id, c) in receivers.into_iter() { - let priority = c.priority.get_ref(); - let non_priority = c.non_priority.get_ref(); - while !priority.is_empty() || !non_priority.is_empty() { - if let Ok(rpc) = priority.try_recv() { - if filter(&peer_id, &rpc) { - collected_messages += 1; - } - } - if let Ok(rpc) = non_priority.try_recv() { + for (peer_id, mut queue) in receivers.into_iter() { + while !queue.is_empty() { + if let Ok(rpc) = queue.try_pop() { if filter(&peer_id, &rpc) { collected_messages += 1; } } } - new_receivers.insert( - peer_id, - Receiver { - priority_queue_len: c.priority_queue_len, - priority: c.priority, - non_priority: c.non_priority, - }, - ); + new_receivers.insert(peer_id, queue); } (collected_messages, new_receivers) } fn flush_events( gs: &mut Behaviour, - receivers: HashMap, -) -> HashMap { + receivers: HashMap>, +) -> HashMap> { gs.events.clear(); let mut new_receivers = HashMap::new(); - for (peer_id, c) in receivers.into_iter() { - let priority = c.priority.get_ref(); - let non_priority = c.non_priority.get_ref(); - while !priority.is_empty() || !non_priority.is_empty() { - let _ = priority.try_recv(); - let _ = non_priority.try_recv(); + for (peer_id, mut queue) in receivers.into_iter() { + while !queue.is_empty() { + let _ = queue.try_pop(); } - new_receivers.insert( - peer_id, - Receiver { - priority_queue_len: c.priority_queue_len, - priority: c.priority, - non_priority: c.non_priority, - }, - ); + new_receivers.insert(peer_id, queue); } new_receivers } @@ -1708,10 +1668,9 @@ fn do_forward_messages_to_explicit_peers() { }; gs.handle_received_message(message.clone(), &local_id); assert_eq!( - receivers.into_iter().fold(0, |mut fwds, (peer_id, c)| { - let non_priority = c.non_priority.get_ref(); - while !non_priority.is_empty() { - if matches!(non_priority.try_recv(), Ok(RpcOut::Forward{message: m, timeout: _}) if peer_id == peers[0] && m.data == message.data) { + receivers.into_iter().fold(0, |mut fwds, (peer_id, mut queue)| { + while !queue.is_empty() { + if matches!(queue.try_pop(), Ok(RpcOut::Forward{message: m, ..}) if peer_id == peers[0] && m.data == message.data) { fwds +=1; } } @@ -1852,11 +1811,10 @@ fn no_gossip_gets_sent_to_explicit_peers() { } // assert that no gossip gets sent to explicit peer - let receiver = receivers.remove(&peers[0]).unwrap(); + let mut receiver_queue = receivers.remove(&peers[0]).unwrap(); let mut gossips = 0; - let non_priority = receiver.non_priority.get_ref(); - while !non_priority.is_empty() { - if let Ok(RpcOut::IHave(_)) = non_priority.try_recv() { + while !receiver_queue.is_empty() { + if let Ok(RpcOut::IHave(_)) = receiver_queue.try_pop() { gossips += 1; } } @@ -2257,10 +2215,9 @@ fn test_flood_publish() { // Collect all publish messages let publishes = receivers .into_values() - .fold(vec![], |mut collected_publish, c| { - let priority = c.priority.get_ref(); - while !priority.is_empty() { - if let Ok(RpcOut::Publish { message, .. }) = priority.try_recv() { + .fold(vec![], |mut collected_publish, mut queue| { + while !queue.is_empty() { + if let Ok(RpcOut::Publish { message, .. }) = queue.try_pop() { collected_publish.push(message); } } @@ -2819,10 +2776,9 @@ fn test_iwant_msg_from_peer_below_gossip_threshold_gets_ignored() { let sent_messages = receivers .into_iter() - .fold(vec![], |mut collected_messages, (peer_id, c)| { - let non_priority = c.non_priority.get_ref(); - while !non_priority.is_empty() { - if let Ok(RpcOut::Forward { message, .. }) = non_priority.try_recv() { + .fold(vec![], |mut collected_messages, (peer_id, mut queue)| { + while !queue.is_empty() { + if let Ok(RpcOut::Forward { message, .. }) = queue.try_pop() { collected_messages.push((peer_id, message)); } } @@ -2964,17 +2920,17 @@ fn test_do_not_publish_to_peer_below_publish_threshold() { gs.publish(topic, publish_data).unwrap(); // Collect all publish messages - let publishes = receivers - .into_iter() - .fold(vec![], |mut collected_publish, (peer_id, c)| { - let priority = c.priority.get_ref(); - while !priority.is_empty() { - if let Ok(RpcOut::Publish { message, .. }) = priority.try_recv() { - collected_publish.push((peer_id, message)); + let publishes = + receivers + .into_iter() + .fold(vec![], |mut collected_publish, (peer_id, mut queue)| { + while !queue.is_empty() { + if let Ok(RpcOut::Publish { message, .. }) = queue.try_pop() { + collected_publish.push((peer_id, message)); + } } - } - collected_publish - }); + collected_publish + }); // assert only published to p2 assert_eq!(publishes.len(), 1); @@ -3019,17 +2975,17 @@ fn test_do_not_flood_publish_to_peer_below_publish_threshold() { gs.publish(Topic::new("test"), publish_data).unwrap(); // Collect all publish messages - let publishes = receivers - .into_iter() - .fold(vec![], |mut collected_publish, (peer_id, c)| { - let priority = c.priority.get_ref(); - while !priority.is_empty() { - if let Ok(RpcOut::Publish { message, .. }) = priority.try_recv() { - collected_publish.push((peer_id, message)) + let publishes = + receivers + .into_iter() + .fold(vec![], |mut collected_publish, (peer_id, mut queue)| { + while !queue.is_empty() { + if let Ok(RpcOut::Publish { message, .. }) = queue.try_pop() { + collected_publish.push((peer_id, message)) + } } - } - collected_publish - }); + collected_publish + }); // assert only published to p2 assert_eq!(publishes.len(), 1); @@ -4571,10 +4527,9 @@ fn test_ignore_too_many_iwants_from_same_peer_for_same_message() { } assert_eq!( - receivers.into_values().fold(0, |mut fwds, c| { - let non_priority = c.non_priority.get_ref(); - while !non_priority.is_empty() { - if let Ok(RpcOut::Forward { .. }) = non_priority.try_recv() { + receivers.into_values().fold(0, |mut fwds, mut queue| { + while !queue.is_empty() { + if let Ok(RpcOut::Forward { .. }) = queue.try_pop() { fwds += 1; } } @@ -4986,10 +4941,9 @@ fn test_publish_to_floodsub_peers_without_flood_publish() { // Collect publish messages to floodsub peers let publishes = receivers .into_iter() - .fold(0, |mut collected_publish, (peer_id, c)| { - let priority = c.priority.get_ref(); - while !priority.is_empty() { - if matches!(priority.try_recv(), + .fold(0, |mut collected_publish, (peer_id, mut queue)| { + while !queue.is_empty() { + if matches!(queue.try_pop(), Ok(RpcOut::Publish{..}) if peer_id == p1 || peer_id == p2) { collected_publish += 1; @@ -5042,10 +4996,9 @@ fn test_do_not_use_floodsub_in_fanout() { // Collect publish messages to floodsub peers let publishes = receivers .into_iter() - .fold(0, |mut collected_publish, (peer_id, c)| { - let priority = c.priority.get_ref(); - while !priority.is_empty() { - if matches!(priority.try_recv(), + .fold(0, |mut collected_publish, (peer_id, mut queue)| { + while !queue.is_empty() { + if matches!(queue.try_pop(), Ok(RpcOut::Publish{..}) if peer_id == p1 || peer_id == p2) { collected_publish += 1; @@ -5268,12 +5221,11 @@ fn test_subscribe_and_graft_with_negative_score() { p1: PeerId, p2: PeerId, connection_id: ConnectionId, - receivers: HashMap| - -> HashMap { + receivers: HashMap>| + -> HashMap> { let new_receivers = HashMap::new(); - for (peer_id, receiver) in receivers.into_iter() { - let non_priority = receiver.non_priority.get_ref(); - match non_priority.try_recv() { + for (peer_id, mut receiver_queue) in receivers.into_iter() { + match receiver_queue.try_pop() { Ok(rpc) if peer_id == p1 => { gs1.on_connection_handler_event( p2, @@ -5364,10 +5316,9 @@ fn sends_idontwant() { assert_eq!( receivers .into_iter() - .fold(0, |mut idontwants, (peer_id, c)| { - let non_priority = c.non_priority.get_ref(); - while !non_priority.is_empty() { - if let Ok(RpcOut::IDontWant(_)) = non_priority.try_recv() { + .fold(0, |mut idontwants, (peer_id, mut queue)| { + while !queue.is_empty() { + if let Ok(RpcOut::IDontWant(_)) = queue.try_pop() { assert_ne!(peer_id, peers[1]); idontwants += 1; } @@ -5406,10 +5357,9 @@ fn doesnt_sends_idontwant_for_lower_message_size() { assert_eq!( receivers .into_iter() - .fold(0, |mut idontwants, (peer_id, c)| { - let non_priority = c.non_priority.get_ref(); - while !non_priority.is_empty() { - if let Ok(RpcOut::IDontWant(_)) = non_priority.try_recv() { + .fold(0, |mut idontwants, (peer_id, mut queue)| { + while !queue.is_empty() { + if let Ok(RpcOut::IDontWant(_)) = queue.try_pop() { assert_ne!(peer_id, peers[1]); idontwants += 1; } @@ -5449,10 +5399,9 @@ fn doesnt_send_idontwant() { assert_eq!( receivers .into_iter() - .fold(0, |mut idontwants, (peer_id, c)| { - let non_priority = c.non_priority.get_ref(); - while !non_priority.is_empty() { - if matches!(non_priority.try_recv(), Ok(RpcOut::IDontWant(_)) if peer_id != peers[1]) { + .fold(0, |mut idontwants, (peer_id, mut queue)| { + while !queue.is_empty() { + if matches!(queue.try_pop(), Ok(RpcOut::IDontWant(_)) if peer_id != peers[1]) { idontwants += 1; } } @@ -5497,16 +5446,17 @@ fn doesnt_forward_idontwant() { gs.handle_received_message(raw_message.clone(), &local_id); assert_eq!( - receivers.into_iter().fold(0, |mut fwds, (peer_id, c)| { - let non_priority = c.non_priority.get_ref(); - while !non_priority.is_empty() { - if let Ok(RpcOut::Forward { .. }) = non_priority.try_recv() { - assert_ne!(peer_id, peers[2]); - fwds += 1; + receivers + .into_iter() + .fold(0, |mut fwds, (peer_id, mut queue)| { + while !queue.is_empty() { + if let Ok(RpcOut::Forward { .. }) = queue.try_pop() { + assert_ne!(peer_id, peers[2]); + fwds += 1; + } } - } - fwds - }), + fwds + }), 2, "IDONTWANT was not sent" ); @@ -5589,14 +5539,11 @@ fn test_all_queues_full() { connections: vec![ConnectionId::new_unchecked(0)], outbound: false, topics: topics.clone(), - sender: Sender::new(2), + messages: Queue::new(2), dont_send: LinkedHashMap::new(), }, ); - let publish_data = vec![0; 42]; - gs.publish(topic_hash.clone(), publish_data.clone()) - .unwrap(); let publish_data = vec![2; 59]; let err = gs.publish(topic_hash, publish_data).unwrap_err(); assert!(matches!(err, PublishError::AllQueuesFull(f) if f == 1)); @@ -5625,7 +5572,7 @@ fn test_slow_peer_returns_failed_publish() { connections: vec![ConnectionId::new_unchecked(0)], outbound: false, topics: topics.clone(), - sender: Sender::new(2), + messages: Queue::new(2), dont_send: LinkedHashMap::new(), }, ); @@ -5638,18 +5585,13 @@ fn test_slow_peer_returns_failed_publish() { connections: vec![ConnectionId::new_unchecked(0)], outbound: false, topics: topics.clone(), - sender: Sender::new(gs.config.connection_handler_queue_len()), + messages: Queue::new(gs.config.connection_handler_queue_len()), dont_send: LinkedHashMap::new(), }, ); let publish_data = vec![0; 42]; - gs.publish(topic_hash.clone(), publish_data.clone()) - .unwrap(); - let publish_data = vec![2; 59]; - gs.publish(topic_hash.clone(), publish_data).unwrap(); - gs.heartbeat(); - + let _failed_publish = gs.publish(topic_hash.clone(), publish_data.clone()); gs.heartbeat(); let slow_peer_failed_messages = match gs.events.pop_front().unwrap() { @@ -5661,20 +5603,11 @@ fn test_slow_peer_returns_failed_publish() { }; let failed_messages = FailedMessages { - publish: 1, - forward: 0, - priority: 1, - non_priority: 0, + queue_full: 1, timeout: 0, }; - assert_eq!(slow_peer_failed_messages.priority, failed_messages.priority); - assert_eq!( - slow_peer_failed_messages.non_priority, - failed_messages.non_priority - ); - assert_eq!(slow_peer_failed_messages.publish, failed_messages.publish); - assert_eq!(slow_peer_failed_messages.forward, failed_messages.forward); + assert_eq!(slow_peer_failed_messages, failed_messages); } #[test] @@ -5699,7 +5632,7 @@ fn test_slow_peer_returns_failed_ihave_handling() { connections: vec![ConnectionId::new_unchecked(0)], outbound: false, topics: topics.clone(), - sender: Sender::new(2), + messages: Queue::new(1), dont_send: LinkedHashMap::new(), }, ); @@ -5716,7 +5649,7 @@ fn test_slow_peer_returns_failed_ihave_handling() { connections: vec![ConnectionId::new_unchecked(0)], outbound: false, topics: topics.clone(), - sender: Sender::new(gs.config.connection_handler_queue_len()), + messages: Queue::new(gs.config.connection_handler_queue_len()), dont_send: LinkedHashMap::new(), }, ); @@ -5774,20 +5707,11 @@ fn test_slow_peer_returns_failed_ihave_handling() { .unwrap(); let failed_messages = FailedMessages { - publish: 0, - forward: 0, - priority: 0, - non_priority: 1, timeout: 0, + queue_full: 1, }; - assert_eq!(slow_peer_failed_messages.priority, failed_messages.priority); - assert_eq!( - slow_peer_failed_messages.non_priority, - failed_messages.non_priority - ); - assert_eq!(slow_peer_failed_messages.publish, failed_messages.publish); - assert_eq!(slow_peer_failed_messages.forward, failed_messages.forward); + assert_eq!(slow_peer_failed_messages, failed_messages); } #[test] @@ -5813,7 +5737,7 @@ fn test_slow_peer_returns_failed_iwant_handling() { connections: vec![ConnectionId::new_unchecked(0)], outbound: false, topics: topics.clone(), - sender: Sender::new(2), + messages: Queue::new(1), dont_send: LinkedHashMap::new(), }, ); @@ -5830,7 +5754,7 @@ fn test_slow_peer_returns_failed_iwant_handling() { connections: vec![ConnectionId::new_unchecked(0)], outbound: false, topics: topics.clone(), - sender: Sender::new(gs.config.connection_handler_queue_len()), + messages: Queue::new(gs.config.connection_handler_queue_len()), dont_send: LinkedHashMap::new(), }, ); @@ -5868,20 +5792,11 @@ fn test_slow_peer_returns_failed_iwant_handling() { .unwrap(); let failed_messages = FailedMessages { - publish: 0, - forward: 1, - priority: 0, - non_priority: 1, + queue_full: 1, timeout: 0, }; - assert_eq!(slow_peer_failed_messages.priority, failed_messages.priority); - assert_eq!( - slow_peer_failed_messages.non_priority, - failed_messages.non_priority - ); - assert_eq!(slow_peer_failed_messages.publish, failed_messages.publish); - assert_eq!(slow_peer_failed_messages.forward, failed_messages.forward); + assert_eq!(slow_peer_failed_messages, failed_messages); } #[test] @@ -5907,7 +5822,7 @@ fn test_slow_peer_returns_failed_forward() { connections: vec![ConnectionId::new_unchecked(0)], outbound: false, topics: topics.clone(), - sender: Sender::new(2), + messages: Queue::new(1), dont_send: LinkedHashMap::new(), }, ); @@ -5924,7 +5839,7 @@ fn test_slow_peer_returns_failed_forward() { connections: vec![ConnectionId::new_unchecked(0)], outbound: false, topics: topics.clone(), - sender: Sender::new(gs.config.connection_handler_queue_len()), + messages: Queue::new(gs.config.connection_handler_queue_len()), dont_send: LinkedHashMap::new(), }, ); @@ -5962,20 +5877,11 @@ fn test_slow_peer_returns_failed_forward() { .unwrap(); let failed_messages = FailedMessages { - publish: 0, - forward: 1, - priority: 0, - non_priority: 1, + queue_full: 1, timeout: 0, }; - assert_eq!(slow_peer_failed_messages.priority, failed_messages.priority); - assert_eq!( - slow_peer_failed_messages.non_priority, - failed_messages.non_priority - ); - assert_eq!(slow_peer_failed_messages.publish, failed_messages.publish); - assert_eq!(slow_peer_failed_messages.forward, failed_messages.forward); + assert_eq!(slow_peer_failed_messages, failed_messages); } #[test] @@ -6006,7 +5912,7 @@ fn test_slow_peer_is_downscored_on_publish() { connections: vec![ConnectionId::new_unchecked(0)], outbound: false, topics: topics.clone(), - sender: Sender::new(2), + messages: Queue::new(1), dont_send: LinkedHashMap::new(), }, ); @@ -6020,7 +5926,7 @@ fn test_slow_peer_is_downscored_on_publish() { connections: vec![ConnectionId::new_unchecked(0)], outbound: false, topics: topics.clone(), - sender: Sender::new(gs.config.connection_handler_queue_len()), + messages: Queue::new(gs.config.connection_handler_queue_len()), dont_send: LinkedHashMap::new(), }, ); @@ -6032,46 +5938,21 @@ fn test_slow_peer_is_downscored_on_publish() { gs.publish(topic_hash.clone(), publish_data).unwrap(); gs.heartbeat(); let slow_peer_score = gs.peer_score(&slow_peer_id).unwrap(); - assert_eq!(slow_peer_score, slow_peer_params.slow_peer_weight); -} - -#[tokio::test] -async fn test_timedout_messages_are_reported() { - let gs_config = ConfigBuilder::default() - .validation_mode(ValidationMode::Permissive) - .build() - .unwrap(); - - let mut gs: Behaviour = Behaviour::new(MessageAuthenticity::RandomAuthor, gs_config).unwrap(); - - let sender = Sender::new(2); - let topic_hash = Topic::new("Test").hash(); - let publish_data = vec![2; 59]; - let raw_message = gs.build_raw_message(topic_hash, publish_data).unwrap(); - - sender - .send_message(RpcOut::Publish { - message: raw_message, - timeout: Delay::new(Duration::from_nanos(1)), - }) - .unwrap(); - let mut receiver = sender.new_receiver(); - let stale = future::poll_fn(|cx| receiver.poll_stale(cx)).await.unwrap(); - assert!(matches!(stale, RpcOut::Publish { .. })); + assert_eq!(slow_peer_score, slow_peer_params.slow_peer_weight * 3.0); } #[test] fn test_priority_messages_are_always_sent() { - let sender = Sender::new(2); + let mut sender = Queue::new(2); let topic_hash = Topic::new("Test").hash(); // Fill the buffer with the first message. assert!(sender - .send_message(RpcOut::Subscribe(topic_hash.clone())) + .try_push(RpcOut::Subscribe(topic_hash.clone())) .is_ok()); assert!(sender - .send_message(RpcOut::Subscribe(topic_hash.clone())) + .try_push(RpcOut::Subscribe(topic_hash.clone())) .is_ok()); - assert!(sender.send_message(RpcOut::Unsubscribe(topic_hash)).is_ok()); + assert!(sender.try_push(RpcOut::Unsubscribe(topic_hash)).is_ok()); } /// Test that specific topic configurations are correctly applied @@ -6443,12 +6324,9 @@ fn test_fanout_with_topic_config() { // Collect publish messages let publishes = receivers .into_values() - .fold(vec![], |mut collected_publish, c| { - let priority = c.priority.get_ref(); - while !priority.is_empty() { - if let Ok(RpcOut::Publish { message, .. }) = priority.try_recv() { - collected_publish.push(message); - } + .fold(vec![], |mut collected_publish, mut c| { + while let Ok(RpcOut::Publish { message, .. }) = c.try_pop() { + collected_publish.push(message); } collected_publish }); diff --git a/protocols/gossipsub/src/handler.rs b/protocols/gossipsub/src/handler.rs index 99d62de953f..227165a159c 100644 --- a/protocols/gossipsub/src/handler.rs +++ b/protocols/gossipsub/src/handler.rs @@ -37,7 +37,7 @@ use web_time::Instant; use crate::{ protocol::{GossipsubCodec, ProtocolConfig}, - rpc::Receiver, + queue::Queue, rpc_proto::proto, types::{PeerKind, RawMessage, Rpc, RpcOut}, ValidationError, @@ -60,7 +60,7 @@ pub enum HandlerEvent { /// which protocol. This message only occurs once per connection. PeerKind(PeerKind), /// A message to be published was dropped because it could not be sent in time. - MessageDropped(RpcOut), + MessagesDropped(RpcOut), } /// A message sent from the behaviour to the handler. @@ -98,8 +98,8 @@ pub struct EnabledHandler { /// The single long-lived inbound substream. inbound_substream: Option, - /// Queue of values that we want to send to the remote - send_queue: Receiver, + /// Queue of dispatched Rpc messages to send. + message_queue: Queue, /// Flag indicating that an outbound substream is being established to prevent duplicate /// requests. @@ -162,7 +162,7 @@ enum OutboundSubstreamState { impl Handler { /// Builds a new [`Handler`]. - pub fn new(protocol_config: ProtocolConfig, message_queue: Receiver) -> Self { + pub(crate) fn new(protocol_config: ProtocolConfig, message_queue: Queue) -> Self { Handler::Enabled(EnabledHandler { listen_protocol: protocol_config, inbound_substream: None, @@ -170,7 +170,7 @@ impl Handler { outbound_substream_establishing: false, outbound_substream_attempts: 0, inbound_substream_attempts: 0, - send_queue: message_queue, + message_queue, peer_kind: None, peer_kind_sent: false, last_io_activity: Instant::now(), @@ -234,7 +234,7 @@ impl EnabledHandler { } // determine if we need to create the outbound stream - if !self.send_queue.poll_is_empty(cx) + if !self.message_queue.is_empty() && self.outbound_substream.is_none() && !self.outbound_substream_establishing { @@ -252,22 +252,25 @@ impl EnabledHandler { { // outbound idle state Some(OutboundSubstreamState::WaitingOutput(substream)) => { - if let Poll::Ready(Some(mut message)) = self.send_queue.poll_next_unpin(cx) { + if let Poll::Ready(mut message) = Pin::new(&mut self.message_queue).poll_pop(cx) + { match message { RpcOut::Publish { message: _, ref mut timeout, + .. } | RpcOut::Forward { message: _, ref mut timeout, + .. } => { if Pin::new(timeout).poll(cx).is_ready() { // Inform the behaviour and end the poll. self.outbound_substream = Some(OutboundSubstreamState::WaitingOutput(substream)); return Poll::Ready(ConnectionHandlerEvent::NotifyBehaviour( - HandlerEvent::MessageDropped(message), + HandlerEvent::MessagesDropped(message), )); } } @@ -407,13 +410,6 @@ impl EnabledHandler { } } - // Drop the next message in queue if it's stale. - if let Poll::Ready(Some(rpc)) = self.send_queue.poll_stale(cx) { - return Poll::Ready(ConnectionHandlerEvent::NotifyBehaviour( - HandlerEvent::MessageDropped(rpc), - )); - } - Poll::Pending } } diff --git a/protocols/gossipsub/src/lib.rs b/protocols/gossipsub/src/lib.rs index 87db1b771d1..3e63e210d50 100644 --- a/protocols/gossipsub/src/lib.rs +++ b/protocols/gossipsub/src/lib.rs @@ -104,7 +104,7 @@ mod mcache; mod metrics; mod peer_score; mod protocol; -mod rpc; +mod queue; mod rpc_proto; mod subscription_filter; mod time_cache; diff --git a/protocols/gossipsub/src/metrics.rs b/protocols/gossipsub/src/metrics.rs index 485bcd54eeb..9bdcc5693de 100644 --- a/protocols/gossipsub/src/metrics.rs +++ b/protocols/gossipsub/src/metrics.rs @@ -133,10 +133,6 @@ pub(crate) struct Metrics { ignored_messages: Family, /// The number of messages rejected by the application (validation result). rejected_messages: Family, - /// The number of publish messages dropped by the sender. - publish_messages_dropped: Family, - /// The number of forward messages dropped by the sender. - forward_messages_dropped: Family, /// The number of messages that timed out and could not be sent. timedout_messages_dropped: Family, @@ -194,9 +190,7 @@ pub(crate) struct Metrics { idontwant_msgs_ids: Counter, /// The size of the priority queue. - priority_queue_size: Histogram, - /// The size of the non-priority queue. - non_priority_queue_size: Histogram, + queue_size: Histogram, } impl Metrics { @@ -245,16 +239,6 @@ impl Metrics { "Number of rejected messages received for each topic" ); - let publish_messages_dropped = register_family!( - "publish_messages_dropped_per_topic", - "Number of publish messages dropped per topic" - ); - - let forward_messages_dropped = register_family!( - "forward_messages_dropped_per_topic", - "Number of forward messages dropped per topic" - ); - let timedout_messages_dropped = register_family!( "timedout_messages_dropped_per_topic", "Number of timedout messages dropped per topic" @@ -361,18 +345,11 @@ impl Metrics { metric }; - let priority_queue_size = Histogram::new(linear_buckets(0.0, 25.0, 100)); + let queue_size = Histogram::new(linear_buckets(0.0, 50.0, 100)); registry.register( "priority_queue_size", "Histogram of observed priority queue sizes", - priority_queue_size.clone(), - ); - - let non_priority_queue_size = Histogram::new(linear_buckets(0.0, 25.0, 100)); - registry.register( - "non_priority_queue_size", - "Histogram of observed non-priority queue sizes", - non_priority_queue_size.clone(), + queue_size.clone(), ); Self { @@ -385,8 +362,6 @@ impl Metrics { accepted_messages, ignored_messages, rejected_messages, - publish_messages_dropped, - forward_messages_dropped, timedout_messages_dropped, mesh_peer_counts, mesh_peer_inclusion_events, @@ -405,8 +380,7 @@ impl Metrics { topic_iwant_msgs, idontwant_msgs, idontwant_msgs_ids, - priority_queue_size, - non_priority_queue_size, + queue_size, } } @@ -537,20 +511,6 @@ impl Metrics { } } - /// Register dropping a Publish message over a topic. - pub(crate) fn publish_msg_dropped(&mut self, topic: &TopicHash) { - if self.register_topic(topic).is_ok() { - self.publish_messages_dropped.get_or_create(topic).inc(); - } - } - - /// Register dropping a Forward message over a topic. - pub(crate) fn forward_msg_dropped(&mut self, topic: &TopicHash) { - if self.register_topic(topic).is_ok() { - self.forward_messages_dropped.get_or_create(topic).inc(); - } - } - /// Register dropping a message that timedout over a topic. pub(crate) fn timeout_msg_dropped(&mut self, topic: &TopicHash) { if self.register_topic(topic).is_ok() { @@ -616,12 +576,7 @@ impl Metrics { /// Observes a priority queue size. pub(crate) fn observe_priority_queue_size(&mut self, len: usize) { - self.priority_queue_size.observe(len as f64); - } - - /// Observes a non-priority queue size. - pub(crate) fn observe_non_priority_queue_size(&mut self, len: usize) { - self.non_priority_queue_size.observe(len as f64); + self.queue_size.observe(len as f64); } /// Observe a score of a mesh peer. diff --git a/protocols/gossipsub/src/queue.rs b/protocols/gossipsub/src/queue.rs new file mode 100644 index 00000000000..3b746778130 --- /dev/null +++ b/protocols/gossipsub/src/queue.rs @@ -0,0 +1,141 @@ +// Copyright 2020 Sigma Prime Pty Ltd. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +use std::{ + collections::{BinaryHeap, HashMap}, + sync::{ + atomic::{AtomicUsize, Ordering}, + Arc, Mutex, + }, + task::{Context, Poll, Waker}, +}; + +/// An async priority queue used to dispatch messages from the `NetworkBehaviour` +/// to the `ConnectionHandler`. Inspired by loole and flume. +#[derive(Debug)] +pub(crate) struct Queue { + shared: Arc>>, + capacity: usize, + id: usize, + count: Arc, +} + +/// The shared stated by the `NetworkBehaviour`s and the `ConnectionHandler`s. +#[derive(Debug)] +pub(crate) struct Shared { + queue: BinaryHeap, + pending_pops: HashMap, +} + +impl Queue { + /// Create a new `Queue` with the `capacity`. + pub(crate) fn new(capacity: usize) -> Self { + Self { + shared: Arc::new(Mutex::new(Shared { + queue: BinaryHeap::with_capacity(capacity), + pending_pops: Default::default(), + })), + capacity, + count: Arc::new(AtomicUsize::new(1)), + id: 1, + } + } + + /// Push an item to the queue ignoring if it's full or not. + pub(crate) fn push(&mut self, item: T) { + let mut shared = self.shared.lock().expect("lock to not be poisoned"); + shared.queue.push(item); + } + + /// Try to add an item to the Queue, return Err if the queue is full. + pub(crate) fn try_push(&mut self, item: T) -> Result<(), T> { + let mut shared = self.shared.lock().expect("lock to not be poisoned"); + if shared.queue.len() >= self.capacity { + return Err(item); + } + shared.queue.push(item); + // Wake pending registered pops. + for (_, s) in shared.pending_pops.drain() { + s.wake(); + } + Ok(()) + } + + /// Pop an element from the queue. + pub(crate) fn poll_pop(self: std::pin::Pin<&mut Self>, cx: &mut Context) -> Poll { + let mut shared = self.shared.lock().expect("lock to not be poisoned"); + match shared.queue.pop() { + Some(t) => Poll::Ready(t), + None => { + shared + .pending_pops + .entry(self.id) + .or_insert(cx.waker().clone()); + Poll::Pending + } + } + } + + /// Attempts to pop an item from the queue. + /// this method returns an error if the queue is empty. + #[cfg(test)] + pub(crate) fn try_pop(&mut self) -> Result { + let mut shared = self.shared.lock().expect("lock to not be poisoned"); + shared.queue.pop().ok_or(()) + } + + /// Retain only the elements specified by the predicate. + /// In other words, remove all elements e for which f(&e) returns false. The elements are visited in unsorted (and unspecified) order. + /// Returns the cleared items. + pub(crate) fn retain bool>(&mut self, f: F) { + let mut shared = self.shared.lock().expect("lock to not be poisoned"); + shared.queue.retain(f); + } + + /// Returns the length of the queue. + pub(crate) fn len(&self) -> usize { + let shared = self.shared.lock().expect("lock to not be poisoned"); + shared.queue.len() + } + + /// Check if the queue is empty. + pub(crate) fn is_empty(&self) -> bool { + let shared = self.shared.lock().expect("lock to not be poisoned"); + shared.queue.len() == 0 + } +} + +impl Clone for Queue { + fn clone(&self) -> Self { + Self { + shared: self.shared.clone(), + capacity: self.capacity, + count: self.count.clone(), + id: self.count.fetch_add(1, Ordering::SeqCst), + } + } +} + +impl Drop for Queue { + fn drop(&mut self) { + let mut shared = self.shared.lock().expect("lock to not be poisoned"); + shared.pending_pops.remove(&self.id); + } +} diff --git a/protocols/gossipsub/src/rpc.rs b/protocols/gossipsub/src/rpc.rs deleted file mode 100644 index 41b338267e9..00000000000 --- a/protocols/gossipsub/src/rpc.rs +++ /dev/null @@ -1,193 +0,0 @@ -// Copyright 2020 Sigma Prime Pty Ltd. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. - -use std::{ - future::Future, - pin::Pin, - sync::{ - atomic::{AtomicUsize, Ordering}, - Arc, - }, - task::{Context, Poll}, -}; - -use futures::{stream::Peekable, Stream, StreamExt}; - -use crate::types::RpcOut; - -/// `RpcOut` sender that is priority aware. -#[derive(Debug)] -pub(crate) struct Sender { - /// Capacity of the priority channel for `Publish` messages. - priority_cap: usize, - len: Arc, - pub(crate) priority_sender: async_channel::Sender, - pub(crate) non_priority_sender: async_channel::Sender, - priority_receiver: async_channel::Receiver, - non_priority_receiver: async_channel::Receiver, -} - -impl Sender { - /// Create a RpcSender. - pub(crate) fn new(cap: usize) -> Sender { - // We intentionally do not bound the channel, as we still need to send control messages - // such as `GRAFT`, `PRUNE`, `SUBSCRIBE`, and `UNSUBSCRIBE`. - // That's also why we define `cap` and divide it by two, - // to ensure there is capacity for both priority and non_priority messages. - let (priority_sender, priority_receiver) = async_channel::unbounded(); - let (non_priority_sender, non_priority_receiver) = async_channel::bounded(cap / 2); - let len = Arc::new(AtomicUsize::new(0)); - Sender { - priority_cap: cap / 2, - len, - priority_sender, - non_priority_sender, - priority_receiver, - non_priority_receiver, - } - } - - /// Create a new Receiver to the sender. - pub(crate) fn new_receiver(&self) -> Receiver { - Receiver { - priority_queue_len: self.len.clone(), - priority: Box::pin(self.priority_receiver.clone().peekable()), - non_priority: Box::pin(self.non_priority_receiver.clone().peekable()), - } - } - - #[allow(clippy::result_large_err)] - pub(crate) fn send_message(&self, rpc: RpcOut) -> Result<(), RpcOut> { - if let RpcOut::Publish { .. } = rpc { - // Update number of publish message in queue. - let len = self.len.load(Ordering::Relaxed); - if len >= self.priority_cap { - return Err(rpc); - } - self.len.store(len + 1, Ordering::Relaxed); - } - let sender = match rpc { - RpcOut::Publish { .. } - | RpcOut::Graft(_) - | RpcOut::Prune(_) - | RpcOut::Subscribe(_) - | RpcOut::Unsubscribe(_) => &self.priority_sender, - RpcOut::Forward { .. } | RpcOut::IHave(_) | RpcOut::IWant(_) | RpcOut::IDontWant(_) => { - &self.non_priority_sender - } - }; - sender.try_send(rpc).map_err(|err| err.into_inner()) - } - - /// Returns the current size of the priority queue. - pub(crate) fn priority_queue_len(&self) -> usize { - self.len.load(Ordering::Relaxed) - } - - /// Returns the current size of the non-priority queue. - pub(crate) fn non_priority_queue_len(&self) -> usize { - self.non_priority_sender.len() - } -} - -/// `RpcOut` sender that is priority aware. -#[derive(Debug)] -pub struct Receiver { - /// The maximum length of the priority queue. - pub(crate) priority_queue_len: Arc, - /// The priority queue receiver. - pub(crate) priority: Pin>>>, - /// The non priority queue receiver. - pub(crate) non_priority: Pin>>>, -} - -impl Receiver { - // Peek the next message in the queues and return it if its timeout has elapsed. - // Returns `None` if there aren't any more messages on the stream or none is stale. - pub(crate) fn poll_stale(&mut self, cx: &mut Context<'_>) -> Poll> { - // Peek priority queue. - let priority = match self.priority.as_mut().poll_peek_mut(cx) { - Poll::Ready(Some(RpcOut::Publish { - message: _, - ref mut timeout, - })) => { - if Pin::new(timeout).poll(cx).is_ready() { - // Return the message. - let dropped = futures::ready!(self.priority.poll_next_unpin(cx)) - .expect("There should be a message"); - return Poll::Ready(Some(dropped)); - } - Poll::Ready(None) - } - poll => poll, - }; - - let non_priority = match self.non_priority.as_mut().poll_peek_mut(cx) { - Poll::Ready(Some(RpcOut::Forward { - message: _, - ref mut timeout, - })) => { - if Pin::new(timeout).poll(cx).is_ready() { - // Return the message. - let dropped = futures::ready!(self.non_priority.poll_next_unpin(cx)) - .expect("There should be a message"); - return Poll::Ready(Some(dropped)); - } - Poll::Ready(None) - } - poll => poll, - }; - - match (priority, non_priority) { - (Poll::Ready(None), Poll::Ready(None)) => Poll::Ready(None), - _ => Poll::Pending, - } - } - - /// Poll queues and return true if both are empty. - pub(crate) fn poll_is_empty(&mut self, cx: &mut Context<'_>) -> bool { - matches!( - ( - self.priority.as_mut().poll_peek(cx), - self.non_priority.as_mut().poll_peek(cx), - ), - (Poll::Ready(None), Poll::Ready(None)) - ) - } -} - -impl Stream for Receiver { - type Item = RpcOut; - - fn poll_next( - mut self: std::pin::Pin<&mut Self>, - cx: &mut std::task::Context<'_>, - ) -> std::task::Poll> { - // The priority queue is first polled. - if let Poll::Ready(rpc) = Pin::new(&mut self.priority).poll_next(cx) { - if let Some(RpcOut::Publish { .. }) = rpc { - self.priority_queue_len.fetch_sub(1, Ordering::Relaxed); - } - return Poll::Ready(rpc); - } - // Then we poll the non priority. - Pin::new(&mut self.non_priority).poll_next(cx) - } -} diff --git a/protocols/gossipsub/src/types.rs b/protocols/gossipsub/src/types.rs index 4c8a3e8f54f..1a734bd3f4b 100644 --- a/protocols/gossipsub/src/types.rs +++ b/protocols/gossipsub/src/types.rs @@ -19,7 +19,11 @@ // DEALINGS IN THE SOFTWARE. //! A collection of types using the Gossipsub system. -use std::{collections::BTreeSet, fmt, fmt::Debug}; +use std::{ + cmp::Ordering, + collections::BTreeSet, + fmt::{self, Debug}, +}; use futures_timer::Delay; use hashlink::LinkedHashMap; @@ -31,36 +35,18 @@ use quick_protobuf::MessageWrite; use serde::{Deserialize, Serialize}; use web_time::Instant; -use crate::{rpc::Sender, rpc_proto::proto, TopicHash}; +use crate::{queue::Queue, rpc_proto::proto, TopicHash}; /// Messages that have expired while attempting to be sent to a peer. -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug, Default, PartialEq, Eq)] pub struct FailedMessages { - /// The number of publish messages that failed to be published in a heartbeat. - pub publish: usize, - /// The number of forward messages that failed to be published in a heartbeat. - pub forward: usize, - /// The number of messages that were failed to be sent to the priority queue as it was full. - pub priority: usize, /// The number of messages that were failed to be sent to the non-priority queue as it was /// full. - pub non_priority: usize, + pub queue_full: usize, /// The number of messages that timed out and could not be sent. pub timeout: usize, } -impl FailedMessages { - /// The total number of messages that failed due to the queue being full. - pub fn total_queue_full(&self) -> usize { - self.priority + self.non_priority - } - - /// The total failed messages in a heartbeat. - pub fn total(&self) -> usize { - self.priority + self.non_priority - } -} - #[derive(Debug)] /// Validation kinds from the application for received messages. pub enum MessageAcceptance { @@ -112,10 +98,10 @@ pub(crate) struct PeerDetails { pub(crate) connections: Vec, /// Subscribed topics. pub(crate) topics: BTreeSet, - /// The rpc sender to the connection handler(s). - pub(crate) sender: Sender, /// Don't send messages. pub(crate) dont_send: LinkedHashMap, + /// Message queue consumed by the connection handler. + pub(crate) messages: Queue, } /// Describes the types of peers that can exist in the gossipsub context. @@ -316,10 +302,18 @@ pub struct IDontWant { pub enum RpcOut { /// Publish a Gossipsub message on network.`timeout` limits the duration the message /// can wait to be sent before it is abandoned. - Publish { message: RawMessage, timeout: Delay }, + Publish { + message_id: MessageId, + message: RawMessage, + timeout: Delay, + }, /// Forward a Gossipsub message on network. `timeout` limits the duration the message /// can wait to be sent before it is abandoned. - Forward { message: RawMessage, timeout: Delay }, + Forward { + message_id: MessageId, + message: RawMessage, + timeout: Delay, + }, /// Subscribe a topic. Subscribe(TopicHash), /// Unsubscribe a topic. @@ -343,24 +337,85 @@ impl RpcOut { pub fn into_protobuf(self) -> proto::RPC { self.into() } + + /// Returns true if the `RpcOut` is high priority. + pub(crate) fn high_priority(&self) -> bool { + matches!( + self, + RpcOut::Subscribe(_) | RpcOut::Unsubscribe(_) | RpcOut::Graft(_) | RpcOut::Prune(_) + ) + } +} + +impl Eq for RpcOut {} +impl PartialEq for RpcOut { + fn eq(&self, other: &Self) -> bool { + match (self, other) { + ( + Self::Publish { + message_id: l_message_id, + .. + }, + Self::Publish { + message_id: r_message_id, + .. + }, + ) => l_message_id == r_message_id, + ( + Self::Forward { + message_id: l_message_id, + .. + }, + Self::Forward { + message_id: r_message_id, + .. + }, + ) => l_message_id == r_message_id, + (Self::Subscribe(l0), Self::Subscribe(r0)) => l0 == r0, + (Self::Unsubscribe(l0), Self::Unsubscribe(r0)) => l0 == r0, + (Self::Graft(l0), Self::Graft(r0)) => l0 == r0, + (Self::Prune(l0), Self::Prune(r0)) => l0 == r0, + (Self::IHave(l0), Self::IHave(r0)) => l0 == r0, + (Self::IWant(l0), Self::IWant(r0)) => l0 == r0, + (Self::IDontWant(l0), Self::IDontWant(r0)) => l0 == r0, + _ => false, + } + } +} + +impl Ord for RpcOut { + fn cmp(&self, other: &Self) -> Ordering { + match (self.high_priority(), other.high_priority()) { + (true, true) | (false, false) => { + // Among non priority messages, `RpcOut::Publish` has the higher priority. + match (self, other) { + (RpcOut::Publish { .. }, _) => Ordering::Greater, + (_, RpcOut::Publish { .. }) => Ordering::Less, + _ => Ordering::Equal, + } + } + (true, false) => Ordering::Greater, + (false, true) => Ordering::Less, + } + } +} + +impl PartialOrd for RpcOut { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } } impl From for proto::RPC { /// Converts the RPC into protobuf format. fn from(rpc: RpcOut) -> Self { match rpc { - RpcOut::Publish { - message, - timeout: _, - } => proto::RPC { + RpcOut::Publish { message, .. } => proto::RPC { subscriptions: Vec::new(), publish: vec![message.into()], control: None, }, - RpcOut::Forward { - message, - timeout: _, - } => proto::RPC { + RpcOut::Forward { message, .. } => proto::RPC { publish: vec![message.into()], subscriptions: Vec::new(), control: None,