diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 151e8a8a50..f2899484dd 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -22,7 +22,7 @@ jobs: - tokio runs-on: ubuntu-latest steps: - - uses: styfle/cancel-workflow-action@0.11.0 + - uses: styfle/cancel-workflow-action@0.12.0 name: Cancel Outdated Builds with: all_but_latest: true diff --git a/.github/workflows/build_arm_nix.yml b/.github/workflows/build_arm_nix.yml index 44878cdefe..b1f76073af 100644 --- a/.github/workflows/build_arm_nix.yml +++ b/.github/workflows/build_arm_nix.yml @@ -20,7 +20,7 @@ jobs: volumes: - github_nix:/nix steps: - - uses: styfle/cancel-workflow-action@0.11.0 + - uses: styfle/cancel-workflow-action@0.12.0 name: Cancel Outdated Builds with: all_but_latest: true diff --git a/.github/workflows/build_nix.yml b/.github/workflows/build_nix.yml index a98c9ae2b4..cceee336f3 100644 --- a/.github/workflows/build_nix.yml +++ b/.github/workflows/build_nix.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 120 steps: - - uses: styfle/cancel-workflow-action@0.11.0 + - uses: styfle/cancel-workflow-action@0.12.0 name: Cancel Outdated Builds with: all_but_latest: true diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 5dd6b32725..304e2fd377 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -9,7 +9,7 @@ jobs: code-coverage: runs-on: ubuntu-latest steps: - - uses: styfle/cancel-workflow-action@0.11.0 + - uses: styfle/cancel-workflow-action@0.12.0 name: Cancel Outdated Builds with: all_but_latest: true diff --git a/.github/workflows/doc.yml b/.github/workflows/doc.yml index bb6f576711..5df5b3430f 100644 --- a/.github/workflows/doc.yml +++ b/.github/workflows/doc.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 35 steps: - - uses: styfle/cancel-workflow-action@0.11.0 + - uses: styfle/cancel-workflow-action@0.12.0 name: Cancel Outdated Builds with: all_but_latest: true diff --git a/Cargo.lock b/Cargo.lock index 97d4568a8d..55d6b94b3c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -140,9 +140,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.0.5" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c378d78423fdad8089616f827526ee33c19f2fddbd5de1629152c9593ba4783" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" dependencies = [ "memchr", ] @@ -178,15 +178,15 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.2" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15c4c2c83f81532e5845a733998b6971faca23490340a418e9b72a3ec9de12ea" +checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" [[package]] name = "anstyle-parse" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333" +checksum = "317b9a89c1868f5ea6ff1d9539a69f45dffc21ce321ac1fd1160dfa48c8e2140" dependencies = [ "utf8parse", ] @@ -575,7 +575,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" dependencies = [ "concurrent-queue", - "event-listener", + "event-listener 2.5.3", "futures-core", ] @@ -611,14 +611,14 @@ dependencies = [ [[package]] name = "async-executor" -version = "1.5.1" +version = "1.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fa3dc5f2a8564f07759c008b9109dc0d39de92a88d5588b8a5036d286383afb" +checksum = "2c1da3ae8dabd9c00f453a329dfe1fb28da3c0a72e2478cdcd93171740c20499" dependencies = [ "async-lock", "async-task", "concurrent-queue", - "fastrand", + "fastrand 2.0.1", "futures-lite", "slab", ] @@ -680,7 +680,7 @@ dependencies = [ "log", "parking", "polling", - "rustix", + "rustix 0.37.24", "slab", "socket2 0.4.9", "waker-fn", @@ -692,36 +692,52 @@ version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b" dependencies = [ - "event-listener", + "event-listener 2.5.3", ] [[package]] name = "async-net" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4051e67316bc7eff608fe723df5d32ed639946adcd69e07df41fd42a7b411f1f" +checksum = "0434b1ed18ce1cf5769b8ac540e33f01fa9471058b5e89da9e06f3c882a8c12f" dependencies = [ "async-io", - "autocfg", "blocking", "futures-lite", ] [[package]] name = "async-process" -version = "1.7.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a9d28b1d97e08915212e2e45310d47854eafa69600756fc735fb788f75199c9" +checksum = "ea6438ba0a08d81529c69b36700fa2f95837bfe3e776ab39cde9c14d9149da88" dependencies = [ "async-io", "async-lock", - "autocfg", + "async-signal", "blocking", "cfg-if", - "event-listener", + "event-listener 3.0.0", "futures-lite", - "rustix", - "signal-hook", + "rustix 0.38.18", + "windows-sys", +] + +[[package]] +name = "async-signal" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1079d27511f6c038736279421774ef4ad4bdd2e300825f4a48c4cc463a57cedf" +dependencies = [ + "async-io", + "async-lock", + "atomic-waker", + "cfg-if", + "futures-core", + "futures-io", + "rustix 0.38.18", + "signal-hook-registry", + "slab", "windows-sys", ] @@ -784,9 +800,9 @@ dependencies = [ [[package]] name = "async-task" -version = "4.4.0" +version = "4.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc7ab41815b3c653ccd2978ec3255c81349336702dfdf62ee6f7069b12a3aae" +checksum = "b9441c6b2fe128a7c2bf680a44c34d0df31ce09e5b7e401fcca3faa483dbc921" [[package]] name = "async-trait" @@ -796,7 +812,7 @@ checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.31", + "syn 2.0.38", ] [[package]] @@ -832,7 +848,7 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4057f2c32adbb2fc158e22fb38433c8e9bbf76b75a4732c7c0cbaf695fb65568" dependencies = [ - "bytes 1.4.0", + "bytes 1.5.0", "futures-sink", "futures-util", "memchr", @@ -841,9 +857,9 @@ dependencies = [ [[package]] name = "atomic-waker" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1181e1e0d1fce796a03db1ae795d67167da795f9cf4a39c37589e85ef57f26d3" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "atomic_enum" @@ -871,7 +887,7 @@ dependencies = [ "async-trait", "axum-core", "bitflags 1.3.2", - "bytes 1.4.0", + "bytes 1.5.0", "futures-util", "http", "http-body", @@ -897,7 +913,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" dependencies = [ "async-trait", - "bytes 1.4.0", + "bytes 1.5.0", "futures-util", "http", "http-body", @@ -942,9 +958,9 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.21.3" +version = "0.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "414dcefbc63d77c526a76b3afcf6fbb9b5e2791c19c3aa2297733208750c6e53" +checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" [[package]] name = "base64ct" @@ -1035,17 +1051,18 @@ dependencies = [ [[package]] name = "blocking" -version = "1.3.1" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77231a1c8f801696fc0123ec6150ce92cffb8e164a02afb9c8ddee0e9b65ad65" +checksum = "8c36a4d0d48574b3dd360b4b7d95cc651d2b6557b6402848a27d4b228a473e2a" dependencies = [ "async-channel", "async-lock", "async-task", - "atomic-waker", - "fastrand", + "fastrand 2.0.1", + "futures-io", "futures-lite", - "log", + "piper", + "tracing", ] [[package]] @@ -1069,9 +1086,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.13.0" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" [[package]] name = "byte-slice-cast" @@ -1081,9 +1098,9 @@ checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" [[package]] name = "byteorder" -version = "1.4.3" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" @@ -1093,9 +1110,9 @@ checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38" [[package]] name = "bytes" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" dependencies = [ "serde", ] @@ -1166,9 +1183,9 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.28" +version = "0.4.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95ed24df0632f708f5f6d8082675bef2596f7084dee3dd55f632290bf35bfe0f" +checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" dependencies = [ "android-tzdata", "iana-time-zone", @@ -1237,7 +1254,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.31", + "syn 2.0.38", ] [[package]] @@ -1298,9 +1315,9 @@ dependencies = [ [[package]] name = "concurrent-queue" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62ec6771ecfa0762d24683ee5a32ad78487a3d3afdc0fb8cae19d2c5deb50b7c" +checksum = "f057a694a54f12365049b0958a1685bb52d567f5593b355fbf685838e873d400" dependencies = [ "crossbeam-utils", ] @@ -1543,7 +1560,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "704722d1d929489c8528bb1882805700f1ba20f54325704973e786352320b1ed" dependencies = [ "blake2", - "curve25519-dalek 4.0.0", + "curve25519-dalek 4.1.1", "rand_core 0.6.4", "serdect", ] @@ -1594,9 +1611,9 @@ dependencies = [ [[package]] name = "curl-sys" -version = "0.4.65+curl-8.2.1" +version = "0.4.67+curl-8.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "961ba061c9ef2fe34bbd12b807152d96f0badd2bebe7b90ce6c8c8b7572a0986" +checksum = "3cc35d066510b197a0f72de863736641539957628c8a42e70e27c66849e77c34" dependencies = [ "cc", "libc", @@ -1605,7 +1622,7 @@ dependencies = [ "openssl-sys", "pkg-config", "vcpkg", - "winapi", + "windows-sys", ] [[package]] @@ -1623,9 +1640,9 @@ dependencies = [ [[package]] name = "curve25519-dalek" -version = "4.0.0" +version = "4.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f711ade317dd348950a9910f81c5947e3d8907ebd2b83f76203ff1807e6a2bc2" +checksum = "e89b8c6a2e4b1f45971ad09761aafb85514a84744b67a95e32c3cc1352d1f65c" dependencies = [ "cfg-if", "cpufeatures", @@ -1646,7 +1663,7 @@ checksum = "83fdaf97f4804dcebfa5862639bc9ce4121e82140bec2a987ac5140294865b5b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.31", + "syn 2.0.38", ] [[package]] @@ -1714,7 +1731,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.31", + "syn 2.0.38", ] [[package]] @@ -1736,7 +1753,7 @@ checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ "darling_core 0.20.3", "quote", - "syn 2.0.31", + "syn 2.0.38", ] [[package]] @@ -1746,7 +1763,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" dependencies = [ "cfg-if", - "hashbrown 0.14.0", + "hashbrown 0.14.1", "lock_api", "once_cell", "parking_lot_core", @@ -1830,7 +1847,7 @@ checksum = "53e0efad4403bfc52dc201159c4b842a246a14b98c64b55dfd0f2d89729dfeb8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.31", + "syn 2.0.38", ] [[package]] @@ -1952,7 +1969,7 @@ checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.31", + "syn 2.0.38", ] [[package]] @@ -1981,9 +1998,9 @@ checksum = "dcbb2bf8e87535c23f7a8a321e364ce21462d0ff10cb6407820e8e96dfff6653" [[package]] name = "dyn-clone" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbfc4744c1b8f2a09adc0e55242f60b1af195d88596bd8700be74418c056c555" +checksum = "23d2f3407d9a573d666de4b5bdf10569d73ca9478087346697dcbae6244bfbcd" [[package]] name = "ed25519" @@ -2001,7 +2018,7 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7277392b266383ef8396db7fdeb1e77b6c52fed775f5df15bb24f35b72156980" dependencies = [ - "curve25519-dalek 4.0.0", + "curve25519-dalek 4.1.1", "ed25519", "rand_core 0.6.4", "serde", @@ -2074,25 +2091,14 @@ dependencies = [ [[package]] name = "errno" -version = "0.3.3" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd" +checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860" dependencies = [ - "errno-dragonfly", "libc", "windows-sys", ] -[[package]] -name = "errno-dragonfly" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" -dependencies = [ - "cc", - "libc", -] - [[package]] name = "espresso-systems-common" version = "0.4.0" @@ -2136,6 +2142,17 @@ version = "2.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" +[[package]] +name = "event-listener" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29e56284f00d94c1bc7fd3c77027b4623c88c1f53d8d2394c6199f2921dea325" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite 0.2.13", +] + [[package]] name = "eyre" version = "0.6.8" @@ -2155,11 +2172,17 @@ dependencies = [ "instant", ] +[[package]] +name = "fastrand" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" + [[package]] name = "fiat-crypto" -version = "0.1.20" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e825f6987101665dea6ec934c09ec6d721de7bc1bf92248e1d5810c8cd636b77" +checksum = "d0870c84016d4b481be5c9f323c24f65e31e901ae618f0e80f4308fb00de1d2d" [[package]] name = "fixed-hash" @@ -2282,7 +2305,7 @@ version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" dependencies = [ - "fastrand", + "fastrand 1.9.0", "futures-core", "futures-io", "memchr", @@ -2299,7 +2322,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.31", + "syn 2.0.38", ] [[package]] @@ -2444,7 +2467,7 @@ version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833" dependencies = [ - "bytes 1.4.0", + "bytes 1.5.0", "fnv", "futures-core", "futures-sink", @@ -2477,9 +2500,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.14.0" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" +checksum = "7dfda62a12f55daeae5015f81b0baea145391cb4520f86c248fc615d72640d12" [[package]] name = "hdrhistogram" @@ -2502,9 +2525,9 @@ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "hermit-abi" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" +checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" [[package]] name = "hex" @@ -2898,7 +2921,7 @@ version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" dependencies = [ - "bytes 1.4.0", + "bytes 1.5.0", "fnv", "itoa 1.0.9", ] @@ -2909,7 +2932,7 @@ version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" dependencies = [ - "bytes 1.4.0", + "bytes 1.5.0", "http", "pin-project-lite 0.2.13", ] @@ -2974,7 +2997,7 @@ version = "0.14.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" dependencies = [ - "bytes 1.4.0", + "bytes 1.5.0", "futures-channel", "futures-core", "futures-util", @@ -3160,12 +3183,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.0.0" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" +checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897" dependencies = [ "equivalent", - "hashbrown 0.14.0", + "hashbrown 0.14.1", "serde", ] @@ -3190,7 +3213,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f97967975f448f1a7ddb12b0bc41069d09ed6a1c161a92687e057325db35d413" dependencies = [ - "bytes 1.4.0", + "bytes 1.5.0", ] [[package]] @@ -3219,7 +3242,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f" dependencies = [ - "socket2 0.5.3", + "socket2 0.5.4", "widestring", "windows-sys", "winreg", @@ -3416,9 +3439,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.147" +version = "0.2.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" +checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" [[package]] name = "libnghttp2-sys" @@ -3436,7 +3459,7 @@ version = "0.52.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32d07d1502a027366d55afe187621c2d7895dc111a3df13b35fed698049681d7" dependencies = [ - "bytes 1.4.0", + "bytes 1.5.0", "futures", "futures-timer", "getrandom 0.2.10", @@ -3517,9 +3540,9 @@ dependencies = [ [[package]] name = "libp2p-core" -version = "0.40.0" +version = "0.40.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef7dd7b09e71aac9271c60031d0e558966cdb3253ba0308ab369bb2de80630d0" +checksum = "dd44289ab25e4c9230d9246c475a22241e301b23e8f4061d3bdef304a1a99713" dependencies = [ "either", "fnv", @@ -3599,9 +3622,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d157562dba6017193e5285acf6b1054759e83540bfd79f75b69d6ce774c88da" dependencies = [ "asynchronous-codec", - "base64 0.21.3", + "base64 0.21.4", "byteorder", - "bytes 1.4.0", + "bytes 1.5.0", "either", "fnv", "futures", @@ -3671,13 +3694,13 @@ dependencies = [ [[package]] name = "libp2p-kad" -version = "0.44.4" +version = "0.44.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc125f83d8f75322c79e4ade74677d299b34aa5c9d9b5251c03ec28c683cb765" +checksum = "41c5c483b1e90e79409711f515c5bea5de9c4d772a245b1ac01a2233fbcb67fe" dependencies = [ "arrayvec", "asynchronous-codec", - "bytes 1.4.0", + "bytes 1.5.0", "either", "fnv", "futures", @@ -3688,6 +3711,7 @@ dependencies = [ "libp2p-swarm", "log", "quick-protobuf", + "quick-protobuf-codec", "rand 0.8.5", "serde", "sha2 0.10.8", @@ -3714,7 +3738,7 @@ dependencies = [ "log", "rand 0.8.5", "smallvec", - "socket2 0.5.3", + "socket2 0.5.4", "tokio", "trust-dns-proto", "void", @@ -3787,8 +3811,8 @@ version = "0.43.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71ce70757f2c0d82e9a3ef738fb10ea0723d16cec37f078f719e2c247704c1bb" dependencies = [ - "bytes 1.4.0", - "curve25519-dalek 4.0.0", + "bytes 1.5.0", + "curve25519-dalek 4.1.1", "futures", "libp2p-core", "libp2p-identity", @@ -3808,9 +3832,9 @@ dependencies = [ [[package]] name = "libp2p-ping" -version = "0.43.0" +version = "0.43.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cd5ee3270229443a2b34b27ed0cb7470ef6b4a6e45e54e89a8771fa683bab48" +checksum = "e702d75cd0827dfa15f8fd92d15b9932abe38d10d21f47c50438c71dd1b5dae3" dependencies = [ "either", "futures", @@ -3831,7 +3855,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37266c683a757df713f7dcda0cdcb5ad4681355ffa1b37b77c113c176a531195" dependencies = [ "asynchronous-codec", - "bytes 1.4.0", + "bytes 1.5.0", "futures", "libp2p-core", "libp2p-identity", @@ -3861,7 +3885,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4cb763e88f9a043546bfebd3575f340e7dd3d6c1b2cf2629600ec8965360c63a" dependencies = [ "async-std", - "bytes 1.4.0", + "bytes 1.5.0", "futures", "futures-timer", "if-watch", @@ -3873,7 +3897,7 @@ dependencies = [ "quinn", "rand 0.8.5", "rustls", - "socket2 0.5.3", + "socket2 0.5.4", "thiserror", "tokio", ] @@ -3885,7 +3909,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cdb07202cdf103486709fda5d9d10a0297a8ba01c212b1e19b7943c45c1bd7d6" dependencies = [ "asynchronous-codec", - "bytes 1.4.0", + "bytes 1.5.0", "either", "futures", "futures-timer", @@ -3946,9 +3970,9 @@ dependencies = [ [[package]] name = "libp2p-swarm" -version = "0.43.3" +version = "0.43.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28016944851bd73526d3c146aabf0fa9bbe27c558f080f9e5447da3a1772c01a" +checksum = "ab94183f8fc2325817835b57946deb44340c99362cd4606c0a5717299b2ba369" dependencies = [ "async-std", "either", @@ -3978,7 +4002,7 @@ dependencies = [ "proc-macro-warning", "proc-macro2", "quote", - "syn 2.0.31", + "syn 2.0.38", ] [[package]] @@ -3995,7 +4019,7 @@ dependencies = [ "libp2p-core", "libp2p-identity", "log", - "socket2 0.5.3", + "socket2 0.5.4", "tokio", ] @@ -4148,6 +4172,12 @@ version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" +[[package]] +name = "linux-raw-sys" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" + [[package]] name = "lock_api" version = "0.4.10" @@ -4219,9 +4249,9 @@ checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" [[package]] name = "matchit" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed1202b2a6f884ae56f04cff409ab315c5ce26b5e58d7412e484f01fd52f52ef" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" [[package]] name = "maud" @@ -4271,9 +4301,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.6.3" +version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" [[package]] name = "memoffset" @@ -4394,7 +4424,7 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea0df8e5eec2298a62b326ee4f0d7fe1a6b90a09dfcf9df37b38f947a8c42f19" dependencies = [ - "bytes 1.4.0", + "bytes 1.5.0", "futures", "log", "pin-project", @@ -4503,7 +4533,7 @@ name = "netlink-proto" version = "0.9.2" source = "git+https://github.com/espressosystems/netlink.git#1347bed011eeae7ece9851773906c4a3c80a5d77" dependencies = [ - "bytes 1.4.0", + "bytes 1.5.0", "futures", "log", "netlink-packet-core 0.4.2 (git+https://github.com/espressosystems/netlink.git)", @@ -4517,7 +4547,7 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "65b4b14489ab424703c092062176d52ba55485a89c076b4f9db05092b7223aa6" dependencies = [ - "bytes 1.4.0", + "bytes 1.5.0", "futures", "log", "netlink-packet-core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4532,7 +4562,7 @@ version = "0.8.2" source = "git+https://github.com/espressosystems/netlink.git#1347bed011eeae7ece9851773906c4a3c80a5d77" dependencies = [ "async-io", - "bytes 1.4.0", + "bytes 1.5.0", "futures", "libc", "log", @@ -4545,7 +4575,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6471bf08e7ac0135876a9581bf3217ef0333c191c128d34878079f42ee150411" dependencies = [ "async-io", - "bytes 1.4.0", + "bytes 1.5.0", "futures", "libc", "log", @@ -4636,9 +4666,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" dependencies = [ "autocfg", ] @@ -4691,9 +4721,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.92" +version = "0.9.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db7e971c2c2bba161b2d2fdf37080177eff520b3bc044787c7f1f5f9e78d869b" +checksum = "db4d56a4c0478783083cfafcc42493dd4a981d41669da64b4572a2a089b51b1d" dependencies = [ "cc", "libc", @@ -4757,9 +4787,9 @@ dependencies = [ [[package]] name = "parking" -version = "2.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14f2252c834a40ed9bb5422029649578e63aa341ac401f74e719dd1afda8394e" +checksum = "e52c774a4c39359c1d1c52e43f73dd91a75a614652c825408eec30c95a9b2067" [[package]] name = "parking_lot" @@ -4813,9 +4843,9 @@ checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] name = "pest" -version = "2.7.3" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7a4d085fd991ac8d5b05a147b437791b4260b76326baf0fc60cf7c9c27ecd33" +checksum = "c022f1e7b65d6a24c0dbbd5fb344c66881bc01f3e5ae74a1c8100f2f985d98a4" dependencies = [ "memchr", "thiserror", @@ -4824,9 +4854,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.7.3" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bee7be22ce7918f641a33f08e3f43388c7656772244e2bbb2477f44cc9021a" +checksum = "35513f630d46400a977c4cb58f78e1bfbe01434316e60c37d27b9ad6139c66d8" dependencies = [ "pest", "pest_generator", @@ -4834,22 +4864,22 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.3" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1511785c5e98d79a05e8a6bc34b4ac2168a0e3e92161862030ad84daa223141" +checksum = "bc9fc1b9e7057baba189b5c626e2d6f40681ae5b6eb064dc7c7834101ec8123a" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.31", + "syn 2.0.38", ] [[package]] name = "pest_meta" -version = "2.7.3" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42f0394d3123e33353ca5e1e89092e533d2cc490389f2bd6131c43c634ebc5f" +checksum = "1df74e9e7ec4053ceb980e7c0c8bd3594e977fde1af91daba9c928e8e8c6708d" dependencies = [ "once_cell", "pest", @@ -4873,7 +4903,7 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2", "quote", - "syn 2.0.31", + "syn 2.0.38", ] [[package]] @@ -4900,6 +4930,17 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d15b6607fa632996eb8a17c9041cb6071cb75ac057abd45dece578723ea8c7c0" +[[package]] +name = "piper" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "668d31b1c4eba19242f2088b2bf3316b82ca31082a8335764db4e083db7485d4" +dependencies = [ + "atomic-waker", + "fastrand 2.0.1", + "futures-io", +] + [[package]] name = "pkcs8" version = "0.10.2" @@ -5050,14 +5091,14 @@ checksum = "3d1eaa7fa0aa1929ffdf7eeb6eac234dde6268914a14ad44d23521ab6a9b258e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.31", + "syn 2.0.38", ] [[package]] name = "proc-macro2" -version = "1.0.66" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" dependencies = [ "unicode-ident", ] @@ -5082,7 +5123,7 @@ checksum = "440f724eba9f6996b75d63681b0a92b06947f1457076d503a4d2e2c8f56442b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.31", + "syn 2.0.38", ] [[package]] @@ -5091,7 +5132,7 @@ version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" dependencies = [ - "bytes 1.4.0", + "bytes 1.5.0", "prost-derive", ] @@ -5139,7 +5180,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8ededb1cd78531627244d51dd0c7139fbe736c7d57af0092a76f0ffb2f56e98" dependencies = [ "asynchronous-codec", - "bytes 1.4.0", + "bytes 1.5.0", "quick-protobuf", "thiserror", "unsigned-varint", @@ -5164,7 +5205,7 @@ checksum = "8cc2c5017e4b43d5995dcea317bc46c1e09404c0a9664d2908f7f02dfe943d75" dependencies = [ "async-io", "async-std", - "bytes 1.4.0", + "bytes 1.5.0", "futures-io", "pin-project-lite 0.2.13", "quinn-proto", @@ -5182,7 +5223,7 @@ version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c78e758510582acc40acb90458401172d41f1016f8c9dde89e49677afb7eec1" dependencies = [ - "bytes 1.4.0", + "bytes 1.5.0", "rand 0.8.5", "ring", "rustc-hash", @@ -5199,9 +5240,9 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "055b4e778e8feb9f93c4e439f71dc2156ef13360b432b799e179a8c4cdf0b1d7" dependencies = [ - "bytes 1.4.0", + "bytes 1.5.0", "libc", - "socket2 0.5.3", + "socket2 0.5.4", "tracing", "windows-sys", ] @@ -5294,9 +5335,9 @@ dependencies = [ [[package]] name = "rayon" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b" +checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" dependencies = [ "either", "rayon-core", @@ -5304,14 +5345,12 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" +checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" dependencies = [ - "crossbeam-channel", "crossbeam-deque", "crossbeam-utils", - "num_cpus", ] [[package]] @@ -5357,13 +5396,13 @@ dependencies = [ [[package]] name = "regex" -version = "1.9.5" +version = "1.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "697061221ea1b4a94a624f67d0ae2bfe4e22b8a17b6a192afb11046542cc8c47" +checksum = "ebee201405406dbf528b8b672104ae6d6d63e6d118cb10e4d51abbc7b58044ff" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.3.8", + "regex-automata 0.3.9", "regex-syntax 0.7.5", ] @@ -5378,9 +5417,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795" +checksum = "59b23e92ee4318893fa3fe3e6fb365258efbfe6ac6ab30f090cdcbb7aa37efa9" dependencies = [ "aho-corasick", "memchr", @@ -5430,7 +5469,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb919243f34364b6bd2fc10ef797edbfa75f33c252e7998527479c6d6b47e1ec" dependencies = [ - "bytes 1.4.0", + "bytes 1.5.0", "rustc-hex", ] @@ -5538,7 +5577,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 1.0.18", + "semver 1.0.19", ] [[package]] @@ -5552,15 +5591,28 @@ dependencies = [ [[package]] name = "rustix" -version = "0.37.23" +version = "0.37.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d69718bf81c6127a49dc64e44a742e8bb9213c0ff8869a22c308f84c1d4ab06" +checksum = "4279d76516df406a8bd37e7dff53fd37d1a093f997a3c34a5c21658c126db06d" dependencies = [ "bitflags 1.3.2", "errno", "io-lifetimes", "libc", - "linux-raw-sys", + "linux-raw-sys 0.3.8", + "windows-sys", +] + +[[package]] +name = "rustix" +version = "0.38.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a74ee2d7c2581cd139b42447d7d9389b889bdaad3a73f1ebb16f2a3237bb19c" +dependencies = [ + "bitflags 2.4.0", + "errno", + "libc", + "linux-raw-sys 0.4.10", "windows-sys", ] @@ -5578,9 +5630,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.101.4" +version = "0.101.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d93931baf2d282fff8d3a532bbfd7653f734643161b87e3e01e59a04439bf0d" +checksum = "3c7d5dece342910d9ba34d259310cae3e0154b873b35408b787b59bce53d34fe" dependencies = [ "ring", "untrusted", @@ -5654,9 +5706,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.18" +version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" +checksum = "ad977052201c6de01a8ef2aa3378c4bd23217a056337d1d6da40468d267a4fb0" [[package]] name = "semver-parser" @@ -5687,7 +5739,7 @@ checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.31", + "syn 2.0.38", ] [[package]] @@ -5764,11 +5816,11 @@ version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ca3b16a3d82c4088f343b7480a93550b3eabe1a358569c2dfe38bbcead07237" dependencies = [ - "base64 0.21.3", + "base64 0.21.4", "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.0.0", + "indexmap 2.0.2", "serde", "serde_json", "serde_with_macros 3.3.0", @@ -5784,7 +5836,7 @@ dependencies = [ "darling 0.20.3", "proc-macro2", "quote", - "syn 2.0.31", + "syn 2.0.38", ] [[package]] @@ -5796,7 +5848,7 @@ dependencies = [ "darling 0.20.3", "proc-macro2", "quote", - "syn 2.0.31", + "syn 2.0.38", ] [[package]] @@ -5873,9 +5925,9 @@ dependencies = [ [[package]] name = "sharded-slab" -version = "0.1.4" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" dependencies = [ "lazy_static", ] @@ -5941,7 +5993,7 @@ version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38aabbeafa6f6dead8cebf246fe9fae1f9215c8d29b3a69f93bd62a9e4a3dcd6" dependencies = [ - "event-listener", + "event-listener 2.5.3", ] [[package]] @@ -5966,9 +6018,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" +checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" [[package]] name = "smartcow" @@ -6039,7 +6091,7 @@ dependencies = [ "aes-gcm 0.9.2", "blake2", "chacha20poly1305 0.9.1", - "curve25519-dalek 4.0.0", + "curve25519-dalek 4.1.1", "rand_core 0.6.4", "ring", "rustc_version 0.4.0", @@ -6059,9 +6111,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2538b18701741680e0322a2302176d3253a35388e2e62f172f64f4f16605f877" +checksum = "4031e820eb552adee9295814c0ced9e5cf38ddf1e8b7d566d6de8e2538ea989e" dependencies = [ "libc", "windows-sys", @@ -6074,7 +6126,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41d1c5305e39e09653383c2c7244f2f78b3bcae37cf50c64cb4789c9f5096ec2" dependencies = [ "base64 0.13.1", - "bytes 1.4.0", + "bytes 1.5.0", "futures", "httparse", "log", @@ -6221,7 +6273,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.31", + "syn 2.0.38", ] [[package]] @@ -6272,15 +6324,15 @@ dependencies = [ [[package]] name = "sval" -version = "2.6.1" +version = "2.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b031320a434d3e9477ccf9b5756d57d4272937b8d22cb88af80b7633a1b78b1" +checksum = "e55089b73dfa822e1eb6b635f8795215512cca94bfae11aee3a1a06228bc88bb" [[package]] name = "sval_buffer" -version = "2.6.1" +version = "2.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bf7e9412af26b342f3f2cc5cc4122b0105e9d16eb76046cd14ed10106cf6028" +checksum = "df307823073d63f1fb126895439fead41afc493ea35d636cceedef9f6b32ba81" dependencies = [ "sval", "sval_ref", @@ -6288,18 +6340,18 @@ dependencies = [ [[package]] name = "sval_dynamic" -version = "2.6.1" +version = "2.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0ef628e8a77a46ed3338db8d1b08af77495123cc229453084e47cd716d403cf" +checksum = "e5f8e4c4d6d028d3cbff66c2bb3d98181d031d312b7df4550eea7142d7036f37" dependencies = [ "sval", ] [[package]] name = "sval_fmt" -version = "2.6.1" +version = "2.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dc09e9364c2045ab5fa38f7b04d077b3359d30c4c2b3ec4bae67a358bd64326" +checksum = "ad53f8eb502b0a3051fea001ae2e3723044699868ebfe06ea81b45545db392c2" dependencies = [ "itoa 1.0.9", "ryu", @@ -6308,9 +6360,9 @@ dependencies = [ [[package]] name = "sval_json" -version = "2.6.1" +version = "2.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ada6f627e38cbb8860283649509d87bc4a5771141daa41c78fd31f2b9485888d" +checksum = "f913253c9f6cd27645ba9a0b6788039b5d4338eae0833c64b42ef178168d2862" dependencies = [ "itoa 1.0.9", "ryu", @@ -6319,18 +6371,18 @@ dependencies = [ [[package]] name = "sval_ref" -version = "2.6.1" +version = "2.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "703ca1942a984bd0d9b5a4c0a65ab8b4b794038d080af4eb303c71bc6bf22d7c" +checksum = "66a9661412d06740ebe81512a527b3d9220460eb7685f4399232c0e670108cb7" dependencies = [ "sval", ] [[package]] name = "sval_serde" -version = "2.6.1" +version = "2.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830926cd0581f7c3e5d51efae4d35c6b6fc4db583842652891ba2f1bed8db046" +checksum = "b8d077e98c1c8dfa466837ae0ec1e03c78138d42ac75662dac05e1bf0aebae20" dependencies = [ "serde", "sval", @@ -6351,9 +6403,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.31" +version = "2.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "718fa2415bcb8d8bd775917a1bf12a7931b6dfa890753378538118181e0cb398" +checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" dependencies = [ "proc-macro2", "quote", @@ -6503,22 +6555,22 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "thiserror" -version = "1.0.48" +version = "1.0.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7" +checksum = "1177e8c6d7ede7afde3585fd2513e611227efd6481bd78d2e82ba1ce16557ed4" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.48" +version = "1.0.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35" +checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.31", + "syn 2.0.38", ] [[package]] @@ -6575,7 +6627,7 @@ dependencies = [ "maud 0.24.0", "parking_lot", "routefinder", - "semver 1.0.18", + "semver 1.0.19", "serde", "serde_json", "serde_with 2.3.3", @@ -6621,7 +6673,7 @@ dependencies = [ "maud 0.25.0", "parking_lot", "routefinder", - "semver 1.0.18", + "semver 1.0.19", "serde", "serde_json", "serde_with 3.3.0", @@ -6754,19 +6806,19 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.32.0" +version = "1.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9" +checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653" dependencies = [ "backtrace", - "bytes 1.4.0", + "bytes 1.5.0", "libc", "mio", "num_cpus", "parking_lot", "pin-project-lite 0.2.13", "signal-hook-registry", - "socket2 0.5.3", + "socket2 0.5.4", "tokio-macros", "tracing", "windows-sys", @@ -6790,7 +6842,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.31", + "syn 2.0.38", ] [[package]] @@ -6806,11 +6858,11 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.8" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" +checksum = "1d68074620f57a0b21594d9735eb2e98ab38b17f80d3fcb189fca266771ca60d" dependencies = [ - "bytes 1.4.0", + "bytes 1.5.0", "futures-core", "futures-sink", "pin-project-lite 0.2.13", @@ -6854,7 +6906,7 @@ version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.0.0", + "indexmap 2.0.2", "serde", "serde_spanned", "toml_datetime", @@ -6869,8 +6921,8 @@ checksum = "3082666a3a6433f7f511c7192923fa1fe07c69332d3c6a2e6bb040b569199d5a" dependencies = [ "async-trait", "axum", - "base64 0.21.3", - "bytes 1.4.0", + "base64 0.21.4", + "bytes 1.5.0", "futures-core", "futures-util", "h2", @@ -6942,7 +6994,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ "proc-macro2", "quote", - "syn 2.0.31", + "syn 2.0.38", ] [[package]] @@ -7089,7 +7141,7 @@ checksum = "5fe8dada8c1a3aeca77d6b51a4f1314e0f4b8e438b7b1b71e3ddaca8080e4093" dependencies = [ "base64 0.13.1", "byteorder", - "bytes 1.4.0", + "bytes 1.5.0", "http", "httparse", "input_buffer", @@ -7109,7 +7161,7 @@ checksum = "983d40747bce878d2fb67d910dcb8bd3eca2b2358540c3cc1b98c027407a3ae3" dependencies = [ "base64 0.13.1", "byteorder", - "bytes 1.4.0", + "bytes 1.5.0", "http", "httparse", "log", @@ -7161,9 +7213,9 @@ checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" [[package]] name = "unicode-ident" -version = "1.0.11" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-normalization" @@ -7202,12 +7254,12 @@ dependencies = [ [[package]] name = "unsigned-varint" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d86a8dc7f45e4c1b0d30e43038c38f274e77af056aa5f74b93c2cf9eb3c1c836" +checksum = "6889a77d49f1f013504cec6bf97a2c730394adedaeb1deb5ea08949a50541105" dependencies = [ "asynchronous-codec", - "bytes 1.4.0", + "bytes 1.5.0", ] [[package]] @@ -7302,9 +7354,9 @@ checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" [[package]] name = "waker-fn" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" +checksum = "f3c4517f54858c779bbcbf228f4fca63d121bf85fbecb2dc578cdf4a39395690" [[package]] name = "want" @@ -7350,7 +7402,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.31", + "syn 2.0.38", "wasm-bindgen-shared", ] @@ -7384,7 +7436,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.31", + "syn 2.0.38", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -7559,9 +7611,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "winnow" -version = "0.5.15" +version = "0.5.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c2e3184b9c4e92ad5167ca73039d0c42476302ab603e2fec4487511f38ccefc" +checksum = "037711d82167854aff2018dfd193aa0fef5370f456732f0d5a0c59b0f1b4b907" dependencies = [ "memchr", ] @@ -7663,5 +7715,5 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.31", + "syn 2.0.38", ] diff --git a/crates/hotshot/src/tasks/mod.rs b/crates/hotshot/src/tasks/mod.rs index 66f9fb20da..bc95f8dbb6 100644 --- a/crates/hotshot/src/tasks/mod.rs +++ b/crates/hotshot/src/tasks/mod.rs @@ -100,7 +100,7 @@ where .expect("Failed to receive broadcast messages"), ); if msgs.0.is_empty() { - async_sleep(Duration::new(0, 500)).await; + async_sleep(Duration::from_millis(100)).await; } else { break msgs; } @@ -120,7 +120,7 @@ where .expect("Failed to receive direct messages"), ); if msgs.0.is_empty() { - async_sleep(Duration::new(0, 500)).await; + async_sleep(Duration::from_millis(100)).await; } else { break msgs; } @@ -288,7 +288,7 @@ where consensus, timeout: handle.hotshot.inner.config.next_view_timeout, cur_view: TYPES::Time::new(0), - block: VIDBlockPayload::genesis(), + block: Some(VIDBlockPayload::genesis()), quorum_exchange: c_api.inner.exchanges.quorum_exchange().clone().into(), api: c_api.clone(), committee_exchange: c_api.inner.exchanges.committee_exchange().clone().into(), diff --git a/crates/hotshot/src/traits/networking/memory_network.rs b/crates/hotshot/src/traits/networking/memory_network.rs index 976186c030..9d9e751ee5 100644 --- a/crates/hotshot/src/traits/networking/memory_network.rs +++ b/crates/hotshot/src/traits/networking/memory_network.rs @@ -6,7 +6,7 @@ use super::{FailedToSerializeSnafu, NetworkError, NetworkReliability, NetworkingMetrics}; use crate::NodeImplementation; use async_compatibility_layer::{ - art::{async_sleep, async_spawn}, + art::async_spawn, channel::{bounded, Receiver, SendError, Sender}, }; use async_lock::{Mutex, RwLock}; @@ -42,18 +42,6 @@ use std::{ }; use tracing::{debug, error, info, info_span, instrument, trace, warn, Instrument}; -#[derive(Debug, Clone, Copy)] -/// dummy implementation of network reliability -pub struct DummyReliability {} -impl NetworkReliability for DummyReliability { - fn sample_keep(&self) -> bool { - true - } - fn sample_delay(&self) -> std::time::Duration { - std::time::Duration::ZERO - } -} - /// Shared state for in-memory mock networking. /// /// This type is responsible for keeping track of the channels to each [`MemoryNetwork`], and is @@ -104,6 +92,9 @@ struct MemoryNetworkInner { /// The networking metrics we're keeping track of metrics: NetworkingMetrics, + + /// config to introduce unreliability to the network + reliability_config: Option>>, } /// In memory only network simulator. @@ -134,7 +125,7 @@ impl MemoryNetwork { pub_key: K, metrics: Box, master_map: Arc>, - reliability_config: Option>, + reliability_config: Option>>, ) -> MemoryNetwork { info!("Attaching new MemoryNetwork"); let (broadcast_input, broadcast_task_recv) = bounded(128); @@ -165,30 +156,11 @@ impl MemoryNetwork { match x { Ok(x) => { let dts = direct_task_send.clone(); - if let Some(r) = reliability_config.clone() { - async_spawn(async move { - if r.sample_keep() { - let delay = r.sample_delay(); - if delay > std::time::Duration::ZERO { - async_sleep(delay).await; - } - let res = dts.send(x).await; - if res.is_ok() { - trace!("Passed message to output queue"); - } else { - error!("Output queue receivers are shutdown"); - } - } else { - warn!("dropping packet!"); - } - }); + let res = dts.send(x).await; + if res.is_ok() { + trace!("Passed message to output queue"); } else { - let res = dts.send(x).await; - if res.is_ok() { - trace!("Passed message to output queue"); - } else { - error!("Output queue receivers are shutdown"); - } + error!("Output queue receivers are shutdown"); } } Err(e) => { @@ -203,28 +175,11 @@ impl MemoryNetwork { match x { Ok(x) => { let bts = broadcast_task_send.clone(); - if let Some(r) = reliability_config.clone() { - async_spawn(async move { - if r.sample_keep() { - let delay = r.sample_delay(); - if delay > std::time::Duration::ZERO { - async_sleep(delay).await; - } - let res = bts.send(x).await; - if res.is_ok() { - trace!("Passed message to output queue"); - } else { - warn!("dropping packet!"); - } - } - }); + let res = bts.send(x).await; + if res.is_ok() { + trace!("Passed message to output queue"); } else { - let res = bts.send(x).await; - if res.is_ok() { - trace!("Passed message to output queue"); - } else { - warn!("dropping packet!"); - } + warn!("dropping packet!"); } } Err(e) => { @@ -249,6 +204,7 @@ impl MemoryNetwork { master_map: master_map.clone(), in_flight_message_count, metrics: NetworkingMetrics::new(&*metrics), + reliability_config, }), }; master_map.map.insert(pub_key, mn.clone()); @@ -347,20 +303,40 @@ impl ConnectedNetwork for Memory .context(FailedToSerializeSnafu)?; trace!("Message bincoded, sending"); for node in &self.inner.master_map.map { + // TODO delay/drop etc here let (key, node) = node.pair(); if !recipients.contains(key) { continue; } trace!(?key, "Sending message to node"); - let res = node.broadcast_input(vec.clone()).await; - match res { - Ok(_) => { - self.inner.metrics.outgoing_message_count.add(1); - trace!(?key, "Delivered message to remote"); + if let Some(r) = &self.inner.reliability_config { + let config = r.read().await; + { + let node2 = node.clone(); + let fut = config.chaos_send_msg( + vec.clone(), + Arc::new(move |msg: Vec| { + let node3 = (node2).clone(); + boxed_sync(async move { + let _res = node3.broadcast_input(msg).await; + // NOTE we're dropping metrics here but this is only for testing + // purposes. I think that should be okay + }) + }), + ); + async_spawn(fut); } - Err(e) => { - self.inner.metrics.message_failed_to_send.add(1); - warn!(?e, ?key, "Error sending broadcast message to node"); + } else { + let res = node.broadcast_input(vec.clone()).await; + match res { + Ok(_) => { + self.inner.metrics.outgoing_message_count.add(1); + trace!(?key, "Delivered message to remote"); + } + Err(e) => { + self.inner.metrics.message_failed_to_send.add(1); + warn!(?e, ?key, "Error sending broadcast message to node"); + } } } } @@ -376,18 +352,37 @@ impl ConnectedNetwork for Memory .context(FailedToSerializeSnafu)?; trace!("Message bincoded, finding recipient"); if let Some(node) = self.inner.master_map.map.get(&recipient) { - let node = node.value(); - let res = node.direct_input(vec).await; - match res { - Ok(_) => { - self.inner.metrics.outgoing_message_count.add(1); - trace!(?recipient, "Delivered message to remote"); - Ok(()) + let node = node.value().clone(); + if let Some(r) = &self.inner.reliability_config { + let config = r.read().await; + { + let fut = config.chaos_send_msg( + vec.clone(), + Arc::new(move |msg: Vec| { + let node2 = node.clone(); + boxed_sync(async move { + let _res = node2.broadcast_input(msg).await; + // NOTE we're dropping metrics here but this is only for testing + // purposes. I think that should be okay + }) + }), + ); + async_spawn(fut); } - Err(e) => { - self.inner.metrics.message_failed_to_send.add(1); - warn!(?e, ?recipient, "Error delivering direct message"); - Err(NetworkError::CouldNotDeliver) + Ok(()) + } else { + let res = node.direct_input(vec).await; + match res { + Ok(_) => { + self.inner.metrics.outgoing_message_count.add(1); + trace!(?recipient, "Delivered message to remote"); + Ok(()) + } + Err(e) => { + self.inner.metrics.message_failed_to_send.add(1); + warn!(?e, ?recipient, "Error delivering direct message"); + Err(NetworkError::CouldNotDeliver) + } } } } else { diff --git a/crates/task-impls/src/consensus.rs b/crates/task-impls/src/consensus.rs index 236b5ae6b8..11a98de85c 100644 --- a/crates/task-impls/src/consensus.rs +++ b/crates/task-impls/src/consensus.rs @@ -43,7 +43,7 @@ use std::{ }; #[cfg(async_executor_impl = "tokio")] use tokio::task::JoinHandle; -use tracing::{debug, error, instrument}; +use tracing::{debug, error, info, instrument}; /// Error returned by the consensus task #[derive(Snafu, Debug)] @@ -84,7 +84,7 @@ pub struct SequencingConsensusTaskState< pub cur_view: TYPES::Time, /// Current block submitted to DA - pub block: TYPES::BlockType, + pub block: Option, /// the quorum exchange pub quorum_exchange: Arc>, @@ -339,8 +339,9 @@ where // Justify qc's leaf commitment is not the same as the parent's leaf commitment, but it should be (in this case) let Some(parent) = parent else { error!( - "Proposal's parent missing from storage with commitment: {:?}", - justify_qc.leaf_commitment() + "Proposal's parent missing from storage with commitment: {:?}, proposal view {:?}", + justify_qc.leaf_commitment(), + proposal.view_number, ); return false; }; @@ -405,8 +406,9 @@ where // Justify qc's leaf commitment is not the same as the parent's leaf commitment, but it should be (in this case) let Some(parent) = parent else { error!( - "Proposal's parent missing from storage with commitment: {:?}", - justify_qc.leaf_commitment() + "Proposal's parent missing from storage with commitment: {:?}, proposal view {:?}", + justify_qc.leaf_commitment(), + proposal.view_number, ); return false; }; @@ -426,8 +428,13 @@ where // Validate the DAC. if self .committee_exchange - .is_valid_cert(cert, proposal.block_commitment) + .is_valid_cert(cert) { + // Validate the block commitment for non-genesis DAC. + if !cert.is_genesis() && cert.leaf_commitment() != proposal.block_commitment { + error!("Block commitment does not equal parent commitment"); + return false; + } self.quorum_exchange.create_yes_message( proposal.justify_qc.commit(), leaf.commit(), @@ -449,13 +456,13 @@ where } } } - debug!( + info!( "Couldn't find DAC cert in certs, meaning we haven't received it yet for view {:?}", *proposal.get_view_number(), ); return false; } - debug!( + info!( "Could not vote because we don't have a proposal yet for view {}", *self.cur_view ); @@ -579,7 +586,6 @@ where Ok(Some(vote_token)) => { debug!("We were chosen for consensus committee on {:?}", view); let consensus = self.consensus.upgradable_read().await; - let message; // TODO ED Insert TC logic here @@ -594,111 +600,171 @@ where .cloned() }; - // Justify qc's leaf commitment is not the same as the parent's leaf commitment, but it should be (in this case) - let Some(parent) = parent else { - error!( - "Proposal's parent missing from storage with commitment: {:?}", - justify_qc.leaf_commitment() - ); - return; - }; - let parent_commitment = parent.commit(); - let leaf: SequencingLeaf<_> = SequencingLeaf { - view_number: view, - height: proposal.data.height, - justify_qc: justify_qc.clone(), - parent_commitment, - deltas: Right(proposal.data.block_commitment), - rejected: Vec::new(), - timestamp: time::OffsetDateTime::now_utc().unix_timestamp_nanos(), - proposer_id: sender.to_bytes(), - }; + // Validate the `justify_qc`. let justify_qc_commitment = justify_qc.commit(); - let leaf_commitment = leaf.commit(); + let invalid = !self.quorum_exchange.is_valid_cert(&justify_qc); + let leaf; - // Validate the `justify_qc`. - if !self - .quorum_exchange - .is_valid_cert(&justify_qc, parent_commitment) - { - error!("Invalid justify_qc in proposal!. parent commitment is {:?} justify qc is {:?}", parent_commitment, justify_qc.clone()); + // Justify qc's leaf commitment is not the same as the parent's leaf commitment, but it should be (in this case) + if let Some(parent) = parent.clone() { + let message; + leaf = SequencingLeaf { + view_number: view, + height: proposal.data.height, + justify_qc: justify_qc.clone(), + parent_commitment: parent.commit(), + deltas: Right(proposal.data.block_commitment), + rejected: Vec::new(), + timestamp: time::OffsetDateTime::now_utc().unix_timestamp_nanos(), + proposer_id: sender.to_bytes(), + }; + let parent_commitment = parent.commit(); + let leaf_commitment = leaf.commit(); - message = self.quorum_exchange.create_no_message::( - justify_qc_commitment, - leaf_commitment, - view, - vote_token, - ); - } - // Validate the `height`. - else if leaf.height != parent.height + 1 { - error!( - "Incorrect height in proposal (expected {}, got {})", - parent.height + 1, - leaf.height - ); - message = self.quorum_exchange.create_no_message( - justify_qc_commitment, - leaf_commitment, - view, - vote_token, - ); - } - // Validate the signature. - else if !view_leader_key - .validate(&proposal.signature, leaf_commitment.as_ref()) - { - error!(?proposal.signature, "Could not verify proposal."); - message = self.quorum_exchange.create_no_message( - justify_qc_commitment, - leaf_commitment, - view, - vote_token, - ); - } - // Create a positive vote if either liveness or safety check - // passes. - else { - // Liveness check. - let liveness_check = justify_qc.view_number > consensus.locked_view; - - // Safety check. - // Check if proposal extends from the locked leaf. - let outcome = consensus.visit_leaf_ancestors( - justify_qc.view_number, - Terminator::Inclusive(consensus.locked_view), - false, - |leaf| { - // if leaf view no == locked view no then we're done, report success by - // returning true - leaf.view_number != consensus.locked_view - }, - ); - let safety_check = outcome.is_ok(); - if let Err(e) = outcome { - self.api.send_view_error(view, Arc::new(e)).await; - } + if invalid { + error!("Invalid justify_qc in proposal! parent commitment is {:?} justify qc is {:?}", parent_commitment, justify_qc.clone()); - // Skip if both saftey and liveness checks fail. - if !safety_check && !liveness_check { - error!("Failed safety check and liveness check"); + message = self.quorum_exchange.create_no_message::( + justify_qc_commitment, + leaf_commitment, + view, + vote_token, + ); + } + // Validate the leaf commitment for non-genesis QC. + else if !justify_qc.is_genesis() + && justify_qc.leaf_commitment() != parent_commitment + { + error!("Leaf commitment does not equal parent commitment"); + message = self.quorum_exchange.create_no_message::( + justify_qc_commitment, + leaf_commitment, + view, + vote_token, + ); + } + // Validate the `height`. + else if leaf.height != parent.height + 1 { + error!( + "Incorrect height in proposal (expected {}, got {})", + parent.height + 1, + leaf.height + ); message = self.quorum_exchange.create_no_message( justify_qc_commitment, leaf_commitment, view, vote_token, ); - } else { - // Generate a message with yes vote. - message = self.quorum_exchange.create_yes_message( + } + // Validate the signature. + else if !view_leader_key + .validate(&proposal.signature, leaf_commitment.as_ref()) + { + error!(?proposal.signature, "Could not verify proposal."); + message = self.quorum_exchange.create_no_message( justify_qc_commitment, leaf_commitment, view, vote_token, ); } + // Create a positive vote if either liveness or safety check + // passes. + // Liveness check. + else { + let liveness_check = justify_qc.view_number > consensus.locked_view; + + // Safety check. + // Check if proposal extends from the locked leaf. + let outcome = consensus.visit_leaf_ancestors( + justify_qc.view_number, + Terminator::Inclusive(consensus.locked_view), + false, + |leaf| { + // if leaf view no == locked view no then we're done, report success by + // returning true + leaf.view_number != consensus.locked_view + }, + ); + let safety_check = outcome.is_ok(); + if let Err(e) = outcome { + self.api.send_view_error(view, Arc::new(e)).await; + } + + // Skip if both saftey and liveness checks fail. + if !safety_check && !liveness_check { + error!("Failed safety check and liveness check"); + message = self.quorum_exchange.create_no_message( + justify_qc_commitment, + leaf_commitment, + view, + vote_token, + ); + } + // Generate a message with yes vote. + else { + message = self.quorum_exchange.create_yes_message( + justify_qc_commitment, + leaf_commitment, + view, + vote_token, + ); + } + } + + if let GeneralConsensusMessage::Vote(vote) = message { + debug!("Sending vote to next leader {:?}", vote); + }; + } else { + // Allow missing parent so we can update the state, but we won't + // vote in this case. + error!( + "Proposal's parent missing from storage with commitment: {:?}, proposal view {:?}", + justify_qc.leaf_commitment(), + proposal.data.view_number, + ); + + if invalid { + error!("Invalid justify_qc in proposal {:?}", justify_qc.clone()); + return; + } + leaf = SequencingLeaf { + view_number: view, + height: proposal.data.height, + justify_qc: justify_qc.clone(), + parent_commitment: justify_qc.leaf_commitment(), + deltas: Right(proposal.data.block_commitment), + rejected: Vec::new(), + timestamp: time::OffsetDateTime::now_utc().unix_timestamp_nanos(), + proposer_id: sender.to_bytes(), + }; + if !view_leader_key + .validate(&proposal.signature, leaf.commit().as_ref()) + { + error!(?proposal.signature, "Could not verify proposal."); + return; + } + + let mut consensus = RwLockUpgradableReadGuard::upgrade(consensus).await; + consensus.state_map.insert( + view, + View { + view_inner: ViewInner::Leaf { + leaf: leaf.commit(), + }, + }, + ); + consensus.saved_leaves.insert(leaf.commit(), leaf.clone()); + drop(consensus); + // The valid QC and signature on the proposal is evidence we can go to the next view + // even though we can't vote in this round because we missed the last proposal. + self.update_view(TYPES::Time::new(*view + 1)).await; + return; } + // TODO (Keyao) Update consensus state only if all verifications pass. + // let high_qc = leaf.justify_qc.clone(); let mut new_anchor_view = consensus.last_decided_view; let mut new_locked_view = consensus.locked_view; @@ -708,70 +774,72 @@ where let mut new_decide_qc = None; let mut leaf_views = Vec::new(); let mut included_txns = HashSet::new(); - let old_anchor_view = consensus.last_decided_view; - let parent_view = leaf.justify_qc.view_number; - let mut current_chain_length = 0usize; - if parent_view + 1 == view { - current_chain_length += 1; - if let Err(e) = consensus.visit_leaf_ancestors( - parent_view, - Terminator::Exclusive(old_anchor_view), - true, - |leaf| { - if !new_decide_reached { - if last_view_number_visited == leaf.view_number + 1 { - last_view_number_visited = leaf.view_number; - current_chain_length += 1; - if current_chain_length == 2 { - new_locked_view = leaf.view_number; - new_commit_reached = true; - // The next leaf in the chain, if there is one, is decided, so this - // leaf's justify_qc would become the QC for the decided chain. - new_decide_qc = Some(leaf.justify_qc.clone()); - } else if current_chain_length == 3 { - new_anchor_view = leaf.view_number; - new_decide_reached = true; - } - } else { - // nothing more to do here... we don't have a new chain extension - return false; - } - } - // starting from the first iteration with a three chain, e.g. right after the else if case nested in the if case above - if new_decide_reached { - let mut leaf = leaf.clone(); - - // If the full block is available for this leaf, include it in the leaf - // chain that we send to the client. - if let Some(block) = - consensus.saved_blocks.get(leaf.get_deltas_commitment()) - { - if let Err(err) = leaf.fill_deltas(block.clone()) { - error!("unable to fill leaf {} with block {}, block will not be available: {}", - leaf.commit(), block.commit(), err); + if parent.is_some() { + let old_anchor_view = consensus.last_decided_view; + let parent_view = leaf.justify_qc.view_number; + let mut current_chain_length = 0usize; + if parent_view + 1 == view { + current_chain_length += 1; + if let Err(e) = consensus.visit_leaf_ancestors( + parent_view, + Terminator::Exclusive(old_anchor_view), + true, + |leaf| { + if !new_decide_reached { + if last_view_number_visited == leaf.view_number + 1 { + last_view_number_visited = leaf.view_number; + current_chain_length += 1; + if current_chain_length == 2 { + new_locked_view = leaf.view_number; + new_commit_reached = true; + // The next leaf in the chain, if there is one, is decided, so this + // leaf's justify_qc would become the QC for the decided chain. + new_decide_qc = Some(leaf.justify_qc.clone()); + } else if current_chain_length == 3 { + new_anchor_view = leaf.view_number; + new_decide_reached = true; + } + } else { + // nothing more to do here... we don't have a new chain extension + return false; + } } - } - - leaf_views.push(leaf.clone()); - match &leaf.deltas { - Left(block) => { - let txns = block.contained_transactions(); - for txn in txns { - included_txns.insert(txn); + // starting from the first iteration with a three chain, e.g. right after the else if case nested in the if case above + if new_decide_reached { + let mut leaf = leaf.clone(); + + // If the full block is available for this leaf, include it in the leaf + // chain that we send to the client. + if let Some(block) = + consensus.saved_blocks.get(leaf.get_deltas_commitment()) + { + if let Err(err) = leaf.fill_deltas(block.clone()) { + error!("unable to fill leaf {} with block {}, block will not be available: {}", + leaf.commit(), block.commit(), err); + } + } + + leaf_views.push(leaf.clone()); + match &leaf.deltas { + Left(block) => { + let txns = block.contained_transactions(); + for txn in txns { + included_txns.insert(txn); + } + } + Right(_) => {} } } - Right(_) => {} + true + }, + ) { + error!("publishing view error"); + self.output_event_stream.publish(Event { + view_number: view, + event: EventType::Error { error: e.into() }, + }).await; } } - true - }, - ) { - error!("publishing view error"); - self.output_event_stream.publish(Event { - view_number: view, - event: EventType::Error { error: e.into() }, - }).await; - } } let included_txns_set: HashSet<_> = if new_decide_reached { @@ -840,7 +908,7 @@ where drop(consensus); if should_propose { debug!( - "Attempting to publish proposal after voting; now in view: {}", + "Attempting to publish proposal before voting; now in view: {}", *new_view ); self.publish_proposal_if_able(qc.clone(), qc.view_number + 1) @@ -859,10 +927,6 @@ where // Update current view and publish a view change event so other tasks also update self.update_view(new_view).await; - - if let GeneralConsensusMessage::Vote(vote) = message { - debug!("Sending vote to next leader {:?}", vote); - }; } } } @@ -1078,7 +1142,8 @@ where } SequencingHotShotEvent::SendDABlockData(block) => { // ED TODO Should make sure this is actually the most recent block - self.block = block; + // ED Should make this a map to view + self.block = Some(block); } _ => {} } @@ -1086,7 +1151,7 @@ where /// Sends a proposal if possible from the high qc we have pub async fn publish_proposal_if_able( - &self, + &mut self, _qc: QuorumCertificate>, view: TYPES::Time, ) -> bool { @@ -1150,49 +1215,54 @@ where // TODO do some sort of sanity check on the view number that it matches decided } - let block_commitment = self.block.commit(); - - let leaf = SequencingLeaf { - view_number: view, - height: parent_leaf.height + 1, - justify_qc: consensus.high_qc.clone(), - parent_commitment: parent_leaf.commit(), - // Use the block commitment rather than the block, so that the replica can construct - // the same leaf with the commitment. - deltas: Right(block_commitment), - rejected: vec![], - timestamp: time::OffsetDateTime::now_utc().unix_timestamp_nanos(), - proposer_id: self.api.public_key().to_bytes(), - }; - - let signature = self - .quorum_exchange - .sign_validating_or_commitment_proposal::(&leaf.commit()); - // TODO: DA cert is sent as part of the proposal here, we should split this out so we don't have to wait for it. - let proposal = QuorumProposal { - block_commitment, - view_number: leaf.view_number, - height: leaf.height, - justify_qc: consensus.high_qc.clone(), - // TODO ED Update this to be the actual TC if there is one - timeout_certificate: None, - proposer_id: leaf.proposer_id, - dac: None, - }; + // let block_commitment = Some(self.block.commit()); + if let Some(block) = &self.block { + let block_commitment = block.commit(); + + let leaf = SequencingLeaf { + view_number: view, + height: parent_leaf.height + 1, + justify_qc: consensus.high_qc.clone(), + parent_commitment: parent_leaf.commit(), + // Use the block commitment rather than the block, so that the replica can construct + // the same leaf with the commitment. + deltas: Right(block_commitment), + rejected: vec![], + timestamp: time::OffsetDateTime::now_utc().unix_timestamp_nanos(), + proposer_id: self.api.public_key().to_bytes(), + }; + + let signature = self + .quorum_exchange + .sign_validating_or_commitment_proposal::(&leaf.commit()); + // TODO: DA cert is sent as part of the proposal here, we should split this out so we don't have to wait for it. + let proposal = QuorumProposal { + block_commitment, + view_number: leaf.view_number, + height: leaf.height, + justify_qc: consensus.high_qc.clone(), + // TODO ED Update this to be the actual TC if there is one + timeout_certificate: None, + proposer_id: leaf.proposer_id, + dac: None, + }; + + let message = Proposal { + data: proposal, + signature, + }; + debug!("Sending proposal for view {:?} \n {:?}", self.cur_view, ""); - let message = Proposal { - data: proposal, - signature, - }; - debug!("Sending proposal for view {:?} \n {:?}", self.cur_view, ""); - - self.event_stream - .publish(SequencingHotShotEvent::QuorumProposalSend( - message, - self.quorum_exchange.public_key().clone(), - )) - .await; - true + self.event_stream + .publish(SequencingHotShotEvent::QuorumProposalSend( + message, + self.quorum_exchange.public_key().clone(), + )) + .await; + self.block = None; + return true; + } + false } } diff --git a/crates/task-impls/src/network.rs b/crates/task-impls/src/network.rs index 5fbada8539..605239c748 100644 --- a/crates/task-impls/src/network.rs +++ b/crates/task-impls/src/network.rs @@ -22,6 +22,7 @@ use hotshot_types::{ use snafu::Snafu; use std::{marker::PhantomData, sync::Arc}; use tracing::error; +use tracing::instrument; /// the type of network task #[derive(Clone, Copy, Debug)] @@ -190,6 +191,8 @@ impl< /// # Panics /// Panic sif a direct message event is received with no recipient #[allow(clippy::too_many_lines)] // TODO https://github.com/EspressoSystems/HotShot/issues/1704 + #[instrument(skip_all, fields(view = *self.view), name = "Newtork Task", level = "error")] + pub async fn handle_event( &mut self, event: SequencingHotShotEvent, diff --git a/crates/task-impls/src/view_sync.rs b/crates/task-impls/src/view_sync.rs index 30f3df83b6..4b241c37cd 100644 --- a/crates/task-impls/src/view_sync.rs +++ b/crates/task-impls/src/view_sync.rs @@ -289,7 +289,7 @@ where (certificate_internal, ViewSyncPhase::Finalize) } }; - debug!( + error!( "Received view sync cert for phase {:?}", last_seen_certificate ); @@ -311,19 +311,20 @@ where } // We do not have a replica task already running, so start one - let mut replica_state = ViewSyncReplicaTaskState { - current_view: certificate_internal.round, - next_view: certificate_internal.round, - relay: 0, - finalized: false, - sent_view_change_event: false, - phase: ViewSyncPhase::None, - exchange: self.exchange.clone(), - api: self.api.clone(), - event_stream: self.event_stream.clone(), - view_sync_timeout: self.view_sync_timeout, - id: self.id, - }; + let mut replica_state: ViewSyncReplicaTaskState = + ViewSyncReplicaTaskState { + current_view: certificate_internal.round, + next_view: certificate_internal.round, + relay: 0, + finalized: false, + sent_view_change_event: false, + phase: ViewSyncPhase::None, + exchange: self.exchange.clone(), + api: self.api.clone(), + event_stream: self.event_stream.clone(), + view_sync_timeout: self.view_sync_timeout, + id: self.id, + }; let result = replica_state.handle_event(event.clone()).await; @@ -494,7 +495,10 @@ where } self.num_timeouts_tracked += 1; - error!("Num timeouts tracked is {}", self.num_timeouts_tracked); + error!( + "Num timeouts tracked is {}. View {} timed out", + self.num_timeouts_tracked, *view_number + ); if self.num_timeouts_tracked > 2 { error!("Too many timeouts! This shouldn't happen"); @@ -502,6 +506,10 @@ where // TODO ED Make this a configurable variable if self.num_timeouts_tracked == 2 { + error!( + "Starting view sync protocol; attempting to sync on view {}", + *view_number + 1 + ); // Start polling for view sync certificates self.exchange .network() @@ -518,10 +526,29 @@ where .await; // panic!("Starting view sync!"); // Spawn replica task + let next_view = *view_number + 1; + // Subscribe to the view after we are leader since we know we won't propose in the next view if we are leader. + let subscribe_view = if self.exchange.is_leader(TYPES::Time::new(next_view)) { + next_view + 1 + } else { + next_view + }; + // Subscribe to the next view just in case there is progress being made + self.exchange + .network() + .inject_consensus_info(ConsensusIntentEvent::PollForProposal( + subscribe_view, + )) + .await; + + self.exchange + .network() + .inject_consensus_info(ConsensusIntentEvent::PollForDAC(subscribe_view)) + .await; let mut replica_state = ViewSyncReplicaTaskState { current_view: self.current_view, - next_view: TYPES::Time::new(*view_number + 1), + next_view: TYPES::Time::new(next_view), relay: 0, finalized: false, sent_view_change_event: false, @@ -547,7 +574,8 @@ where let name = format!( "View Sync Replica Task: Attempting to enter view {:?} from view {:?}", - self.next_view, self.current_view + *view_number + 1, + *view_number ); let replica_handle_event = HandleEvent(Arc::new( @@ -648,7 +676,7 @@ where // Ignore certificate if it is for an older round if certificate_internal.round < self.next_view { - debug!("We're already in a higher round"); + error!("We're already in a higher round"); return (None, self); } @@ -665,9 +693,9 @@ where // If certificate is not valid, return current state if !self .exchange - .is_valid_view_sync_cert(message.data, certificate_internal.round) + .is_valid_view_sync_cert(message.data.clone(), certificate_internal.round) { - error!("Not valid view sync cert!"); + error!("Not valid view sync cert! {:?}", message.data); return (None, self); } @@ -785,6 +813,7 @@ where let phase = self.phase.clone(); async move { async_sleep(self.view_sync_timeout).await; + error!("Vote sending timed out in ViewSyncCertificateRecv"); stream .publish(SequencingHotShotEvent::ViewSyncTimeout( TYPES::Time::new(*self.next_view), @@ -846,6 +875,7 @@ where let stream = self.event_stream.clone(); async move { async_sleep(self.view_sync_timeout).await; + error!("Vote sending timed out in ViewSyncTrigger"); stream .publish(SequencingHotShotEvent::ViewSyncTimeout( TYPES::Time::new(*self.next_view), @@ -916,6 +946,7 @@ where let stream = self.event_stream.clone(); async move { async_sleep(self.view_sync_timeout).await; + error!("Vote sending timed out in ViewSyncTimeout"); stream .publish(SequencingHotShotEvent::ViewSyncTimeout( TYPES::Time::new(*self.next_view), diff --git a/crates/testing/src/network_reliability.rs b/crates/testing/src/network_reliability.rs deleted file mode 100644 index 97b22b533b..0000000000 --- a/crates/testing/src/network_reliability.rs +++ /dev/null @@ -1,163 +0,0 @@ -use std::time::Duration; - -use hotshot::traits::NetworkReliability; -use rand::{ - distributions::{Bernoulli, Uniform}, - prelude::Distribution, -}; - -/// A synchronous network. Packets may be delayed, but are guaranteed -/// to arrive within `timeout` ns -#[derive(Clone, Copy, Debug, Default)] -pub struct SynchronousNetwork { - /// Max delay of packet before arrival - timeout_ms: u64, - /// Lowest value in milliseconds that a packet may be delayed - delay_low_ms: u64, -} - -impl NetworkReliability for SynchronousNetwork { - /// never drop a packet - fn sample_keep(&self) -> bool { - true - } - fn sample_delay(&self) -> Duration { - Duration::from_millis( - Uniform::new_inclusive(self.delay_low_ms, self.timeout_ms) - .sample(&mut rand::thread_rng()), - ) - } -} - -/// An asynchronous network. Packets may be dropped entirely -/// or delayed for arbitrarily long periods -/// probability that packet is kept = `keep_numerator` / `keep_denominator` -/// packet delay is obtained by sampling from a uniform distribution -/// between `delay_low_ms` and `delay_high_ms`, inclusive -#[derive(Debug, Clone, Copy)] -pub struct AsynchronousNetwork { - /// numerator for probability of keeping packets - keep_numerator: u32, - /// denominator for probability of keeping packets - keep_denominator: u32, - /// lowest value in milliseconds that a packet may be delayed - delay_low_ms: u64, - /// highest value in milliseconds that a packet may be delayed - delay_high_ms: u64, -} - -impl NetworkReliability for AsynchronousNetwork { - fn sample_keep(&self) -> bool { - Bernoulli::from_ratio(self.keep_numerator, self.keep_denominator) - .unwrap() - .sample(&mut rand::thread_rng()) - } - fn sample_delay(&self) -> Duration { - Duration::from_millis( - Uniform::new_inclusive(self.delay_low_ms, self.delay_high_ms) - .sample(&mut rand::thread_rng()), - ) - } -} - -/// An partially synchronous network. Behaves asynchronously -/// until some arbitrary time bound, GST, -/// then synchronously after GST -#[derive(Debug, Clone, Copy)] -pub struct PartiallySynchronousNetwork { - /// asynchronous portion of network - asynchronous: AsynchronousNetwork, - /// synchronous portion of network - synchronous: SynchronousNetwork, - /// time when GST occurs - gst: std::time::Duration, - /// when the network was started - start: std::time::Instant, -} - -impl NetworkReliability for PartiallySynchronousNetwork { - /// never drop a packet - fn sample_keep(&self) -> bool { - true - } - fn sample_delay(&self) -> Duration { - // act asyncronous before gst - if self.start.elapsed() < self.gst { - if self.asynchronous.sample_keep() { - self.asynchronous.sample_delay() - } else { - // assume packet was "dropped" and will arrive after gst - self.synchronous.sample_delay() + self.gst - } - } else { - // act syncronous after gst - self.synchronous.sample_delay() - } - } -} - -impl Default for AsynchronousNetwork { - // disable all chance of failure - fn default() -> Self { - AsynchronousNetwork { - keep_numerator: 1, - keep_denominator: 1, - delay_low_ms: 0, - delay_high_ms: 0, - } - } -} - -impl Default for PartiallySynchronousNetwork { - fn default() -> Self { - PartiallySynchronousNetwork { - synchronous: SynchronousNetwork::default(), - asynchronous: AsynchronousNetwork::default(), - gst: std::time::Duration::new(0, 0), - start: std::time::Instant::now(), - } - } -} - -impl SynchronousNetwork { - /// create new `SynchronousNetwork` - pub fn new(timeout: u64, delay_low_ms: u64) -> Self { - SynchronousNetwork { - timeout_ms: timeout, - delay_low_ms, - } - } -} - -impl AsynchronousNetwork { - /// create new `AsynchronousNetwork` - pub fn new( - keep_numerator: u32, - keep_denominator: u32, - delay_low_ms: u64, - delay_high_ms: u64, - ) -> Self { - AsynchronousNetwork { - keep_numerator, - keep_denominator, - delay_low_ms, - delay_high_ms, - } - } -} - -impl PartiallySynchronousNetwork { - /// create new `PartiallySynchronousNetwork` - pub fn new( - asynchronous: AsynchronousNetwork, - synchronous: SynchronousNetwork, - gst: std::time::Duration, - ) -> Self { - PartiallySynchronousNetwork { - asynchronous, - synchronous, - gst, - start: std::time::Instant::now(), - } - } -} diff --git a/crates/testing/tests/web_server.rs b/crates/testing/tests/web_server.rs index 6c95318c7b..9b19532902 100644 --- a/crates/testing/tests/web_server.rs +++ b/crates/testing/tests/web_server.rs @@ -31,10 +31,9 @@ async fn web_server_network() { num_successful_views: 35, ..Default::default() }, - // allow more time to pass in CI completion_task_description: CompletionTaskDescription::TimeBasedCompletionTaskBuilder( TimeBasedCompletionTaskDescription { - duration: Duration::from_millis(1_200_000), + duration: Duration::from_secs(20), }, ), ..TestMetadata::default() diff --git a/crates/types/src/traits/election.rs b/crates/types/src/traits/election.rs index 6b3ef7e790..0a881cd093 100644 --- a/crates/types/src/traits/election.rs +++ b/crates/types/src/traits/election.rs @@ -331,18 +331,13 @@ pub trait ConsensusExchange: Send + Sync { /// The contents of a vote on `commit`. fn vote_data(&self, commit: Self::Commitment) -> VoteData; - /// Validate a QC. - fn is_valid_cert(&self, qc: &Self::Certificate, commit: Self::Commitment) -> bool { + /// Validate a certificate. + fn is_valid_cert(&self, qc: &Self::Certificate) -> bool { if qc.is_genesis() && qc.view_number() == TYPES::Time::genesis() { return true; } let leaf_commitment = qc.leaf_commitment(); - if leaf_commitment != commit { - error!("Leaf commitment does not equal parent commitment"); - return false; - } - match qc.signatures() { AssembledSignature::DA(qc) => { let real_commit = VoteData::DA(leaf_commitment).get_commit(); diff --git a/crates/types/src/traits/network.rs b/crates/types/src/traits/network.rs index ef02b05245..1729636836 100644 --- a/crates/types/src/traits/network.rs +++ b/crates/types/src/traits/network.rs @@ -2,9 +2,10 @@ //! //! Contains types and traits used by `HotShot` to abstract over network access +use async_compatibility_layer::art::async_sleep; #[cfg(async_executor_impl = "async-std")] use async_std::future::TimeoutError; -use hotshot_task::BoxSyncFuture; +use hotshot_task::{boxed_sync, BoxSyncFuture}; use libp2p_networking::network::NetworkNodeHandleError; #[cfg(async_executor_impl = "tokio")] use tokio::time::error::Elapsed as TimeoutError; @@ -14,6 +15,10 @@ use super::{election::Membership, node_implementation::NodeType, signature_key:: use crate::{data::ViewNumber, message::MessagePurpose}; use async_compatibility_layer::channel::UnboundedSendError; use async_trait::async_trait; +use rand::{ + distributions::{Bernoulli, Uniform}, + prelude::Distribution, +}; use serde::{Deserialize, Serialize}; use snafu::Snafu; use std::{collections::BTreeSet, fmt::Debug, sync::Arc, time::Duration}; @@ -366,6 +371,7 @@ pub enum NetworkChange { } /// interface describing how reliable the network is +#[async_trait] pub trait NetworkReliability: Debug + Sync + std::marker::Send { /// Sample from bernoulli distribution to decide whether /// or not to keep a packet @@ -373,8 +379,225 @@ pub trait NetworkReliability: Debug + Sync + std::marker::Send { /// /// Panics if `self.keep_numerator > self.keep_denominator` /// - fn sample_keep(&self) -> bool; + fn sample_keep(&self) -> bool { + true + } + /// sample from uniform distribution to decide whether /// or not to keep a packet - fn sample_delay(&self) -> Duration; + fn sample_delay(&self) -> Duration { + std::time::Duration::ZERO + } + + /// scramble the packet + fn scramble(&self, msg: Vec) -> Vec { + msg + } + + /// number of times to repeat the packet + fn sample_repeat(&self) -> usize { + 1 + } + + /// given a message and a way to send the message, + /// decide whether or not to send the message + /// how long to delay the message + /// whether or not to send duplicates + /// and whether or not to include noise with the message + /// then send the message + fn chaos_send_msg( + &self, + msg: Vec, + send_fn: Arc) -> BoxSyncFuture<'static, ()>>, + ) -> BoxSyncFuture<'static, ()> { + let sample_keep = self.sample_keep(); + let delay = self.sample_delay(); + let repeats = self.sample_repeat(); + let mut msgs = Vec::new(); + for _idx in 0..repeats { + let scrambled = self.scramble(msg.clone()); + msgs.push(scrambled); + } + let closure = async move { + if sample_keep { + async_sleep(delay).await; + for msg in msgs { + send_fn(msg).await; + } + } + }; + boxed_sync(closure) + } +} + +/// ideal network +#[derive(Clone, Copy, Debug, Default)] +pub struct PerfectNetwork {} + +impl NetworkReliability for PerfectNetwork {} + +/// A synchronous network. Packets may be delayed, but are guaranteed +/// to arrive within `timeout` ns +#[derive(Clone, Copy, Debug, Default)] +pub struct SynchronousNetwork { + /// Max delay of packet before arrival + timeout_ms: u64, + /// Lowest value in milliseconds that a packet may be delayed + delay_low_ms: u64, +} + +impl NetworkReliability for SynchronousNetwork { + /// never drop a packet + fn sample_keep(&self) -> bool { + true + } + fn sample_delay(&self) -> Duration { + Duration::from_millis( + Uniform::new_inclusive(self.delay_low_ms, self.timeout_ms) + .sample(&mut rand::thread_rng()), + ) + } +} + +/// An asynchronous network. Packets may be dropped entirely +/// or delayed for arbitrarily long periods +/// probability that packet is kept = `keep_numerator` / `keep_denominator` +/// packet delay is obtained by sampling from a uniform distribution +/// between `delay_low_ms` and `delay_high_ms`, inclusive +#[derive(Debug, Clone, Copy)] +pub struct AsynchronousNetwork { + /// numerator for probability of keeping packets + keep_numerator: u32, + /// denominator for probability of keeping packets + keep_denominator: u32, + /// lowest value in milliseconds that a packet may be delayed + delay_low_ms: u64, + /// highest value in milliseconds that a packet may be delayed + delay_high_ms: u64, +} + +impl NetworkReliability for AsynchronousNetwork { + fn sample_keep(&self) -> bool { + Bernoulli::from_ratio(self.keep_numerator, self.keep_denominator) + .unwrap() + .sample(&mut rand::thread_rng()) + } + fn sample_delay(&self) -> Duration { + Duration::from_millis( + Uniform::new_inclusive(self.delay_low_ms, self.delay_high_ms) + .sample(&mut rand::thread_rng()), + ) + } +} + +/// An partially synchronous network. Behaves asynchronously +/// until some arbitrary time bound, GST, +/// then synchronously after GST +#[allow(clippy::similar_names)] +#[derive(Debug, Clone, Copy)] +pub struct PartiallySynchronousNetwork { + /// asynchronous portion of network + asynchronous: AsynchronousNetwork, + /// synchronous portion of network + synchronous: SynchronousNetwork, + /// time when GST occurs + gst: std::time::Duration, + /// when the network was started + start: std::time::Instant, +} + +impl NetworkReliability for PartiallySynchronousNetwork { + /// never drop a packet + fn sample_keep(&self) -> bool { + true + } + fn sample_delay(&self) -> Duration { + // act asyncronous before gst + if self.start.elapsed() < self.gst { + if self.asynchronous.sample_keep() { + self.asynchronous.sample_delay() + } else { + // assume packet was "dropped" and will arrive after gst + self.synchronous.sample_delay() + self.gst + } + } else { + // act syncronous after gst + self.synchronous.sample_delay() + } + } +} + +impl Default for AsynchronousNetwork { + // disable all chance of failure + fn default() -> Self { + AsynchronousNetwork { + keep_numerator: 1, + keep_denominator: 1, + delay_low_ms: 0, + delay_high_ms: 0, + } + } +} + +impl Default for PartiallySynchronousNetwork { + fn default() -> Self { + PartiallySynchronousNetwork { + synchronous: SynchronousNetwork::default(), + asynchronous: AsynchronousNetwork::default(), + gst: std::time::Duration::new(0, 0), + start: std::time::Instant::now(), + } + } +} + +impl SynchronousNetwork { + /// create new `SynchronousNetwork` + #[must_use] + pub fn new(timeout: u64, delay_low_ms: u64) -> Self { + SynchronousNetwork { + timeout_ms: timeout, + delay_low_ms, + } + } +} + +impl AsynchronousNetwork { + /// create new `AsynchronousNetwork` + #[must_use] + pub fn new( + keep_numerator: u32, + keep_denominator: u32, + delay_low_ms: u64, + delay_high_ms: u64, + ) -> Self { + AsynchronousNetwork { + keep_numerator, + keep_denominator, + delay_low_ms, + delay_high_ms, + } + } +} + +impl PartiallySynchronousNetwork { + /// create new `PartiallySynchronousNetwork` + #[allow(clippy::similar_names)] + #[must_use] + pub fn new( + asynchronous: AsynchronousNetwork, + synchronous: SynchronousNetwork, + gst: std::time::Duration, + ) -> Self { + PartiallySynchronousNetwork { + asynchronous, + synchronous, + gst, + start: std::time::Instant::now(), + } + } +} + +/// A chaotic network using all the networking calls +pub struct ChaosNetwork { + // TODO } diff --git a/crates/web_server/src/lib.rs b/crates/web_server/src/lib.rs index 2bd746e1cd..e29ce036e8 100644 --- a/crates/web_server/src/lib.rs +++ b/crates/web_server/src/lib.rs @@ -288,11 +288,11 @@ impl WebServerDataSource for WebServerState { self.oldest_vote += 1; } } - let highest_index = self.vote_index.entry(view_number).or_insert(0); + let next_index = self.vote_index.entry(view_number).or_insert(0); self.votes .entry(view_number) - .and_modify(|current_votes| current_votes.push((*highest_index, vote.clone()))) - .or_insert_with(|| vec![(*highest_index, vote)]); + .and_modify(|current_votes| current_votes.push((*next_index, vote.clone()))) + .or_insert_with(|| vec![(*next_index, vote)]); self.vote_index .entry(view_number) .and_modify(|index| *index += 1); @@ -310,11 +310,11 @@ impl WebServerDataSource for WebServerState { self.oldest_view_sync_vote += 1; } } - let highest_index = self.view_sync_vote_index.entry(view_number).or_insert(0); + let next_index = self.view_sync_vote_index.entry(view_number).or_insert(0); self.view_sync_votes .entry(view_number) - .and_modify(|current_votes| current_votes.push((*highest_index, vote.clone()))) - .or_insert_with(|| vec![(*highest_index, vote)]); + .and_modify(|current_votes| current_votes.push((*next_index, vote.clone()))) + .or_insert_with(|| vec![(*next_index, vote)]); self.view_sync_vote_index .entry(view_number) .and_modify(|index| *index += 1); @@ -349,7 +349,8 @@ impl WebServerDataSource for WebServerState { ) -> Result<(), Error> { // Only keep proposal history for MAX_VIEWS number of view if self.view_sync_proposals.len() >= MAX_VIEWS { - self.view_sync_proposals.remove(&self.oldest_view_sync_vote); + self.view_sync_proposals + .remove(&self.oldest_view_sync_proposal); while !self .view_sync_proposals .contains_key(&self.oldest_view_sync_proposal) @@ -357,14 +358,14 @@ impl WebServerDataSource for WebServerState { self.oldest_view_sync_proposal += 1; } } - let highest_index = self + let next_index = self .view_sync_proposal_index .entry(view_number) .or_insert(0); self.view_sync_proposals .entry(view_number) - .and_modify(|current_props| current_props.push((*highest_index, proposal.clone()))) - .or_insert_with(|| vec![(*highest_index, proposal)]); + .and_modify(|current_props| current_props.push((*next_index, proposal.clone()))) + .or_insert_with(|| vec![(*next_index, proposal)]); self.view_sync_proposal_index .entry(view_number) .and_modify(|index| *index += 1); diff --git a/flake.lock b/flake.lock index 99bccee207..c170fd09d4 100644 --- a/flake.lock +++ b/flake.lock @@ -41,11 +41,11 @@ "rust-analyzer-src": "rust-analyzer-src" }, "locked": { - "lastModified": 1696054802, - "narHash": "sha256-VTON/WlYeyzFoYwwsb8KveqJJCfWEI6NtZYHcAFKBuo=", + "lastModified": 1696659643, + "narHash": "sha256-HO1VCcwEe3jlEIUlSv1jFwt/ILw1fWxP0g8S9kRsous=", "owner": "nix-community", "repo": "fenix", - "rev": "3116ee073ab3931c78328ca126224833c95e6227", + "rev": "6e3bc9460b51a4602b7e85746ec3e3988b8bd8c9", "type": "github" }, "original": { @@ -57,11 +57,11 @@ "flake-compat": { "flake": false, "locked": { - "lastModified": 1673956053, - "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=", + "lastModified": 1696426674, + "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", "owner": "edolstra", "repo": "flake-compat", - "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9", + "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", "type": "github" }, "original": { @@ -72,11 +72,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1695978539, - "narHash": "sha256-lta5HToBZMWZ2hl5CautNSUgIZViR41QxN7JKbMAjgQ=", + "lastModified": 1696661029, + "narHash": "sha256-GIB5VTkvsDIqfMpdtuetOzpm64P8wm8nBSv5Eo8XM3Y=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "bd9b686c0168041aea600222be0805a0de6e6ab8", + "rev": "2de1be5b51c3d6fa833f1c1f222dc867dd054b31", "type": "github" }, "original": { @@ -99,11 +99,11 @@ "rust-analyzer-src": { "flake": false, "locked": { - "lastModified": 1696014495, - "narHash": "sha256-TcDFXRK9weJ1yCQyo6zxRhLfYHe/GcXDbSUpiszNCuw=", + "lastModified": 1696592032, + "narHash": "sha256-kY1temv39OjasB81KHdoMqpxh21F3kStwxE51eqViJ0=", "owner": "rust-lang", "repo": "rust-analyzer", - "rev": "4791a5de21735e3d9414d131a4f973da9bae0537", + "rev": "b1f89a84ab350091e6c20cfe30c2fab8d76b80e4", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index 04cbf3c782..9019e5b6ee 100644 --- a/flake.nix +++ b/flake.nix @@ -178,6 +178,7 @@ openssl.out ] ++ lib.optionals stdenv.isDarwin [ darwin.apple_sdk.frameworks.Security + darwin.apple_sdk.frameworks.CoreServices pkgs.libiconv darwin.apple_sdk.frameworks.SystemConfiguration ]; diff --git a/justfile b/justfile index d0c4b9a5b2..1e1c21aa96 100644 --- a/justfile +++ b/justfile @@ -13,7 +13,7 @@ run_ci: lint build test @async_std target *ARGS: echo setting executor to async-std - export RUSTDOCFLAGS='--cfg async_executor_impl="async-std" --cfg async_channel_impl="async-std" {{original_rustdocflags}}' RUSTFLAGS='--cfg async_executor_impl="async-std" --cfg async_channel_impl="async-std" {{original_rustflags}}' && just {{target}} {{ARGS}} + export RUST_MIN_STACK=4194304 RUSTDOCFLAGS='--cfg async_executor_impl="async-std" --cfg async_channel_impl="async-std" {{original_rustdocflags}}' RUSTFLAGS='--cfg async_executor_impl="async-std" --cfg async_channel_impl="async-std" {{original_rustflags}}' && just {{target}} {{ARGS}} build: cargo build --verbose --workspace --examples --bins --tests --lib --benches