diff --git a/Cargo.lock b/Cargo.lock index cbdc46554..92dab9a62 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -65,9 +65,9 @@ dependencies = [ [[package]] name = "ahash" -version = "0.8.6" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" +checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01" dependencies = [ "cfg-if", "getrandom", @@ -108,9 +108,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.5" +version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d664a92ecae85fd0a7392615844904654d1d5f5514837f471ddef4a057aba1b6" +checksum = "4cd2405b3ac1faab2990b74d728624cd9fd115651fcecc7c2d8daf01376275ba" dependencies = [ "anstyle", "anstyle-parse", @@ -156,9 +156,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.77" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9d19de80eff169429ac1e9f48fffb163916b448a44e8e046186232046d9e1f9" +checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "approx" @@ -266,11 +266,11 @@ version = "2.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6afaa937395a620e33dc6a742c593c01aced20aa376ffb0f628121198578ccc7" dependencies = [ - "async-lock 3.2.0", + "async-lock 3.3.0", "cfg-if", "concurrent-queue", "futures-io", - "futures-lite 2.1.0", + "futures-lite 2.2.0", "parking", "polling 3.3.1", "rustix 0.38.28", @@ -290,24 +290,24 @@ dependencies = [ [[package]] name = "async-lock" -version = "3.2.0" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7125e42787d53db9dd54261812ef17e937c95a51e4d291373b670342fa44310c" +checksum = "d034b430882f8381900d3fe6f0aaa3ad94f2cb4ac519b429692a1bc2dda4ae7b" dependencies = [ - "event-listener 4.0.1", + "event-listener 4.0.3", "event-listener-strategy", "pin-project-lite", ] [[package]] name = "async-trait" -version = "0.1.75" +version = "0.1.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdf6721fb0140e4f897002dd086c06f6c27775df19cfe1fccb21181a48fd2c98" +checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.48", ] [[package]] @@ -376,13 +376,13 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "axum" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "202651474fe73c62d9e0a56c6133f7a0ff1dc1c8cf7a5b03381af2a26553ac9d" +checksum = "d09dbe0e490df5da9d69b36dca48a76635288a82f92eca90024883a56202026d" dependencies = [ "async-trait", "axum-core", - "base64 0.21.5", + "base64 0.21.7", "bytes", "futures-util", "http 1.0.0", @@ -402,7 +402,7 @@ dependencies = [ "sha1", "sync_wrapper", "tokio", - "tokio-tungstenite 0.20.1", + "tokio-tungstenite 0.21.0", "tower", "tower-layer", "tower-service", @@ -410,9 +410,9 @@ dependencies = [ [[package]] name = "axum-core" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77cb22c689c44d4c07b0ab44ebc25d69d8ae601a2f28fb8d672d344178fa17aa" +checksum = "e87c8503f93e6d144ee5690907ba22db7ba79ab001a932ab99034f0fe836b3df" dependencies = [ "async-trait", "bytes", @@ -457,9 +457,9 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.21.5" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] name = "base64ct" @@ -494,7 +494,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.43", + "syn 2.0.48", ] [[package]] @@ -712,9 +712,9 @@ dependencies = [ [[package]] name = "clang-sys" -version = "1.6.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c688fc74432808e3eb684cae8830a86be1d66a2bd58e1f248ed0960a590baf6f" +checksum = "67523a3b4be3ce1989d607a828d036249522dd9c1c8de7f4dd2dae43a37369d1" dependencies = [ "glob", "libc", @@ -723,9 +723,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.12" +version = "4.4.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcfab8ba68f3668e89f6ff60f5b205cea56aa7b769451a59f34b8682f51c056d" +checksum = "58e54881c004cec7895b0068a0a954cd5d62da01aef83fa35b1e594497bf5445" dependencies = [ "clap_builder", "clap_derive", @@ -733,9 +733,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.12" +version = "4.4.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb7fb5e4e979aec3be7791562fcba452f94ad85e954da024396433e0e25a79e9" +checksum = "59cb82d7f531603d2fd1f507441cdd35184fa81beff7bd489570de7f773460bb" dependencies = [ "anstream", "anstyle", @@ -752,7 +752,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.48", ] [[package]] @@ -857,9 +857,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" dependencies = [ "libc", ] @@ -964,11 +964,10 @@ checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" [[package]] name = "crossbeam" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6eb9105919ca8e40d437fc9cbb8f1975d916f1bd28afe795a48aae32a2cc8920" +checksum = "1137cd7e7fc0fb5d3c5a8678be38ec56e819125d8d7907411fe24ccb943faca8" dependencies = [ - "cfg-if", "crossbeam-channel", "crossbeam-deque", "crossbeam-epoch", @@ -978,54 +977,46 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.10" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82a9b73a36529d9c47029b9fb3a6f0ea3cc916a261195352ba19e770fc1748b2" +checksum = "176dc175b78f56c0f321911d9c8eb2b77a78a4860b9c19db83835fea1a46649b" dependencies = [ - "cfg-if", "crossbeam-utils", ] [[package]] name = "crossbeam-deque" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fca89a0e215bab21874660c67903c5f143333cab1da83d041c7ded6053774751" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" dependencies = [ - "cfg-if", "crossbeam-epoch", "crossbeam-utils", ] [[package]] name = "crossbeam-epoch" -version = "0.9.17" +version = "0.9.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e3681d554572a651dda4186cd47240627c3d0114d45a95f6ad27f2f22e7548d" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" dependencies = [ - "autocfg", - "cfg-if", "crossbeam-utils", ] [[package]] name = "crossbeam-queue" -version = "0.3.10" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adc6598521bb5a83d491e8c1fe51db7296019d2ca3cb93cc6c2a20369a4d78a2" +checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35" dependencies = [ - "cfg-if", "crossbeam-utils", ] [[package]] name = "crossbeam-utils" -version = "0.8.18" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3a430a770ebd84726f584a90ee7f020d28db52c6d02138900f22341f866d39c" -dependencies = [ - "cfg-if", -] +checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" [[package]] name = "crypto-common" @@ -1112,7 +1103,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.48", ] [[package]] @@ -1136,7 +1127,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.43", + "syn 2.0.48", ] [[package]] @@ -1147,7 +1138,7 @@ checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ "darling_core", "quote", - "syn 2.0.43", + "syn 2.0.48", ] [[package]] @@ -1227,9 +1218,9 @@ dependencies = [ [[package]] name = "deranged" -version = "0.3.10" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eb30d70a07a3b04884d2677f06bec33509dc67ca60d92949e5535352d3191dc" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" dependencies = [ "powerfmt", "serde", @@ -1254,7 +1245,7 @@ checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611" dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.48", ] [[package]] @@ -1298,7 +1289,7 @@ checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.48", ] [[package]] @@ -1374,7 +1365,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.48", ] [[package]] @@ -1415,7 +1406,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.48", ] [[package]] @@ -1453,9 +1444,9 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "event-listener" -version = "4.0.1" +version = "4.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84f2cdcf274580f2d63697192d744727b3198894b1bf02923643bf59e2c26712" +checksum = "67b215c49b2b248c855fb73579eb1f4f26c38ffdc12973e20e07b91d78d5646e" dependencies = [ "concurrent-queue", "parking", @@ -1468,7 +1459,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "958e4d70b6d5e81971bebec42271ec641e7ff4e170a6fa605f2b8a8b65cb97d3" dependencies = [ - "event-listener 4.0.1", + "event-listener 4.0.3", "pin-project-lite", ] @@ -1657,7 +1648,7 @@ version = "0.0.5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.48", ] [[package]] @@ -1794,9 +1785,9 @@ dependencies = [ [[package]] name = "futures-lite" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aeee267a1883f7ebef3700f262d2d54de95dfaf38189015a74fdc4e0c7ad8143" +checksum = "445ba825b27408685aaecefd65178908c36c6e96aaf6d8599419d46e624192ba" dependencies = [ "futures-core", "pin-project-lite", @@ -1810,7 +1801,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.48", ] [[package]] @@ -1880,9 +1871,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" +checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" dependencies = [ "cfg-if", "js-sys", @@ -1926,9 +1917,9 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "h2" -version = "0.3.22" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d6250322ef6e60f93f9a2162799302cd6f68f79f6e5d85c8c16f14d1d958178" +checksum = "b553656127a00601c8ae5590fcfdc118e4083a7924b6cf4ffc1ea4b99dc429d7" dependencies = [ "bytes", "fnv", @@ -1945,9 +1936,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1d308f63daf4181410c242d34c11f928dcb3aa105852019e043c9d1f4e4368a" +checksum = "991910e35c615d8cab86b5ab04be67e6ad24d2bf5f4f11fdbbed26da999bbeab" dependencies = [ "bytes", "fnv", @@ -1977,7 +1968,7 @@ version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" dependencies = [ - "ahash 0.8.6", + "ahash 0.8.7", "allocator-api2", ] @@ -1996,7 +1987,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "322106e6bd0cba2d5ead589ddb8150a13d7c4217cf80d7c4f682ca994ccc6aa9" dependencies = [ - "base64 0.21.5", + "base64 0.21.7", "bytes", "headers-core", "http 1.0.0", @@ -2157,7 +2148,7 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2 0.3.22", + "h2 0.3.23", "http 0.2.11", "http-body 0.4.6", "httparse", @@ -2180,7 +2171,7 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "h2 0.4.0", + "h2 0.4.1", "http 1.0.0", "http-body 1.0.0", "httparse", @@ -2210,16 +2201,16 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.58" +version = "0.1.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8326b86b6cff230b97d0d312a6c40a60726df3332e721f72a1b035f451663b20" +checksum = "b6a67363e2aa4443928ce15e57ebae94fd8949958fd1223c4cfc0cd473ad7539" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "windows-core", + "windows-core 0.52.0", ] [[package]] @@ -2299,9 +2290,9 @@ dependencies = [ [[package]] name = "igd-next" -version = "0.14.2" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57e065e90a518ab5fedf79aa1e4b784e10f8e484a834f6bda85c42633a2cb7af" +checksum = "064d90fec10d541084e7b39ead8875a5a80d9114a2b18791565253bae25f49e4" dependencies = [ "async-trait", "attohttpc", @@ -2523,18 +2514,18 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "libc" -version = "0.2.151" +version = "0.2.152" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" +checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" [[package]] name = "libloading" -version = "0.7.4" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +checksum = "c571b676ddfc9a8c12f1f3d3085a7b163966a8fd8098a90640953ce5f6170161" dependencies = [ "cfg-if", - "winapi", + "windows-sys 0.48.0", ] [[package]] @@ -2860,7 +2851,7 @@ dependencies = [ "proc-macro-warning", "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.48", ] [[package]] @@ -2966,9 +2957,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.12" +version = "1.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d97137b25e321a73eef1418d1d5d2eda4d77e12813f8e6dead84bc52c5870a7b" +checksum = "295c17e837573c8c821dbaeb3cceb3d745ad082f7572191409e69cbc1b3fd050" dependencies = [ "cc", "libc", @@ -3588,9 +3579,9 @@ dependencies = [ [[package]] name = "opentelemetry_sdk" -version = "0.21.1" +version = "0.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "968ba3f2ca03e90e5187f5e4f46c791ef7f2c163ae87789c8ce5f5ca3b7b7de5" +checksum = "2f16aec8a98a457a52664d69e0091bac3a0abd18ead9b641cb00202ba4e0efe4" dependencies = [ "async-trait", "crossbeam-channel", @@ -3740,9 +3731,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.5" +version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae9cee2a55a544be8b89dc6848072af97a20f2422603c10865be2a42b580fff5" +checksum = "1f200d8d83c44a45b21764d1916299752ca035d15ecd46faca3e9a2a2bf6ad06" dependencies = [ "memchr", "thiserror", @@ -3751,9 +3742,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.7.5" +version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81d78524685f5ef2a3b3bd1cafbc9fcabb036253d9b1463e726a91cd16e2dfc2" +checksum = "bcd6ab1236bbdb3a49027e920e693192ebfe8913f6d60e294de57463a493cfde" dependencies = [ "pest", "pest_generator", @@ -3761,22 +3752,22 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.5" +version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68bd1206e71118b5356dae5ddc61c8b11e28b09ef6a31acbd15ea48a28e0c227" +checksum = "2a31940305ffc96863a735bef7c7994a00b325a7138fdbc5bda0f1a0476d3275" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.48", ] [[package]] name = "pest_meta" -version = "2.7.5" +version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c747191d4ad9e4a4ab9c8798f1e82a39affe7ef9648390b7e5548d18e099de6" +checksum = "a7ff62f5259e53b78d1af898941cdcdccfae7385cf7d793a6e55de5d05bb4b7d" dependencies = [ "once_cell", "pest", @@ -3806,7 +3797,7 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.48", ] [[package]] @@ -3921,12 +3912,12 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "prettyplease" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d" +checksum = "a41cf62165e97c7f814d2221421dbb9afcbcdb0a88068e5ea206e19951c2cbb5" dependencies = [ "proc-macro2", - "syn 2.0.43", + "syn 2.0.48", ] [[package]] @@ -3961,14 +3952,14 @@ checksum = "3d1eaa7fa0aa1929ffdf7eeb6eac234dde6268914a14ad44d23521ab6a9b258e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.48", ] [[package]] name = "proc-macro2" -version = "1.0.71" +version = "1.0.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75cb1540fadbd5b8fbccc4dddad2734eba435053f725621c070711a14bb5f4b8" +checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c" dependencies = [ "unicode-ident", ] @@ -3993,7 +3984,7 @@ checksum = "440f724eba9f6996b75d63681b0a92b06947f1457076d503a4d2e2c8f56442b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.48", ] [[package]] @@ -4094,9 +4085,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.33" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -4492,7 +4483,7 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" dependencies = [ - "base64 0.21.5", + "base64 0.21.7", ] [[package]] @@ -4585,18 +4576,18 @@ checksum = "58bf37232d3bb9a2c4e641ca2a11d83b5062066f88df7fed36c28772046d65ba" [[package]] name = "semver" -version = "1.0.20" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" +checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" dependencies = [ "serde", ] [[package]] name = "serde" -version = "1.0.193" +version = "1.0.195" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" +checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02" dependencies = [ "serde_derive", ] @@ -4625,29 +4616,29 @@ dependencies = [ [[package]] name = "serde_bytes" -version = "0.11.13" +version = "0.11.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bb1879ea93538b78549031e2d54da3e901fd7e75f2e4dc758d760937b123d10" +checksum = "8b8497c313fd43ab992087548117643f6fcd935cbf36f176ffda0aacf9591734" dependencies = [ "serde", ] [[package]] name = "serde_derive" -version = "1.0.193" +version = "1.0.195" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" +checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.48", ] [[package]] name = "serde_json" -version = "1.0.108" +version = "1.0.111" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" +checksum = "176e46fa42316f18edd598015a5166857fc835ec732f5215eac6b7bdbf0a84f4" dependencies = [ "itoa", "ryu", @@ -4681,7 +4672,7 @@ version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64cd236ccc1b7a29e7e2739f27c0b2dd199804abc4290e32f59f3b68d6405c23" dependencies = [ - "base64 0.21.5", + "base64 0.21.7", "chrono", "hex", "indexmap 1.9.3", @@ -4701,7 +4692,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.48", ] [[package]] @@ -4913,7 +4904,7 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d84b0a3c3739e220d94b3239fd69fb1f74bc36e16643423bd99de3b43c21bfbd" dependencies = [ - "ahash 0.8.6", + "ahash 0.8.7", "atoi", "byteorder", "bytes", @@ -4996,7 +4987,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e37195395df71fd068f6e2082247891bc11e3289624bbc776a0cdfa1ca7f1ea4" dependencies = [ "atoi", - "base64 0.21.5", + "base64 0.21.7", "bitflags 2.4.1", "byteorder", "bytes", @@ -5038,7 +5029,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6ac0ac3b7ccd10cc96c7ab29791a7dd236bd94021f31eec7ba3d46a74aa1c24" dependencies = [ "atoi", - "base64 0.21.5", + "base64 0.21.7", "bitflags 2.4.1", "byteorder", "crc", @@ -5175,9 +5166,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.43" +version = "2.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee659fb5f3d355364e1f3e5bc10fb82068efbf824a1e9d1c9504244a6469ad53" +checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" dependencies = [ "proc-macro2", "quote", @@ -5242,9 +5233,9 @@ dependencies = [ [[package]] name = "target-lexicon" -version = "0.12.12" +version = "0.12.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c39fd04924ca3a864207c66fc2cd7d22d7c016007f9ce846cbb9326331930a" +checksum = "69758bda2e78f098e4ccb393021a0963bb3442eac05f135c30f61b7370bbafae" [[package]] name = "tempfile" @@ -5261,22 +5252,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.52" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83a48fd946b02c0a526b2e9481c8e2a17755e47039164a86c4070446e3a4614d" +checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.52" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7fbe9b594d6568a6a1443250a7e67d80b74e1e96f6d1715e1e21cc1888291d3" +checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.48", ] [[package]] @@ -5382,7 +5373,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.48", ] [[package]] @@ -5551,7 +5542,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.48", ] [[package]] @@ -5958,7 +5949,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.48", "wasm-bindgen-shared", ] @@ -5980,7 +5971,7 @@ checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.48", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -6255,7 +6246,7 @@ version = "0.51.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca229916c5ee38c2f2bc1e9d8f04df975b4bd93f9955dc69fabb5d91270045c9" dependencies = [ - "windows-core", + "windows-core 0.51.1", "windows-targets 0.48.5", ] @@ -6268,6 +6259,15 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.0", +] + [[package]] name = "windows-sys" version = "0.33.0" @@ -6445,9 +6445,9 @@ checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" [[package]] name = "winnow" -version = "0.5.31" +version = "0.5.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97a4882e6b134d6c28953a387571f1acdd3496830d5e36c5e3a1075580ea641c" +checksum = "b7cf47b659b318dccbd69cc4797a39ae128f533dce7902a1096044d1967b9c16" dependencies = [ "memchr", ] @@ -6591,7 +6591,7 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.48", ] [[package]] @@ -6611,5 +6611,5 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.48", ] diff --git a/crates/core/src/message.rs b/crates/core/src/message.rs index 9e1389b69..dfc20b556 100644 --- a/crates/core/src/message.rs +++ b/crates/core/src/message.rs @@ -6,6 +6,7 @@ use std::{ time::{Duration, SystemTime}, }; +use freenet_stdlib::prelude::ContractKey; use serde::{Deserialize, Serialize}; use ulid::Ulid; @@ -228,6 +229,11 @@ pub(crate) enum NetMessage { Put(PutMsg), Get(GetMsg), Subscribe(SubscribeMsg), + Unsubscribed { + transaction: Transaction, + key: ContractKey, + from: PeerId, + }, Update(UpdateMsg), /// Failed a transaction, informing of abortion. Aborted(Transaction), @@ -294,6 +300,7 @@ impl NetMessage { Subscribe(op) => op.id(), Update(op) => op.id(), Aborted(tx) => tx, + Unsubscribed { transaction, .. } => transaction, } } @@ -306,6 +313,7 @@ impl NetMessage { Subscribe(op) => op.target(), Update(op) => op.target(), Aborted(_) => None, + Unsubscribed { .. } => None, } } @@ -319,6 +327,7 @@ impl NetMessage { Subscribe(op) => op.terminal(), Update(op) => op.terminal(), Aborted(_) => true, + Unsubscribed { .. } => true, } } @@ -331,6 +340,7 @@ impl NetMessage { Subscribe(op) => op.requested_location(), Update(op) => op.requested_location(), Aborted(_) => None, + Unsubscribed { .. } => None, } } @@ -351,6 +361,9 @@ impl Display for NetMessage { Subscribe(msg) => msg.fmt(f)?, Update(msg) => msg.fmt(f)?, Aborted(msg) => msg.fmt(f)?, + Unsubscribed { key, from, .. } => { + write!(f, "Unsubscribed {{ key: {}, from: {} }}", key, from)?; + } }; write!(f, "}}") } diff --git a/crates/core/src/node.rs b/crates/core/src/node.rs index 316c3fc88..3b2e906b9 100644 --- a/crates/core/src/node.rs +++ b/crates/core/src/node.rs @@ -19,7 +19,10 @@ use std::{ }; use either::Either; -use freenet_stdlib::client_api::{ClientRequest, ContractRequest, ErrorKind}; +use freenet_stdlib::{ + client_api::{ClientRequest, ContractRequest, ErrorKind}, + prelude::ContractKey, +}; use libp2p::{identity, multiaddr::Protocol, Multiaddr, PeerId as Libp2pPeerId}; use serde::{Deserialize, Serialize}; use tracing::Instrument; @@ -421,61 +424,7 @@ async fn process_open_request(request: OpenRequest<'static>, op_manager: Arc { - const TIMEOUT: Duration = Duration::from_secs(30); - let mut missing_contract = false; - let timeout = tokio::time::timeout(TIMEOUT, async { - // Initialize a subscribe op. - loop { - let op = subscribe::start_op(key.clone()); - let _ = op_manager - .ch_outbound - .waiting_for_transaction_result(op.id, client_id) - .await; - match subscribe::request_subscribe(&op_manager, op).await { - Err(OpError::ContractError(ContractError::ContractNotFound( - key, - ))) if !missing_contract => { - tracing::info!(%key, "Trying to subscribe to a contract not present, requesting it first"); - missing_contract = true; - let get_op = get::start_op(key.clone(), true); - if let Err(error) = get::request_get(&op_manager, get_op).await - { - tracing::error!(%key, %error, "Failed getting the contract while previously trying to subscribe; bailing"); - break Err(error); - } - continue; - } - Err(OpError::ContractError(ContractError::ContractNotFound(_))) => { - tracing::warn!("Still waiting for {key} contract"); - tokio::time::sleep(Duration::from_secs(2)).await - } - Err(err) => { - tracing::error!("{}", err); - break Err(err); - } - Ok(()) => { - if missing_contract { - tracing::debug!(%key, - "Got back the missing contract while subscribing" - ); - } - tracing::debug!(%key, "Starting subscribe request"); - break Ok(()); - } - } - } - }); - match timeout.await { - Err(_) => { - tracing::error!(%key, "Timeout while waiting for contract to start subscription"); - } - Ok(Err(error)) => { - tracing::error!(%key, %error, "Error while subscribing to contract"); - } - Ok(Ok(_)) => { - tracing::debug!(%key, "Started subscription to contract"); - } - } + subscribe(op_manager, key, Some(client_id)).await; } _ => { tracing::error!("Op not supported"); @@ -698,11 +647,75 @@ async fn process_message( ) .await; } + NetMessage::Unsubscribed { key, .. } => { + subscribe(op_manager, key.clone(), None).await; + break; + } _ => break, } } } +/// Attempts to subscribe to a contract +async fn subscribe(op_manager: Arc, key: ContractKey, client_id: Option) { + const TIMEOUT: Duration = Duration::from_secs(30); + let mut missing_contract = false; + let timeout = tokio::time::timeout(TIMEOUT, async { + // Initialize a subscribe op. + loop { + let op = subscribe::start_op(key.clone()); + if let Some(client_id) = client_id { + let _ = op_manager + .ch_outbound + .waiting_for_transaction_result(op.id, client_id) + .await; + } + match subscribe::request_subscribe(&op_manager, op).await { + Err(OpError::ContractError(ContractError::ContractNotFound(key))) + if !missing_contract => + { + tracing::info!(%key, "Trying to subscribe to a contract not present, requesting it first"); + missing_contract = true; + let get_op = get::start_op(key.clone(), true); + if let Err(error) = get::request_get(&op_manager, get_op).await { + tracing::error!(%key, %error, "Failed getting the contract while previously trying to subscribe; bailing"); + break Err(error); + } + continue; + } + Err(OpError::ContractError(ContractError::ContractNotFound(_))) => { + tracing::warn!("Still waiting for {key} contract"); + tokio::time::sleep(Duration::from_secs(2)).await + } + Err(err) => { + tracing::error!("{}", err); + break Err(err); + } + Ok(()) => { + if missing_contract { + tracing::debug!(%key, + "Got back the missing contract while subscribing" + ); + } + tracing::debug!(%key, "Starting subscribe request"); + break Ok(()); + } + } + } + }); + match timeout.await { + Err(_) => { + tracing::error!(%key, "Timeout while waiting for contract to start subscription"); + } + Ok(Err(error)) => { + tracing::error!(%key, %error, "Error while subscribing to contract"); + } + Ok(Ok(_)) => { + tracing::debug!(%key, "Started subscription to contract"); + } + } +} + async fn handle_aborted_op( tx: Transaction, this_peer: PeerId, diff --git a/crates/core/src/node/testing_impl.rs b/crates/core/src/node/testing_impl.rs index e7364f17e..ab6a5d315 100644 --- a/crates/core/src/node/testing_impl.rs +++ b/crates/core/src/node/testing_impl.rs @@ -127,7 +127,7 @@ impl<'a> From<&'a str> for NodeLabel { #[cfg(test)] #[derive(Clone)] pub(crate) struct NodeSpecification { - pub owned_contracts: Vec<(ContractContainer, WrappedState, Option)>, + pub owned_contracts: Vec<(ContractContainer, WrappedState, bool)>, pub events_to_generate: HashMap>, pub contract_subscribers: HashMap>, } @@ -283,7 +283,7 @@ pub(super) struct Builder { contract_handler_name: String, add_noise: bool, event_register: ER, - contracts: Vec<(ContractContainer, WrappedState, Option)>, + contracts: Vec<(ContractContainer, WrappedState, bool)>, contract_subscribers: HashMap>, } diff --git a/crates/core/src/node/testing_impl/in_memory.rs b/crates/core/src/node/testing_impl/in_memory.rs index 885bb0e5d..df192bc89 100644 --- a/crates/core/src/node/testing_impl/in_memory.rs +++ b/crates/core/src/node/testing_impl/in_memory.rs @@ -78,7 +78,7 @@ impl Builder { #[cfg(test)] pub fn append_contracts( &mut self, - contracts: Vec<(ContractContainer, WrappedState, Option)>, + contracts: Vec<(ContractContainer, WrappedState, bool)>, contract_subscribers: std::collections::HashMap>, ) { self.contracts.extend(contracts); @@ -93,7 +93,7 @@ where { async fn append_contracts( &mut self, - contracts: Vec<(ContractContainer, WrappedState, Option)>, + contracts: Vec<(ContractContainer, WrappedState, bool)>, contract_subscribers: HashMap>, ) -> Result<(), anyhow::Error> { use crate::contract::ContractHandlerEvent; @@ -112,10 +112,8 @@ where key, self.op_manager.ring.peer_key ); - if let Some(subscription) = subscription { - self.op_manager - .ring - .add_subscription(key.clone(), subscription); + if subscription { + self.op_manager.ring.seed_contract(key.clone()); } if let Some(subscribers) = contract_subscribers.get(&key) { // add contract subscribers diff --git a/crates/core/src/operations/get.rs b/crates/core/src/operations/get.rs index 27280277b..58bc44901 100644 --- a/crates/core/src/operations/get.rs +++ b/crates/core/src/operations/get.rs @@ -593,9 +593,7 @@ impl Operation for GetOp { .. }) ); - let should_subscribe = op_manager - .ring - .within_subscribing_distance(&Location::from(&key)); + let should_subscribe = op_manager.ring.should_seed(&key); let should_put = is_original_requester || should_subscribe; if should_put { @@ -610,7 +608,7 @@ impl Operation for GetOp { match res { ContractHandlerEvent::PutResponse { new_value: Ok(_) } => { let is_subscribed_contract = - op_manager.ring.is_subscribed_to_contract(&key); + op_manager.ring.is_seeding_contract(&key); if !is_subscribed_contract && should_subscribe { tracing::debug!(tx = %id, %key, peer = %op_manager.ring.peer_key, "Contract not cached @ peer, caching"); super::start_subscription_request( @@ -953,7 +951,7 @@ mod test { owned_contracts: vec![( ContractContainer::Wasm(ContractWasmAPIVersion::V1(contract)), contract_val, - None, + false, )], events_to_generate: HashMap::new(), contract_subscribers: HashMap::new(), @@ -1048,7 +1046,7 @@ mod test { owned_contracts: vec![( ContractContainer::Wasm(ContractWasmAPIVersion::V1(contract)), contract_val, - None, + false, )], events_to_generate: HashMap::new(), contract_subscribers: HashMap::new(), diff --git a/crates/core/src/operations/put.rs b/crates/core/src/operations/put.rs index 4cc843c42..675888cd1 100644 --- a/crates/core/src/operations/put.rs +++ b/crates/core/src/operations/put.rs @@ -235,7 +235,7 @@ impl Operation for PutOp { sender, } => { let key = contract.key(); - let is_subscribed_contract = op_manager.ring.is_subscribed_to_contract(&key); + let is_subscribed_contract = op_manager.ring.is_seeding_contract(&key); tracing::debug!( tx = %id, @@ -244,11 +244,7 @@ impl Operation for PutOp { "Puttting contract at target peer", ); - if is_subscribed_contract - || op_manager - .ring - .within_subscribing_distance(&Location::from(&key)) - { + if is_subscribed_contract || op_manager.ring.should_seed(&key) { tracing::debug!(tx = %id, "Attempting contract value update"); put_contract( op_manager, @@ -432,13 +428,8 @@ impl Operation for PutOp { PutMsg::SuccessfulPut { id, .. } => { match self.state { Some(PutState::AwaitingResponse { key, upstream }) => { - let is_subscribed_contract = - op_manager.ring.is_subscribed_to_contract(&key); - if !is_subscribed_contract - && op_manager - .ring - .within_subscribing_distance(&Location::from(&key)) - { + let is_subscribed_contract = op_manager.ring.is_seeding_contract(&key); + if !is_subscribed_contract && op_manager.ring.should_seed(&key) { tracing::debug!(tx = %id, %key, peer = %op_manager.ring.peer_key, "Contract not cached @ peer, caching"); super::start_subscription_request(op_manager, key.clone(), true) .await; @@ -479,11 +470,8 @@ impl Operation for PutOp { "Forwarding changes, trying put the contract" ); - let is_subscribed_contract = op_manager.ring.is_subscribed_to_contract(&key); - let within_caching_dist = op_manager - .ring - .within_subscribing_distance(&Location::from(&key)); - if is_subscribed_contract || within_caching_dist { + let should_seed = op_manager.ring.should_seed(&key); + if should_seed { // after the contract has been cached, push the update query put_contract( op_manager, @@ -510,7 +498,8 @@ impl Operation for PutOp { new_skip_list, ) .await; - if put_here && !is_subscribed_contract { + let is_seeding_contract = op_manager.ring.is_seeding_contract(&key); + if put_here && !is_seeding_contract && should_seed { // if already subscribed the value was already put and merging succeeded put_contract( op_manager, @@ -520,6 +509,22 @@ impl Operation for PutOp { contract, ) .await?; + let (dropped_contract, old_subscribers) = + op_manager.ring.seed_contract(key.clone()); + if let Some(key) = dropped_contract { + for subscriber in old_subscribers { + conn_manager + .send( + &subscriber.peer, + NetMessage::Unsubscribed { + transaction: Transaction::new::(), + key: key.clone(), + from: op_manager.ring.peer_key, + }, + ) + .await?; + } + } } put_here } else { @@ -564,7 +569,7 @@ impl Operation for PutOp { impl OpManager { fn get_broadcast_targets(&self, key: &ContractKey, sender: &PeerId) -> Vec { - let mut subscribers = self + let subscribers = self .ring .subscribers_of(key) .map(|subs| { @@ -575,9 +580,6 @@ impl OpManager { .collect::>() }) .unwrap_or_default(); - if let Some(peer) = self.ring.subscribed_to_contract(key) { - subscribers.push(peer); - } subscribers } } @@ -1022,7 +1024,6 @@ mod test { ) .await; let mut locations = sim_nw.get_locations_by_node(); - let gw0_loc = locations.remove(&"gateway-0".into()).unwrap(); let node0_loc = locations.remove(&"node-1".into()).unwrap(); let node1_loc = locations.remove(&"node-2".into()).unwrap(); @@ -1031,7 +1032,7 @@ mod test { owned_contracts: vec![( ContractContainer::Wasm(ContractWasmAPIVersion::V1(contract.clone())), contract_val.clone(), - Some(gw0_loc), + false, )], events_to_generate: HashMap::new(), contract_subscribers: HashMap::new(), @@ -1041,7 +1042,7 @@ mod test { owned_contracts: vec![( ContractContainer::Wasm(ContractWasmAPIVersion::V1(contract.clone())), contract_val.clone(), - Some(gw0_loc), + false, )], events_to_generate: HashMap::new(), contract_subscribers: HashMap::new(), @@ -1058,7 +1059,7 @@ mod test { owned_contracts: vec![( ContractContainer::Wasm(ContractWasmAPIVersion::V1(contract.clone())), contract_val, - None, + false, )], events_to_generate: HashMap::from_iter([(1, put_event)]), contract_subscribers: HashMap::from_iter([(key.clone(), vec![node0_loc, node1_loc])]), diff --git a/crates/core/src/operations/subscribe.rs b/crates/core/src/operations/subscribe.rs index c6f172f79..153a2d2a6 100644 --- a/crates/core/src/operations/subscribe.rs +++ b/crates/core/src/operations/subscribe.rs @@ -381,7 +381,7 @@ impl Operation for SubscribeOp { provider = %sender.peer, "Subscribed to contract" ); - op_manager.ring.add_subscription(key.clone(), *sender); + op_manager.ring.register_subscription(key, *sender); new_state = Some(SubscribeState::Completed {}); if let Some(upstream_subscriber) = upstream_subscriber { @@ -542,7 +542,7 @@ mod test { owned_contracts: vec![( ContractContainer::Wasm(ContractWasmAPIVersion::V1(contract)), contract_val, - None, + true, )], events_to_generate: HashMap::new(), contract_subscribers: HashMap::new(), diff --git a/crates/core/src/ring.rs b/crates/core/src/ring.rs index 42a4ba7b6..ae84781b9 100644 --- a/crates/core/src/ring.rs +++ b/crates/core/src/ring.rs @@ -156,6 +156,23 @@ impl LiveTransactionTracker { } } +#[derive(PartialEq, Clone, Copy)] +struct Score(f64); + +impl PartialOrd for Score { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for Score { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + self.partial_cmp(other).unwrap_or(std::cmp::Ordering::Equal) + } +} + +impl Eq for Score {} + /// Thread safe and friendly data structure to keep track of the local knowledge /// of the state of the ring. /// @@ -179,8 +196,8 @@ pub(crate) struct Ring { /// of subscribers more often than inserting, and anyways is a relatively short sequence /// then is more optimal to just use a vector for it's compact memory layout. subscribers: DashMap>, - /// Contracts this peer is subscribed to. - subscriptions: DashMap, + /// Contracts this peer is seeding. + seeding_contract: DashMap, /// Interim connections ongoing handshake or successfully open connections /// Is important to keep track of this so no more connections are accepted prematurely. open_connections: AtomicUsize, @@ -215,12 +232,21 @@ impl Ring { /// Max number of subscribers for a contract. const MAX_SUBSCRIBERS: usize = 10; + /// All subscribers, including the upstream subscriber. + const TOTAL_MAX_SUBSCRIPTIONS: usize = Self::MAX_SUBSCRIBERS + 1; + /// Above this number of remaining hops, randomize which node a message which be forwarded to. const DEFAULT_RAND_WALK_ABOVE_HTL: usize = 7; /// Max hops to be performed for certain operations (e.g. propagating connection of a peer in the network). const DEFAULT_MAX_HOPS_TO_LIVE: usize = 10; + /// Max number of seeding contracts. + const MAX_SEEDING_CONTRACTS: usize = 100; + + /// Min number of seeding contracts. + const MIN_SEEDING_CONTRACTS: usize = Self::MAX_SEEDING_CONTRACTS / 4; + pub fn new( config: &NodeConfig, event_loop_notifier: EventLoopNotificationsSender, @@ -293,7 +319,7 @@ impl Ring { own_location, peer_key, subscribers: DashMap::new(), - subscriptions: DashMap::new(), + seeding_contract: DashMap::new(), open_connections: AtomicUsize::new(0), live_tx_tracker: live_tx_tracker.clone(), event_register: Box::new(event_register), @@ -349,32 +375,66 @@ impl Ring { } } - /// Return if a location is within appropiate subscription distance. - pub fn within_subscribing_distance(&self, loc: &Location) -> bool { + /// Return if a contract is within appropiate seeding distance. + pub fn should_seed(&self, key: &ContractKey) -> bool { const CACHING_DISTANCE: f64 = 0.05; - const MAX_CACHED: usize = 100; - const MIN_CACHED: usize = MAX_CACHED / 4; let caching_distance = Distance::new(CACHING_DISTANCE); - if self.subscriptions.len() < MIN_CACHED { + if self.seeding_contract.len() < Self::MIN_SEEDING_CONTRACTS { return true; } - self.subscriptions.len() < MAX_CACHED - && self - .own_location() - .location - .map(|own_loc| own_loc.distance(loc) <= caching_distance) - .unwrap_or(false) + let key_loc = Location::from(key); + let own_loc = self.own_location().location.expect("should be set"); + if self.seeding_contract.len() < Self::MAX_SEEDING_CONTRACTS { + return own_loc.distance(key_loc) <= caching_distance; + } + + let contract_score = self.calculate_seed_score(key); + let r = self + .seeding_contract + .iter() + .min_by_key(|v| *v.value()) + .unwrap(); + let min_score = *r.value(); + contract_score > min_score } - /// Whether this node already is subscribed to this contract or not. - #[inline] - pub fn is_subscribed_to_contract(&self, key: &ContractKey) -> bool { - self.subscriptions.contains_key(key) + /// Add a new subscription for this peer. + pub fn seed_contract(&self, key: ContractKey) -> (Option, Vec) { + let seed_score = self.calculate_seed_score(&key); + let mut old_subscribers = vec![]; + let mut contract_to_drop = None; + if self.seeding_contract.len() < Self::MAX_SEEDING_CONTRACTS { + let dropped_contract = self + .seeding_contract + .iter() + .min_by_key(|v| *v.value()) + .unwrap() + .key() + .clone(); + self.seeding_contract.remove(&dropped_contract); + if let Some((_, mut subscribers_of_contract)) = + self.subscribers.remove(&dropped_contract) + { + std::mem::swap(&mut subscribers_of_contract, &mut old_subscribers); + } + contract_to_drop = Some(dropped_contract); + } + self.seeding_contract.insert(key, seed_score); + (contract_to_drop, old_subscribers) } + fn calculate_seed_score(&self, key: &ContractKey) -> Score { + let location = self.own_location().location.expect("should be set"); + let key_loc = Location::from(key); + let distance = key_loc.distance(location); + let score = 0.5 - distance.as_f64(); + Score(score) + } + + /// Whether this node already is seeding to this contract or not. #[inline] - pub fn subscribed_to_contract(&self, key: &ContractKey) -> Option { - self.subscriptions.get(key).map(|v| *v.value()) + pub fn is_seeding_contract(&self, key: &ContractKey) -> bool { + self.seeding_contract.contains_key(key) } /// Update this node location. @@ -551,6 +611,14 @@ impl Ring { } } + pub fn register_subscription(&self, contract: &ContractKey, subscriber: PeerKeyLocation) { + self.subscribers + .entry(contract.clone()) + .or_insert(Vec::with_capacity(Self::TOTAL_MAX_SUBSCRIPTIONS)) + .value_mut() + .push(subscriber); + } + /// Will return an error in case the max number of subscribers has been added. pub fn add_subscriber( &self, @@ -560,7 +628,7 @@ impl Ring { let mut subs = self .subscribers .entry(contract.clone()) - .or_insert(Vec::with_capacity(Self::MAX_SUBSCRIBERS)); + .or_insert(Vec::with_capacity(Self::TOTAL_MAX_SUBSCRIPTIONS)); if subs.len() >= Self::MAX_SUBSCRIBERS { return Err(()); } @@ -575,11 +643,6 @@ impl Ring { Ok(()) } - /// Add a new subscription for this peer. - pub fn add_subscription(&self, contract: ContractKey, peer: PeerKeyLocation) { - self.subscriptions.insert(contract, peer); - } - pub fn subscribers_of( &self, contract: &ContractKey, diff --git a/crates/core/src/server.rs b/crates/core/src/server.rs index 84cf29fe5..fb54d18be 100644 --- a/crates/core/src/server.rs +++ b/crates/core/src/server.rs @@ -85,7 +85,7 @@ pub mod local_node { serve(socket, ws_router.layer(TraceLayer::new_for_http())); - // FIXME: use combinator instead + // TODO: use combinator instead // let mut all_clients = // ClientEventsCombinator::new([Box::new(ws_handle), Box::new(http_handle)]); enum Receiver { diff --git a/crates/core/src/wasm_runtime/contract.rs b/crates/core/src/wasm_runtime/contract.rs index c1a019f54..c65aa05c6 100644 --- a/crates/core/src/wasm_runtime/contract.rs +++ b/crates/core/src/wasm_runtime/contract.rs @@ -116,7 +116,6 @@ impl ContractRuntimeInterface for super::Runtime { Ok(is_valid) } - // FIXME: actually use this in the executor! fn validate_delta<'a>( &mut self, key: &ContractKey, diff --git a/crates/core/src/wasm_runtime/contract_store.rs b/crates/core/src/wasm_runtime/contract_store.rs index 3f2b5c094..3942cec97 100644 --- a/crates/core/src/wasm_runtime/contract_store.rs +++ b/crates/core/src/wasm_runtime/contract_store.rs @@ -64,7 +64,7 @@ impl ContractStore { } /// Returns a copy of the contract bytes if available, none otherwise. - // FIXME: instead return Result, _> to handle IO errors upstream + // todo: instead return Result, _> to handle IO errors upstream pub fn fetch_contract( &self, key: &ContractKey, diff --git a/crates/fdev/src/network_metrics_server.rs b/crates/fdev/src/network_metrics_server.rs index 68b7ac14a..480bbd3b4 100644 --- a/crates/fdev/src/network_metrics_server.rs +++ b/crates/fdev/src/network_metrics_server.rs @@ -346,7 +346,7 @@ async fn record_saver( change: Change, } - // FIXME: this ain't flushing correctly after test ends, + // todo: this ain't flushing correctly after test ends, // for now flushing each single time we get a new record // let mut batch = Vec::with_capacity(1024); while let Ok(change) = incoming_rec.recv().await {