diff --git a/Cargo.lock b/Cargo.lock index f1f4767d88..54960d7d46 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -214,14 +214,14 @@ dependencies = [ "alloy-transport", "futures", "futures-util", - "thiserror 2.0.11", + "thiserror 2.0.12", ] [[package]] name = "alloy-core" -version = "0.8.21" +version = "0.8.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "482f377cebceed4bb1fb5e7970f0805e2ab123d06701be9351b67ed6341e74aa" +checksum = "45ef3546f382c07c7c2e1d24844ed593e1c9b272236aedf635e4a295fb3fc9d0" dependencies = [ "alloy-dyn-abi", "alloy-json-abi", @@ -231,9 +231,9 @@ dependencies = [ [[package]] name = "alloy-dyn-abi" -version = "0.8.21" +version = "0.8.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "555896f0b8578adb522b1453b6e6cc6704c3027bd0af20058befdde992cee8e9" +checksum = "00e08c581811006021970bf07f2ecf3213f6237c125f7fd99607004b23627b61" dependencies = [ "alloy-json-abi", "alloy-primitives", @@ -259,14 +259,14 @@ dependencies = [ [[package]] name = "alloy-eip7702" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cabf647eb4650c91a9d38cb6f972bb320009e7e9d61765fb688a86f1563b33e8" +checksum = "9b15b13d38b366d01e818fe8e710d4d702ef7499eacd44926a06171dd9585d0c" dependencies = [ "alloy-primitives", "alloy-rlp", - "derive_more 1.0.0", "serde", + "thiserror 2.0.12", ] [[package]] @@ -289,9 +289,9 @@ dependencies = [ [[package]] name = "alloy-json-abi" -version = "0.8.21" +version = "0.8.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4012581681b186ba0882007ed873987cc37f86b1b488fe6b91d5efd0b585dc41" +checksum = "125601804507fef5ae7debcbf800906b12741f19800c1c05b953d0f1b990131a" dependencies = [ "alloy-primitives", "alloy-sol-type-parser", @@ -309,7 +309,7 @@ dependencies = [ "alloy-sol-types", "serde", "serde_json", - "thiserror 2.0.11", + "thiserror 2.0.12", "tracing", ] @@ -335,7 +335,7 @@ dependencies = [ "futures-utils-wasm", "serde", "serde_json", - "thiserror 2.0.11", + "thiserror 2.0.12", ] [[package]] @@ -353,15 +353,15 @@ dependencies = [ [[package]] name = "alloy-primitives" -version = "0.8.21" +version = "0.8.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "478bedf4d24e71ea48428d1bc278553bd7c6ae07c30ca063beb0b09fe58a9e74" +checksum = "8c66bb6715b7499ea755bde4c96223ae8eb74e05c014ab38b9db602879ffb825" dependencies = [ "alloy-rlp", "bytes 1.10.0", "cfg-if", "const-hex", - "derive_more 1.0.0", + "derive_more 2.0.1", "foldhash", "hashbrown 0.15.2", "indexmap 2.7.1", @@ -410,7 +410,7 @@ dependencies = [ "schnellru", "serde", "serde_json", - "thiserror 2.0.11", + "thiserror 2.0.12", "tokio", "tracing", "url", @@ -455,7 +455,7 @@ checksum = "a40e1ef334153322fd878d07e86af7a529bcb86b2439525920a88eba87bcf943" dependencies = [ "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.99", ] [[package]] @@ -523,7 +523,7 @@ dependencies = [ "itertools 0.13.0", "serde", "serde_json", - "thiserror 2.0.11", + "thiserror 2.0.12", ] [[package]] @@ -548,7 +548,7 @@ dependencies = [ "auto_impl", "elliptic-curve", "k256", - "thiserror 2.0.11", + "thiserror 2.0.12", ] [[package]] @@ -566,28 +566,28 @@ dependencies = [ "coins-bip39 0.12.0", "k256", "rand 0.8.5", - "thiserror 2.0.11", + "thiserror 2.0.12", ] [[package]] name = "alloy-sol-macro" -version = "0.8.21" +version = "0.8.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2708e27f58d747423ae21d31b7a6625159bd8d867470ddd0256f396a68efa11" +checksum = "c7f9c3c7bc1f4e334e5c5fc59ec8dac894973a71b11da09065affc6094025049" dependencies = [ "alloy-sol-macro-expander", "alloy-sol-macro-input", "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.99", ] [[package]] name = "alloy-sol-macro-expander" -version = "0.8.21" +version = "0.8.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6b7984d7e085dec382d2c5ef022b533fcdb1fe6129200af30ebf5afddb6a361" +checksum = "46ff7aa715eb2404cb87fa94390d2c5d5addd70d9617e20b2398ee6f48cb21f0" dependencies = [ "alloy-json-abi", "alloy-sol-macro-input", @@ -597,16 +597,16 @@ dependencies = [ "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.99", "syn-solidity", "tiny-keccak", ] [[package]] name = "alloy-sol-macro-input" -version = "0.8.21" +version = "0.8.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33d6a9fc4ed1a3c70bdb2357bec3924551c1a59f24e5a04a74472c755b37f87d" +checksum = "6f105fa700140c0cc6e2c3377adef650c389ac57b8ead8318a2e6bd52f1ae841" dependencies = [ "alloy-json-abi", "const-hex", @@ -615,15 +615,15 @@ dependencies = [ "proc-macro2", "quote", "serde_json", - "syn 2.0.98", + "syn 2.0.99", "syn-solidity", ] [[package]] name = "alloy-sol-type-parser" -version = "0.8.21" +version = "0.8.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b1b3e9a48a6dd7bb052a111c8d93b5afc7956ed5e2cb4177793dc63bb1d2a36" +checksum = "c649acc6c9d3893e392c737faeadce30b4a1751eed148ae43bc2f27f29c4480c" dependencies = [ "serde", "winnow 0.7.3", @@ -631,9 +631,9 @@ dependencies = [ [[package]] name = "alloy-sol-types" -version = "0.8.21" +version = "0.8.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6044800da35c38118fd4b98e18306bd3b91af5dedeb54c1b768cf1b4fb68f549" +checksum = "5f819635439ebb06aa13c96beac9b2e7360c259e90f5160a6848ae0d94d10452" dependencies = [ "alloy-json-abi", "alloy-primitives", @@ -654,7 +654,7 @@ dependencies = [ "futures-utils-wasm", "serde", "serde_json", - "thiserror 2.0.11", + "thiserror 2.0.12", "tokio", "tower 0.5.2", "tracing", @@ -793,9 +793,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.96" +version = "1.0.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b964d184e89d9b6b67dd2715bc8e74cf3107fb2b529990c90cf517326150bf4" +checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f" [[package]] name = "arbitrary" @@ -1201,7 +1201,7 @@ checksum = "965c2d33e53cb6b267e148a4cb0760bc01f4904c1cd4bb4002a085bb016d1490" dependencies = [ "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.99", "synstructure", ] @@ -1213,7 +1213,7 @@ checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.99", ] [[package]] @@ -1498,7 +1498,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.99", ] [[package]] @@ -1522,13 +1522,13 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.86" +version = "0.1.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "644dd749086bf3771a2fbc5f256fdb982d53f011c7d5d560304eafeecebce79d" +checksum = "d556ec1359574147ec0c4fc5eb525f3f23263a592b1a9c07e0a75b427de55c97" dependencies = [ "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.99", ] [[package]] @@ -1627,7 +1627,7 @@ checksum = "e12882f59de5360c748c4cbf569a042d5fb0eb515f7bea9c1f470b47f6ffbd73" dependencies = [ "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.99", ] [[package]] @@ -1638,13 +1638,13 @@ checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "automod" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edf3ee19dbc0a46d740f6f0926bde8c50f02bdbc7b536842da28f6ac56513a8b" +checksum = "ebb4bd301db2e2ca1f5be131c24eb8ebf2d9559bc3744419e93baf8ddea7e670" dependencies = [ "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.99", ] [[package]] @@ -1811,7 +1811,7 @@ version = "0.69.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" dependencies = [ - "bitflags 2.8.0", + "bitflags 2.9.0", "cexpr", "clang-sys", "itertools 0.12.1", @@ -1822,7 +1822,7 @@ dependencies = [ "regex", "rustc-hash 1.1.0", "shlex", - "syn 2.0.98", + "syn 2.0.99", ] [[package]] @@ -1831,7 +1831,7 @@ version = "0.71.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f58bf3d7db68cfbac37cfc485a8d711e87e064c3d0fe0435b92f7a407f9d6b3" dependencies = [ - "bitflags 2.8.0", + "bitflags 2.9.0", "cexpr", "clang-sys", "itertools 0.13.0", @@ -1842,7 +1842,7 @@ dependencies = [ "regex", "rustc-hash 2.1.1", "shlex", - "syn 2.0.98", + "syn 2.0.99", ] [[package]] @@ -1883,9 +1883,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.8.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36" +checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" dependencies = [ "serde", ] @@ -1914,16 +1914,15 @@ dependencies = [ [[package]] name = "blake3" -version = "1.6.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1230237285e3e10cde447185e8975408ae24deaa67205ce684805c25bc0c7937" +checksum = "675f87afced0413c9bb02843499dbbd3882a237645883f71a2b59644a6d2f753" dependencies = [ "arrayref", "arrayvec", "cc", "cfg-if", "constant_time_eq 0.3.1", - "memmap2", ] [[package]] @@ -2021,9 +2020,9 @@ checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" [[package]] name = "byte-slice-cast" -version = "1.2.2" +version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" +checksum = "7575182f7272186991736b70173b0ea045398f984bf5ebbb3804736ce1330c9d" [[package]] name = "bytecheck" @@ -2049,9 +2048,9 @@ dependencies = [ [[package]] name = "bytemuck" -version = "1.21.0" +version = "1.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef657dfab802224e671f5818e9a4935f9b1957ed18e58292690cc39e7a4092a3" +checksum = "b6b1fc10dbac614ebc03540c9dbd60e83887fda27794998c6528f1782047d540" dependencies = [ "bytemuck_derive", ] @@ -2064,7 +2063,7 @@ checksum = "3fa76293b4f7bb636ab88fd78228235b5248b4d05cc589aed610f954af5d7c7a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.99", ] [[package]] @@ -2106,12 +2105,11 @@ dependencies = [ [[package]] name = "bzip2-sys" -version = "0.1.12+1.0.8" +version = "0.1.13+1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72ebc2f1a417f01e1da30ef264ee86ae31d2dcd2d603ea283d3c244a883ca2a9" +checksum = "225bff33b2141874fe80d71e07d6eec4f85c5c216453dd96388240f96e1acc14" dependencies = [ "cc", - "libc", "pkg-config", ] @@ -2141,9 +2139,9 @@ dependencies = [ [[package]] name = "capnp" -version = "0.20.3" +version = "0.20.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bce4e2d41c16cf9188f47ca4d59fdcdca1f33705af211bdb41f0afbd3442f8b5" +checksum = "0d1e413320159773070317b6678b180f7ebdcb4f8825d2bdec5b56e7ecc8d0dd" dependencies = [ "embedded-io", ] @@ -2216,9 +2214,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.15" +version = "1.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c736e259eea577f443d5c86c304f9f4ae0295c43f3ba05c21f1d66b5f06001af" +checksum = "be714c154be609ec7f5dad223a33bf1482fff90472de28f7362806e6d4832b8c" dependencies = [ "jobserver", "libc", @@ -2341,7 +2339,7 @@ dependencies = [ "sqlx", "thiserror 1.0.69", "tokio", - "tokio-rustls 0.26.1", + "tokio-rustls 0.26.2", "tracing", "url", "warp", @@ -2376,7 +2374,7 @@ dependencies = [ "sqlx", "thiserror 1.0.69", "tokio", - "tokio-rustls 0.26.1", + "tokio-rustls 0.26.2", "tracing", "url", "warp", @@ -2405,9 +2403,9 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "chrono" -version = "0.4.39" +version = "0.4.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e36cc9d416881d2e24f9a963be5fb1cd90966419ac844274161d10488b3e825" +checksum = "1a7964611d71df112cb1730f2ee67324fcf4d0fc6606acbbe9bfe06df124637c" dependencies = [ "android-tzdata", "iana-time-zone", @@ -2415,7 +2413,7 @@ dependencies = [ "num-traits", "serde", "wasm-bindgen", - "windows-targets 0.52.6", + "windows-link", ] [[package]] @@ -2512,7 +2510,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.99", ] [[package]] @@ -3195,7 +3193,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.99", ] [[package]] @@ -3216,7 +3214,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.99", "synstructure", ] @@ -3241,7 +3239,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.98", + "syn 2.0.99", ] [[package]] @@ -3252,7 +3250,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", - "syn 2.0.98", + "syn 2.0.99", ] [[package]] @@ -3292,7 +3290,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "18e4fdb82bd54a12e42fb58a800dcae6b9e13982238ce2296dc3570b92148e1f" dependencies = [ "data-encoding", - "syn 2.0.98", + "syn 2.0.99", ] [[package]] @@ -3303,7 +3301,7 @@ checksum = "297806318ef30ad066b15792a8372858020ae3ca2e414ee6c2133b1eb9e9e945" dependencies = [ "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.99", ] [[package]] @@ -3360,7 +3358,7 @@ checksum = "30542c1ad912e0e3d22a1935c290e12e8a29d704a420177a31faad4a601a0800" dependencies = [ "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.99", ] [[package]] @@ -3381,7 +3379,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.99", ] [[package]] @@ -3391,7 +3389,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" dependencies = [ "derive_builder_core", - "syn 2.0.98", + "syn 2.0.99", ] [[package]] @@ -3404,7 +3402,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version 0.4.1", - "syn 2.0.98", + "syn 2.0.99", ] [[package]] @@ -3413,7 +3411,16 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a9b99b9cbbe49445b21764dc0625032a89b145a2642e67603e1c936f5458d05" dependencies = [ - "derive_more-impl", + "derive_more-impl 1.0.0", +] + +[[package]] +name = "derive_more" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "093242cf7570c207c83073cf82f79706fe7b8317e98620a47d5be7c3d8497678" +dependencies = [ + "derive_more-impl 2.0.1", ] [[package]] @@ -3425,7 +3432,19 @@ dependencies = [ "convert_case 0.6.0", "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.99", + "unicode-xid", +] + +[[package]] +name = "derive_more-impl" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.99", "unicode-xid", ] @@ -3556,7 +3575,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.99", ] [[package]] @@ -3728,7 +3747,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.99", ] [[package]] @@ -3989,7 +4008,7 @@ dependencies = [ "reqwest 0.11.27", "serde", "serde_json", - "syn 2.0.98", + "syn 2.0.99", "toml 0.8.20", "walkdir", ] @@ -4007,7 +4026,7 @@ dependencies = [ "proc-macro2", "quote", "serde_json", - "syn 2.0.98", + "syn 2.0.99", ] [[package]] @@ -4041,7 +4060,7 @@ dependencies = [ "serde", "serde_json", "strum 0.26.3", - "syn 2.0.98", + "syn 2.0.99", "tempfile", "thiserror 1.0.69", "tiny-keccak", @@ -4505,7 +4524,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.99", ] [[package]] @@ -5328,7 +5347,7 @@ dependencies = [ "derive_builder", "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.99", "workspace-hack", ] @@ -5722,9 +5741,9 @@ dependencies = [ [[package]] name = "httparse" -version = "1.10.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2d708df4e7140240a16cd6ab0ab65c972d7433ab77819ea693fde9c43811e2a" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" [[package]] name = "httpdate" @@ -5809,7 +5828,7 @@ dependencies = [ "rustls 0.23.23", "rustls-pki-types", "tokio", - "tokio-rustls 0.26.1", + "tokio-rustls 0.26.2", "tower-service", ] @@ -6031,7 +6050,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.99", ] [[package]] @@ -6148,7 +6167,7 @@ checksum = "a0eb5a3343abf848c0984fe4604b2b105da9539376e24fc0a3b0007411ae4fd9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.99", ] [[package]] @@ -7203,7 +7222,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.99", ] [[package]] @@ -7264,7 +7283,7 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bitflags 2.8.0", + "bitflags 2.9.0", "libc", ] @@ -7360,9 +7379,9 @@ checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" [[package]] name = "litemap" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" +checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856" [[package]] name = "local-ip-address" @@ -7632,7 +7651,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.99", ] [[package]] @@ -7651,15 +7670,6 @@ version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" -[[package]] -name = "memmap2" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd3f7eed9d3848f8b98834af67102b720745c4ec028fcd0aa0239277e7de374f" -dependencies = [ - "libc", -] - [[package]] name = "memoffset" version = "0.6.5" @@ -7897,7 +7907,7 @@ dependencies = [ "log", "netlink-packet-core", "netlink-sys", - "thiserror 2.0.11", + "thiserror 2.0.12", ] [[package]] @@ -8143,7 +8153,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.99", ] [[package]] @@ -8233,7 +8243,7 @@ version = "0.10.71" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e14130c6a98cd258fdcb0fb6d744152343ff729cbfcb28c656a9d12b999fbcd" dependencies = [ - "bitflags 2.8.0", + "bitflags 2.9.0", "cfg-if", "foreign-types", "libc", @@ -8250,7 +8260,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.99", ] [[package]] @@ -8327,7 +8337,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.99", ] [[package]] @@ -8451,7 +8461,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b7cafe60d6cf8e62e1b9b2ea516a089c008945bb5a275416789e7db0bc199dc" dependencies = [ "memchr", - "thiserror 2.0.11", + "thiserror 2.0.12", "ucd-trie", ] @@ -8475,7 +8485,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.99", ] [[package]] @@ -8539,7 +8549,7 @@ dependencies = [ "phf_shared", "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.99", ] [[package]] @@ -8553,22 +8563,22 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.1.9" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfe2e71e1471fe07709406bf725f710b02927c9c54b2b5b2ec0e8087d97c327d" +checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.9" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6e859e6e5bd50440ab63c47e3ebabc90f26251f7c73c3d3e837b74a1cc3fa67" +checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" dependencies = [ "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.99", ] [[package]] @@ -8629,9 +8639,9 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" [[package]] name = "plotters" @@ -8779,7 +8789,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6924ced06e1f7dfe3fa48d57b9f74f55d8915f5036121bef647ef4b204895fac" dependencies = [ "proc-macro2", - "syn 2.0.98", + "syn 2.0.99", ] [[package]] @@ -8858,7 +8868,7 @@ dependencies = [ "proc-macro-error-attr2", "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.99", ] [[package]] @@ -8869,9 +8879,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.93" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" +checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" dependencies = [ "unicode-ident", ] @@ -8911,7 +8921,7 @@ checksum = "440f724eba9f6996b75d63681b0a92b06947f1457076d503a4d2e2c8f56442b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.99", ] [[package]] @@ -8934,7 +8944,7 @@ checksum = "14cae93065090804185d3b75f0bf93b8eeda30c7a9b4a33d3bdb3988d6229e50" dependencies = [ "bit-set 0.8.0", "bit-vec 0.8.0", - "bitflags 2.8.0", + "bitflags 2.9.0", "lazy_static", "num-traits", "rand 0.8.5", @@ -8966,7 +8976,7 @@ dependencies = [ "itertools 0.12.1", "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.99", ] [[package]] @@ -9034,13 +9044,13 @@ dependencies = [ [[package]] name = "quick_cache" -version = "0.6.10" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f67cfc9c723c39f3615eb0840b00c4cb9e2b068d2fa761a30d845ec91730a59" +checksum = "0af25b4e960ffdf0dead61cf0cec0c2e44c76927bf933ab4f02e2858fb449397" dependencies = [ "ahash 0.8.11", "equivalent", - "hashbrown 0.14.5", + "hashbrown 0.15.2", "parking_lot", ] @@ -9058,7 +9068,7 @@ dependencies = [ "rustc-hash 2.1.1", "rustls 0.23.23", "socket2 0.5.8", - "thiserror 2.0.11", + "thiserror 2.0.12", "tokio", "tracing", ] @@ -9077,7 +9087,7 @@ dependencies = [ "rustls 0.23.23", "rustls-pki-types", "slab", - "thiserror 2.0.11", + "thiserror 2.0.12", "tinyvec", "tracing", "web-time", @@ -9099,9 +9109,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.38" +version = "1.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" +checksum = "c1f1914ce909e1658d9907913b4b91947430c7d9be598b15a1912935b8c04801" dependencies = [ "proc-macro2", ] @@ -9144,8 +9154,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94" dependencies = [ "rand_chacha 0.9.0", - "rand_core 0.9.2", - "zerocopy 0.8.20", + "rand_core 0.9.3", + "zerocopy 0.8.21", ] [[package]] @@ -9175,7 +9185,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" dependencies = [ "ppv-lite86", - "rand_core 0.9.2", + "rand_core 0.9.3", ] [[package]] @@ -9198,12 +9208,11 @@ dependencies = [ [[package]] name = "rand_core" -version = "0.9.2" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a509b1a2ffbe92afab0e55c8fd99dea1c280e8171bd2d88682bb20bc41cbc2c" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" dependencies = [ "getrandom 0.3.1", - "zerocopy 0.8.20", ] [[package]] @@ -9306,11 +9315,11 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.9" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82b568323e98e49e2a0899dcee453dd679fae22d69adf9b11dd508d1549b7e2f" +checksum = "0b8c0c260b63a8219631167be35e6a988e9554dbd323f8bd08439c8ed1302bd1" dependencies = [ - "bitflags 2.8.0", + "bitflags 2.9.0", ] [[package]] @@ -9366,7 +9375,7 @@ dependencies = [ "quote", "refinery-core", "regex", - "syn 2.0.98", + "syn 2.0.99", ] [[package]] @@ -9432,7 +9441,6 @@ dependencies = [ "bincode", "blake3", "byteorder", - "derive_builder", "derive_more 1.0.0", "hotshot-types", "parking_lot", @@ -9602,7 +9610,7 @@ dependencies = [ "rkyv_derive", "seahash", "tinyvec", - "uuid 1.14.0", + "uuid 1.15.1", ] [[package]] @@ -9645,7 +9653,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94" dependencies = [ "base64 0.21.7", - "bitflags 2.8.0", + "bitflags 2.9.0", "serde", "serde_derive", ] @@ -9826,7 +9834,7 @@ version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ - "bitflags 2.8.0", + "bitflags 2.9.0", "errno", "libc", "linux-raw-sys 0.4.15", @@ -9995,7 +10003,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.99", ] [[package]] @@ -10088,7 +10096,7 @@ version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags 2.8.0", + "bitflags 2.9.0", "core-foundation", "core-foundation-sys", "libc", @@ -10171,6 +10179,7 @@ dependencies = [ "async-once-cell", "async-trait", "bincode", + "byteorder", "cdn-broker 0.4.0 (git+https://github.com/EspressoSystems/Push-CDN?tag=0.5.1-upgrade)", "cdn-marshal 0.4.0 (git+https://github.com/EspressoSystems/Push-CDN?tag=0.5.1-upgrade)", "clap", @@ -10216,6 +10225,7 @@ dependencies = [ "rand 0.8.5", "rand_chacha 0.3.1", "rand_distr", + "request-response", "reqwest 0.12.12", "sequencer", "sequencer-utils", @@ -10292,14 +10302,14 @@ checksum = "59fb1bedd774187d304179493b0d3c41fbe97b04b14305363f68d2bdf5e47cb9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.99", ] [[package]] name = "serde_bytes" -version = "0.11.15" +version = "0.11.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "387cc504cb06bb40a96c8e04e951fe01854cf6bc921053c954e4a606d9675c6a" +checksum = "364fec0df39c49a083c9a8a18a23a6bcfd9af130fe9fe321d18520a0d113e09e" dependencies = [ "serde", ] @@ -10312,7 +10322,7 @@ checksum = "f09503e191f4e797cb8aac08e9a4a4695c5edf6a2e70e376d961ddd5c969f82b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.99", ] [[package]] @@ -10326,9 +10336,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.139" +version = "1.0.140" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44f86c3acccc9c65b153fe1b85a3be07fe5515274ec9f0653b4a0875731c72a6" +checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" dependencies = [ "itoa", "memchr", @@ -10395,7 +10405,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.99", ] [[package]] @@ -10560,7 +10570,7 @@ checksum = "297f631f50729c8c99b84667867963997ec0b50f32b2a7dbcab828ef0541e8bb" dependencies = [ "num-bigint", "num-traits", - "thiserror 2.0.11", + "thiserror 2.0.12", "time 0.3.37", ] @@ -10660,7 +10670,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.99", ] [[package]] @@ -10772,7 +10782,7 @@ dependencies = [ "serde_json", "sha2 0.10.8", "smallvec", - "thiserror 2.0.11", + "thiserror 2.0.12", "time 0.3.37", "tokio", "tokio-stream", @@ -10790,7 +10800,7 @@ dependencies = [ "quote", "sqlx-core", "sqlx-macros-core", - "syn 2.0.98", + "syn 2.0.99", ] [[package]] @@ -10813,7 +10823,7 @@ dependencies = [ "sqlx-mysql", "sqlx-postgres", "sqlx-sqlite", - "syn 2.0.98", + "syn 2.0.99", "tempfile", "tokio", "url", @@ -10827,7 +10837,7 @@ checksum = "4560278f0e00ce64938540546f59f590d60beee33fffbd3b9cd47851e5fff233" dependencies = [ "atoi", "base64 0.22.1", - "bitflags 2.8.0", + "bitflags 2.9.0", "byteorder", "bytes 1.10.0", "crc", @@ -10856,7 +10866,7 @@ dependencies = [ "smallvec", "sqlx-core", "stringprep", - "thiserror 2.0.11", + "thiserror 2.0.12", "time 0.3.37", "tracing", "whoami", @@ -10871,7 +10881,7 @@ dependencies = [ "atoi", "base64 0.22.1", "bit-vec 0.6.3", - "bitflags 2.8.0", + "bitflags 2.9.0", "byteorder", "crc", "dotenvy", @@ -10895,7 +10905,7 @@ dependencies = [ "smallvec", "sqlx-core", "stringprep", - "thiserror 2.0.11", + "thiserror 2.0.12", "time 0.3.37", "tracing", "whoami", @@ -11052,7 +11062,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.98", + "syn 2.0.99", ] [[package]] @@ -11065,7 +11075,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.98", + "syn 2.0.99", ] [[package]] @@ -11227,9 +11237,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.98" +version = "2.0.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36147f1a48ae0ec2b5b3bc5b537d267457555a10dc06f3dbc8cb11ba3006d3b1" +checksum = "e02e925281e18ffd9d640e234264753c43edc62d64b2d4cf898f1bc5e75f3fc2" dependencies = [ "proc-macro2", "quote", @@ -11238,14 +11248,14 @@ dependencies = [ [[package]] name = "syn-solidity" -version = "0.8.21" +version = "0.8.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c2de690018098e367beeb793991c7d4dc7270f42c9d2ac4ccc876c1368ca430" +checksum = "ac9f9798a84bca5cd4d1760db691075fda8f2c3a5d9647e8bfd29eb9b3fabb87" dependencies = [ "paste", "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.99", ] [[package]] @@ -11271,7 +11281,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.99", ] [[package]] @@ -11291,7 +11301,7 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" dependencies = [ - "bitflags 2.8.0", + "bitflags 2.9.0", "core-foundation", "system-configuration-sys 0.6.0", ] @@ -11400,11 +11410,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.11" +version = "2.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d452f284b73e6d76dd36758a0c8684b1d5be31f92b89d07fd5822175732206fc" +checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" dependencies = [ - "thiserror-impl 2.0.11", + "thiserror-impl 2.0.12", ] [[package]] @@ -11415,18 +11425,18 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.99", ] [[package]] name = "thiserror-impl" -version = "2.0.11" +version = "2.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26afc1baea8a989337eeb52b6e72a039780ce45c3edfcc9c5b9d112feeb173c2" +checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.99", ] [[package]] @@ -11644,9 +11654,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.8.1" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "022db8904dfa342efe721985167e9fcd16c29b226db4397ed752a761cfce81e8" +checksum = "09b3661f17e86524eccd4371ab0429194e0d7c008abb45f7a7495b1719463c71" dependencies = [ "tinyvec_macros", ] @@ -11668,7 +11678,7 @@ dependencies = [ "proc-macro2", "quote", "semver 1.0.25", - "syn 2.0.98", + "syn 2.0.99", ] [[package]] @@ -11707,7 +11717,7 @@ checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.99", ] [[package]] @@ -11758,9 +11768,9 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.26.1" +version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f6d0975eaace0cf0fcadee4e4aaa5da15b5c079146f2cffb67c113be122bf37" +checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" dependencies = [ "rustls 0.23.23", "tokio", @@ -11804,7 +11814,7 @@ dependencies = [ "rustls 0.23.23", "rustls-pki-types", "tokio", - "tokio-rustls 0.26.1", + "tokio-rustls 0.26.2", "tungstenite 0.24.0", "webpki-roots 0.26.8", ] @@ -11977,7 +11987,7 @@ checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.99", ] [[package]] @@ -12138,7 +12148,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04659ddb06c87d233c566112c1c9c5b9e98256d9af50ec3bc9c8327f873a7568" dependencies = [ "quote", - "syn 2.0.98", + "syn 2.0.99", ] [[package]] @@ -12149,7 +12159,7 @@ checksum = "70977707304198400eb4835a78f6a9f928bf41bba420deb8fdb175cd965d77a7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.99", ] [[package]] @@ -12398,9 +12408,9 @@ dependencies = [ [[package]] name = "uuid" -version = "1.14.0" +version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93d59ca99a559661b96bf898d8fce28ed87935fd2bea9f05983c1464dd6c71b1" +checksum = "e0f540e3240398cce6128b64ba83fdbdd86129c16a3aa1a3a252efd66eb3d587" [[package]] name = "valuable" @@ -12641,7 +12651,7 @@ dependencies = [ "log", "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.99", "wasm-bindgen-shared", ] @@ -12676,7 +12686,7 @@ checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" dependencies = [ "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.99", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -12835,6 +12845,12 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-link" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dccfd733ce2b1753b03b6d3c65edf020262ea35e20ccdf3e288043e6dd620e3" + [[package]] name = "windows-registry" version = "0.2.0" @@ -13056,7 +13072,7 @@ version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c" dependencies = [ - "bitflags 2.8.0", + "bitflags 2.9.0", ] [[package]] @@ -13084,7 +13100,7 @@ dependencies = [ "crypto-common", "data-encoding", "derive_more 1.0.0", - "derive_more-impl", + "derive_more-impl 1.0.0", "digest 0.10.7", "digest 0.9.0", "displaydoc", @@ -13131,7 +13147,7 @@ dependencies = [ "smallvec", "standback", "subtle", - "syn 2.0.98", + "syn 2.0.99", "time 0.3.37", "tokio", "tokio-util", @@ -13272,7 +13288,7 @@ checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" dependencies = [ "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.99", "synstructure", ] @@ -13288,11 +13304,11 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.20" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dde3bb8c68a8f3f1ed4ac9221aad6b10cece3e60a8e2ea54a6a2dec806d0084c" +checksum = "dcf01143b2dd5d134f11f545cf9f1431b13b749695cb33bcce051e7568f99478" dependencies = [ - "zerocopy-derive 0.8.20", + "zerocopy-derive 0.8.21", ] [[package]] @@ -13303,38 +13319,38 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.99", ] [[package]] name = "zerocopy-derive" -version = "0.8.20" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eea57037071898bf96a6da35fd626f4f27e9cee3ead2a6c703cf09d472b2e700" +checksum = "712c8386f4f4299382c9abee219bee7084f78fb939d88b6840fcc1320d5f6da2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.99", ] [[package]] name = "zerofrom" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e" +checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" dependencies = [ "zerofrom-derive", ] [[package]] name = "zerofrom-derive" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" +checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.99", "synstructure", ] @@ -13355,7 +13371,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.99", ] [[package]] @@ -13377,7 +13393,7 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.99", ] [[package]] diff --git a/hotshot-query-service/src/data_source/storage/sql/transaction.rs b/hotshot-query-service/src/data_source/storage/sql/transaction.rs index efeea128e6..105df2586a 100644 --- a/hotshot-query-service/src/data_source/storage/sql/transaction.rs +++ b/hotshot-query-service/src/data_source/storage/sql/transaction.rs @@ -496,8 +496,13 @@ where // Similarly, we can initialize the payload table with a null payload, which can help us // distinguish between blocks that haven't been produced yet and blocks we haven't received // yet when answering queries. - self.upsert("payload", ["height"], ["height"], [(height as i64,)]) - .await?; + // We don't overwrite the payload if it already exists. + // During epoch transition in PoS, the same height block is sent multiple times. + // The first block may have the payload, but subsequent blocks might be missing it. + // Overwriting would cause the payload to be lost since the block height is the same + let query = query("INSERT INTO payload (height) VALUES ($1) ON CONFLICT DO NOTHING") + .bind(height as i64); + query.execute(self.as_mut()).await?; // Finally, we insert the leaf itself, which references the header row we created. // Serialize the full leaf and QC to JSON for easy storage. diff --git a/hotshot-task-impls/src/consensus/mod.rs b/hotshot-task-impls/src/consensus/mod.rs index 484039f1b0..202e174152 100644 --- a/hotshot-task-impls/src/consensus/mod.rs +++ b/hotshot-task-impls/src/consensus/mod.rs @@ -7,7 +7,6 @@ use async_broadcast::{Receiver, Sender}; use async_lock::RwLock; use async_trait::async_trait; -use either::Either; use hotshot_task::task::TaskState; use hotshot_types::{ consensus::OuterConsensus, @@ -30,8 +29,11 @@ use tracing::instrument; use self::handlers::{ handle_quorum_vote_recv, handle_timeout, handle_timeout_vote_recv, handle_view_change, }; -use crate::helpers::{validate_qc_and_next_epoch_qc, wait_for_next_epoch_qc}; -use crate::{events::HotShotEvent, helpers::broadcast_event, vote_collection::VoteCollectorsMap}; +use crate::{ + events::HotShotEvent, + helpers::{broadcast_event, validate_qc_and_next_epoch_qc}, + vote_collection::VoteCollectorsMap, +}; /// Event handlers for use in the `handle` method. mod handlers; @@ -140,40 +142,14 @@ impl, V: Versions> ConsensusTaskSt tracing::debug!("Failed to handle Timeout event; error = {e}"); } } - HotShotEvent::Qc2Formed(Either::Left(quorum_cert)) => { - let cert_view = quorum_cert.view_number(); - if !self.upgrade_lock.epochs_enabled(cert_view).await { - tracing::debug!("QC2 formed but epochs not enabled. Do nothing"); - return Ok(()); - } - if !self - .consensus - .read() - .await - .is_leaf_extended(quorum_cert.data.leaf_commit) - { - tracing::debug!("We formed QC but not eQC. Do nothing"); - return Ok(()); - } - if wait_for_next_epoch_qc( - quorum_cert, - &self.consensus, - self.timeout, - self.view_start_time, - &receiver, - ) - .await - .is_none() - { - tracing::warn!("We formed eQC but we don't have corresponding next epoch eQC."); - return Ok(()); - } + HotShotEvent::ExtendedQc2Formed(eqc) => { + let cert_view = eqc.view_number(); let cert_block_number = self .consensus .read() .await .saved_leaves() - .get(&quorum_cert.data.leaf_commit) + .get(&eqc.data.leaf_commit) .context(error!( "Could not find the leaf for the eQC. It shouldn't happen." ))? diff --git a/hotshot-task-impls/src/events.rs b/hotshot-task-impls/src/events.rs index e34f856476..a1e828f27a 100644 --- a/hotshot-task-impls/src/events.rs +++ b/hotshot-task-impls/src/events.rs @@ -135,6 +135,8 @@ pub enum HotShotEvent { Qc2Formed(Either, TimeoutCertificate2>), /// The next leader has collected enough votes from the next epoch nodes to form a QC; emitted by the next leader in the consensus task; an internal event only NextEpochQc2Formed(Either, TimeoutCertificate>), + /// A validator formed both a current epoch eQC and a next epoch eQC + ExtendedQc2Formed(QuorumCertificate2), /// The DA leader has collected enough votes to form a DAC; emitted by the DA leader in the DA task; sent to the entire network via the networking task DacSend(DaCertificate2, TYPES::SignatureKey), /// The current view has changed; emitted by the replica in the consensus task or replica in the view sync task; received by almost all other tasks @@ -312,6 +314,7 @@ impl HotShotEvent { either::Left(qc) => Some(qc.view_number()), either::Right(tc) => Some(tc.view_number()), }, + HotShotEvent::ExtendedQc2Formed(cert) => Some(cert.view_number()), HotShotEvent::ViewSyncCommitVoteSend(vote) | HotShotEvent::ViewSyncCommitVoteRecv(vote) => Some(vote.view_number()), HotShotEvent::ViewSyncPreCommitVoteRecv(vote) @@ -447,6 +450,9 @@ impl Display for HotShotEvent { write!(f, "NextEpochQc2Formed(view_number={:?})", tc.view_number()) } }, + HotShotEvent::ExtendedQc2Formed(cert) => { + write!(f, "ExtendedQc2Formed(view_number={:?})", cert.view_number()) + } HotShotEvent::DacSend(cert, _) => { write!(f, "DacSend(view_number={:?})", cert.view_number()) } diff --git a/hotshot-task-impls/src/quorum_proposal/handlers.rs b/hotshot-task-impls/src/quorum_proposal/handlers.rs index c0796c26e0..fc5577c912 100644 --- a/hotshot-task-impls/src/quorum_proposal/handlers.rs +++ b/hotshot-task-impls/src/quorum_proposal/handlers.rs @@ -13,10 +13,15 @@ use std::{ time::{Duration, Instant}, }; +use crate::{ + events::HotShotEvent, + helpers::{broadcast_event, parent_leaf_and_state, wait_for_next_epoch_qc}, + quorum_proposal::{QuorumProposalTaskState, UpgradeLock, Versions}, +}; use anyhow::{ensure, Context, Result}; use async_broadcast::{Receiver, Sender}; use async_lock::RwLock; -use committable::Committable; +use committable::{Commitment, Committable}; use hotshot_task::dependency_task::HandleDepOutput; use hotshot_types::{ consensus::{CommitmentAndMetadata, OuterConsensus}, @@ -24,7 +29,9 @@ use hotshot_types::{ message::Proposal, simple_certificate::{QuorumCertificate2, UpgradeCertificate}, traits::{ - block_contents::BlockHeader, election::Membership, node_implementation::NodeType, + block_contents::BlockHeader, + election::Membership, + node_implementation::{NodeImplementation, NodeType}, signature_key::SignatureKey, }, utils::{is_last_block_in_epoch, option_epoch_from_block_number}, @@ -35,12 +42,6 @@ use hotshot_utils::anytrace::*; use tracing::instrument; use vbs::version::StaticVersionType; -use crate::{ - events::HotShotEvent, - helpers::{broadcast_event, parent_leaf_and_state, wait_for_next_epoch_qc}, - quorum_proposal::{UpgradeLock, Versions}, -}; - /// Proposal dependency types. These types represent events that precipitate a proposal. #[derive(PartialEq, Debug)] pub(crate) enum ProposalDependency { @@ -500,3 +501,51 @@ impl HandleDepOutput for ProposalDependencyHandle< } } } + +pub(super) async fn handle_eqc_formed< + TYPES: NodeType, + I: NodeImplementation, + V: Versions, +>( + cert_view: TYPES::View, + leaf_commit: Commitment>, + task_state: &QuorumProposalTaskState, + event_sender: &Sender>>, +) { + if !task_state.upgrade_lock.epochs_enabled(cert_view).await { + tracing::debug!("QC2 formed but epochs not enabled. Do nothing"); + return; + } + if !task_state + .consensus + .read() + .await + .is_leaf_extended(leaf_commit) + { + tracing::debug!("We formed QC but not eQC. Do nothing"); + return; + } + + let consensus_reader = task_state.consensus.read().await; + let current_epoch_qc = consensus_reader.high_qc(); + let Some(next_epoch_qc) = consensus_reader.next_epoch_high_qc() else { + tracing::debug!("We formed the eQC but we don't have the next epoch eQC at all."); + return; + }; + if current_epoch_qc.view_number() != next_epoch_qc.view_number() + || current_epoch_qc.data != *next_epoch_qc.data + { + tracing::debug!( + "We formed the eQC but the current and next epoch QCs do not correspond to each other." + ); + return; + } + let current_epoch_qc_clone = current_epoch_qc.clone(); + drop(consensus_reader); + + broadcast_event( + Arc::new(HotShotEvent::ExtendedQc2Formed(current_epoch_qc_clone)), + event_sender, + ) + .await; +} diff --git a/hotshot-task-impls/src/quorum_proposal/mod.rs b/hotshot-task-impls/src/quorum_proposal/mod.rs index c5bcc1bc00..bfbebe5a57 100644 --- a/hotshot-task-impls/src/quorum_proposal/mod.rs +++ b/hotshot-task-impls/src/quorum_proposal/mod.rs @@ -35,6 +35,7 @@ use tracing::instrument; use self::handlers::{ProposalDependency, ProposalDependencyHandle}; use crate::events::HotShotEvent; +use crate::quorum_proposal::handlers::handle_eqc_formed; mod handlers; @@ -437,6 +438,10 @@ impl, V: Versions> .await .wrap() .context(error!("Failed to update high QC in storage!"))?; + + handle_eqc_formed(qc.view_number(), qc.data.leaf_commit, self, &event_sender) + .await; + let view_number = qc.view_number() + 1; self.create_dependency_task_if_new( view_number, @@ -598,6 +603,14 @@ impl, V: Versions> .await .wrap() .context(error!("Failed to update next epoch high QC in storage!"))?; + + handle_eqc_formed( + next_epoch_qc.view_number(), + next_epoch_qc.data.leaf_commit, + self, + &event_sender, + ) + .await; } _ => {} } diff --git a/hotshot-testing/tests/tests_6/test_epochs.rs b/hotshot-testing/tests/tests_6/test_epochs.rs index 686ea8f6ab..718ab21310 100644 --- a/hotshot-testing/tests/tests_6/test_epochs.rs +++ b/hotshot-testing/tests/tests_6/test_epochs.rs @@ -491,54 +491,54 @@ cross_tests!( } ); -cross_tests!( - TestName: test_all_restart_epochs, - Impls: [CombinedImpl, PushCdnImpl], - Types: [TestTypes, TestTypesRandomizedLeader, TestTwoStakeTablesTypes], - Versions: [EpochsTestVersions], - Ignore: false, - Metadata: { - let timing_data = TimingData { - next_view_timeout: 2000, - ..Default::default() - }; - let mut metadata = TestDescription::default().set_num_nodes(20,20); - let mut catchup_nodes = vec![]; - - for i in 0..20 { - catchup_nodes.push(ChangeNode { - idx: i, - updown: NodeAction::RestartDown(0), - }) - } - - metadata.timing_data = timing_data; - - metadata.spinning_properties = SpinningTaskDescription { - // Restart all the nodes in view 10 - node_changes: vec![(10, catchup_nodes)], - }; - metadata.view_sync_properties = - hotshot_testing::view_sync_task::ViewSyncTaskDescription::Threshold(0, 20); - - metadata.completion_task_description = - CompletionTaskDescription::TimeBasedCompletionTaskBuilder( - TimeBasedCompletionTaskDescription { - duration: Duration::from_secs(60), - }, - ); - metadata.overall_safety_properties = OverallSafetyPropertiesDescription { - // Make sure we keep committing rounds after the catchup, but not the full 50. - num_successful_views: 22, - expected_view_failures: vec![10], - possible_view_failures: vec![9, 11], - decide_timeout: Duration::from_secs(20), - ..Default::default() - }; - - metadata - }, -); +// cross_tests!( +// TestName: test_all_restart_epochs, +// Impls: [CombinedImpl, PushCdnImpl], +// Types: [TestTypes, TestTypesRandomizedLeader, TestTwoStakeTablesTypes], +// Versions: [EpochsTestVersions], +// Ignore: false, +// Metadata: { +// let timing_data = TimingData { +// next_view_timeout: 2000, +// ..Default::default() +// }; +// let mut metadata = TestDescription::default().set_num_nodes(20,20); +// let mut catchup_nodes = vec![]; +// +// for i in 0..20 { +// catchup_nodes.push(ChangeNode { +// idx: i, +// updown: NodeAction::RestartDown(0), +// }) +// } +// +// metadata.timing_data = timing_data; +// +// metadata.spinning_properties = SpinningTaskDescription { +// // Restart all the nodes in view 10 +// node_changes: vec![(10, catchup_nodes)], +// }; +// metadata.view_sync_properties = +// hotshot_testing::view_sync_task::ViewSyncTaskDescription::Threshold(0, 20); +// +// metadata.completion_task_description = +// CompletionTaskDescription::TimeBasedCompletionTaskBuilder( +// TimeBasedCompletionTaskDescription { +// duration: Duration::from_secs(60), +// }, +// ); +// metadata.overall_safety_properties = OverallSafetyPropertiesDescription { +// // Make sure we keep committing rounds after the catchup, but not the full 50. +// num_successful_views: 22, +// expected_view_failures: vec![10], +// possible_view_failures: vec![9, 11], +// decide_timeout: Duration::from_secs(20), +// ..Default::default() +// }; +// +// metadata +// }, +// ); cross_tests!( TestName: test_all_restart_one_da_with_epochs, diff --git a/request-response/Cargo.toml b/request-response/Cargo.toml index 4760053dff..3c45aec7e3 100644 --- a/request-response/Cargo.toml +++ b/request-response/Cargo.toml @@ -14,7 +14,6 @@ async-trait = { workspace = true } bincode = { workspace = true } blake3 = { workspace = true } byteorder = { version = "1", default-features = false } -derive_builder = { workspace = true } derive_more = { workspace = true } hotshot-types = { workspace = true } parking_lot = { workspace = true } diff --git a/request-response/src/lib.rs b/request-response/src/lib.rs index d643547ba6..d2cd58221b 100644 --- a/request-response/src/lib.rs +++ b/request-response/src/lib.rs @@ -10,7 +10,6 @@ use std::{ use anyhow::{anyhow, Context, Result}; use data_source::DataSource; -use derive_builder::Builder; use derive_more::derive::Deref; use hotshot_types::traits::signature_key::SignatureKey; use message::{Message, RequestMessage, ResponseMessage}; @@ -87,39 +86,39 @@ pub trait Serializable: Sized { } /// The underlying configuration for the request-response protocol -#[derive(Clone, Builder)] +#[derive(Clone)] pub struct RequestResponseConfig { /// The timeout for incoming requests. Do not respond to a request after this threshold /// has passed. - incoming_request_ttl: Duration, + pub incoming_request_ttl: Duration, /// The maximum amount of time we will spend trying to both derive a response for a request and /// send the response over the wire. - response_send_timeout: Duration, + pub response_send_timeout: Duration, /// The maximum amount of time we will spend trying to validate a response. This is used to prevent /// an attack where a malicious participant sends us a bunch of requests that take a long time to /// validate. - response_validate_timeout: Duration, + pub response_validate_timeout: Duration, /// The batch size for outgoing requests. This is the number of request messages that we will /// send out at a time for a single request before waiting for the [`request_batch_interval`]. - request_batch_size: usize, + pub request_batch_size: usize, /// The time to wait (per request) between sending out batches of request messages - request_batch_interval: Duration, + pub request_batch_interval: Duration, /// The maximum (global) number of outgoing responses that can be in flight at any given time - max_outgoing_responses: usize, + pub max_outgoing_responses: usize, /// The maximum (global) number of incoming responses that can be processed at any given time. /// We need this because responses coming in need to be validated [asynchronously] that they /// satisfy the request they are responding to - max_incoming_responses: usize, + pub max_incoming_responses: usize, } /// A protocol that allows for request-response communication. Is cheaply cloneable, so there is no /// need to wrap it in an `Arc` -#[derive(Clone, Deref)] +#[derive(Deref)] pub struct RequestResponse< S: Sender, R: Receiver, Req: Request, - RS: RecipientSource, + RS: RecipientSource, DS: DataSource, K: SignatureKey + 'static, > { @@ -130,11 +129,30 @@ pub struct RequestResponse< _receiving_task_handle: Arc>, } +/// We need to manually implement the `Clone` trait for this type because deriving +/// `Deref` will cause an issue where it tries to clone the inner field instead +impl< + S: Sender, + R: Receiver, + Req: Request, + RS: RecipientSource, + DS: DataSource, + K: SignatureKey + 'static, + > Clone for RequestResponse +{ + fn clone(&self) -> Self { + Self { + inner: Arc::clone(&self.inner), + _receiving_task_handle: Arc::clone(&self._receiving_task_handle), + } + } +} + impl< S: Sender, R: Receiver, Req: Request, - RS: RecipientSource, + RS: RecipientSource, DS: DataSource, K: SignatureKey + 'static, > RequestResponse @@ -186,14 +204,14 @@ pub struct RequestResponseInner< S: Sender, R: Receiver, Req: Request, - RS: RecipientSource, + RS: RecipientSource, DS: DataSource, K: SignatureKey + 'static, > { /// The configuration of the protocol config: RequestResponseConfig, /// The sender to use for the protocol - sender: S, + pub sender: S, /// The recipient source to use for the protocol recipient_source: RS, /// The data source to use for the protocol @@ -207,7 +225,7 @@ impl< S: Sender, R: Receiver, Req: Request, - RS: RecipientSource, + RS: RecipientSource, DS: DataSource, K: SignatureKey + 'static, > RequestResponseInner @@ -303,7 +321,7 @@ impl< // that we don't always send to the same recipients in the same order let mut recipients = self .recipient_source - .get_recipients_for(&request_message.request) + .get_expected_responders(&request_message.request) .await; recipients.shuffle(&mut rand::thread_rng()); @@ -617,8 +635,8 @@ mod tests { // Implement the [`RecipientSource`] trait for the [`TestSender`] type #[async_trait] - impl RecipientSource for TestSender { - async fn get_recipients_for(&self, _request: &R) -> Vec { + impl RecipientSource for TestSender { + async fn get_expected_responders(&self, _request: &TestRequest) -> Vec { // Get all the participants in the network self.network.keys().copied().collect() } @@ -671,14 +689,14 @@ mod tests { } #[async_trait] - impl DataSource> for TestDataSource { - async fn derive_response_for(&self, request: &Vec) -> Result> { + impl DataSource for TestDataSource { + async fn derive_response_for(&self, request: &TestRequest) -> Result> { // Return a response if we hit the hit rate if self.has_data && Instant::now() >= self.data_available_time { if self.take_data && !self.taken.swap(true, std::sync::atomic::Ordering::Relaxed) { return Err(anyhow::anyhow!("data already taken")); } - Ok(blake3::hash(request).as_bytes().to_vec()) + Ok(blake3::hash(&request.0).as_bytes().to_vec()) } else { Err(anyhow::anyhow!("did not have the data")) } @@ -687,16 +705,15 @@ mod tests { /// Create and return a default protocol configuration fn default_protocol_config() -> RequestResponseConfig { - RequestResponseConfigBuilder::create_empty() - .incoming_request_ttl(Duration::from_secs(40)) - .response_send_timeout(Duration::from_secs(40)) - .request_batch_size(10) - .request_batch_interval(Duration::from_millis(100)) - .max_outgoing_responses(10) - .response_validate_timeout(Duration::from_secs(1)) - .max_incoming_responses(5) - .build() - .expect("failed to build config") + RequestResponseConfig { + incoming_request_ttl: Duration::from_secs(40), + response_send_timeout: Duration::from_secs(40), + request_batch_size: 10, + request_batch_interval: Duration::from_millis(100), + max_outgoing_responses: 10, + response_validate_timeout: Duration::from_secs(1), + max_incoming_responses: 5, + } } /// Create fully connected test networks with `num_participants` participants @@ -805,10 +822,10 @@ mod tests { .push(Arc::clone(&protocol._receiving_task_handle)); // Create a random request - let request = vec![rand::thread_rng().gen(); 100]; + let request = TestRequest(vec![rand::thread_rng().gen(); 100]); // Get the hash of the request - let request_hash = blake3::hash(&request).as_bytes().to_vec(); + let request_hash = blake3::hash(&request.0).as_bytes().to_vec(); // Create a new request message let request = RequestMessage::new_signed(&public_key, &private_key, &request) @@ -924,7 +941,7 @@ mod tests { let one = Arc::new(participants.remove(0)); // Create the request that they should all be able to join on - let request = vec![rand::thread_rng().gen(); 100]; + let request = TestRequest(vec![rand::thread_rng().gen(); 100]); // Create a join set to wait for all the tasks to finish let mut join_set = JoinSet::new(); diff --git a/request-response/src/recipient_source.rs b/request-response/src/recipient_source.rs index 49da07a2a2..bfc65d1348 100644 --- a/request-response/src/recipient_source.rs +++ b/request-response/src/recipient_source.rs @@ -7,7 +7,7 @@ use super::request::Request; /// expect responses from. In `HotShot` this would go on top of the [`Membership`] trait and determine /// which nodes are able (quorum/DA) to respond to which requests #[async_trait] -pub trait RecipientSource: Send + Sync + 'static { +pub trait RecipientSource: Send + Sync + 'static { /// Get all the recipients that the specific request should expect responses from - async fn get_recipients_for(&self, request: &R) -> Vec; + async fn get_expected_responders(&self, request: &R) -> Vec; } diff --git a/request-response/src/request.rs b/request-response/src/request.rs index 87bc466452..5d7589e8d5 100644 --- a/request-response/src/request.rs +++ b/request-response/src/request.rs @@ -24,6 +24,18 @@ pub trait Request: Send + Sync + Serializable + 'static + Clone + Debug { /// A trait that a response needs to implement #[async_trait] +#[cfg(not(test))] +pub trait Response: Send + Sync + Serializable + Clone + Debug { + /// Validate the response, making sure it is valid for the given request + /// + /// # Errors + /// If the response is not valid for the given request + async fn validate(&self, request: &R) -> Result<()>; +} + +/// A trait that a response needs to implement +#[async_trait] +#[cfg(test)] pub trait Response: Send + Sync + Serializable + Clone + Debug + PartialEq + Eq { diff --git a/sequencer-sqlite/Cargo.lock b/sequencer-sqlite/Cargo.lock index c0707fca30..1d9cb79e6d 100644 --- a/sequencer-sqlite/Cargo.lock +++ b/sequencer-sqlite/Cargo.lock @@ -8726,6 +8726,26 @@ dependencies = [ "bytecheck", ] +[[package]] +name = "request-response" +version = "0.1.0" +dependencies = [ + "anyhow", + "async-broadcast", + "async-trait", + "bincode", + "blake3", + "byteorder", + "derive_more 1.0.0", + "hotshot-types", + "parking_lot", + "rand 0.8.5", + "thiserror 1.0.69", + "tokio", + "tokio-util", + "tracing", +] + [[package]] name = "reqwest" version = "0.11.27" @@ -9453,6 +9473,7 @@ dependencies = [ "async-once-cell", "async-trait", "bincode", + "byteorder", "cdn-broker 0.4.0 (git+https://github.com/EspressoSystems/Push-CDN?tag=0.5.1-upgrade)", "cdn-marshal 0.4.0 (git+https://github.com/EspressoSystems/Push-CDN?tag=0.5.1-upgrade)", "clap", @@ -9492,6 +9513,7 @@ dependencies = [ "rand 0.8.5", "rand_chacha 0.3.1", "rand_distr", + "request-response", "sequencer-utils", "serde", "serde_json", diff --git a/sequencer/Cargo.toml b/sequencer/Cargo.toml index 0bca424833..1c5d9b5347 100644 --- a/sequencer/Cargo.toml +++ b/sequencer/Cargo.toml @@ -52,6 +52,7 @@ async-lock = { workspace = true } async-once-cell = { workspace = true } async-trait = { workspace = true } bincode = { workspace = true } +byteorder = "1" # CDN imports cdn-broker = { git = "https://github.com/EspressoSystems/Push-CDN", tag = "0.5.1-upgrade", package = "cdn-broker", features = ["global-permits"] } @@ -101,6 +102,7 @@ priority-queue = { workspace = true } rand = { workspace = true } rand_chacha = { workspace = true } rand_distr = { workspace = true } +request-response = { path = "../request-response" } sequencer-utils = { path = "../utils" } serde = { workspace = true } serde_json = { workspace = true } diff --git a/sequencer/src/context.rs b/sequencer/src/context.rs index b56c0b6eb0..9b69947f73 100644 --- a/sequencer/src/context.rs +++ b/sequencer/src/context.rs @@ -27,15 +27,24 @@ use hotshot_types::{ PeerConfig, ValidatorConfig, }; use parking_lot::Mutex; -use std::fmt::Debug; +use request_response::{network::Bytes, RequestResponse, RequestResponseConfig}; +use std::{fmt::Debug, time::Duration}; use std::{fmt::Display, sync::Arc}; -use tokio::{spawn, task::JoinHandle}; +use tokio::{ + spawn, + sync::mpsc::{channel, Receiver}, + task::JoinHandle, +}; use tracing::{Instrument, Level}; use url::Url; use crate::{ - external_event_handler::{self, ExternalEventHandler}, + external_event_handler::ExternalEventHandler, proposal_fetcher::ProposalFetcherConfig, + request_response::{ + data_source::DataSource, network::Sender as RequestResponseSender, + recipient_source::RecipientSource, request::Request, + }, state_signature::StateSigner, static_stake_table_commitment, Node, SeqTypes, SequencerApiVersion, }; @@ -51,6 +60,18 @@ pub struct SequencerContext, P: SequencerPersistence #[derivative(Debug = "ignore")] handle: Arc>>, + /// The request-response protocol + #[derivative(Debug = "ignore")] + #[allow(dead_code)] + request_response_protocol: RequestResponse< + RequestResponseSender, + Receiver, + Request, + RecipientSource, + DataSource, + PubKey, + >, + /// Context for generating state signatures. state_signer: Arc>, @@ -87,7 +108,6 @@ impl, P: SequencerPersistence, V: Versions> Sequence state_relay_server: Option, metrics: &dyn Metrics, stake_table_capacity: u64, - public_api_url: Option, event_consumer: impl PersistenceEventConsumer + 'static, _: V, marketplace_config: MarketplaceConfig>, @@ -124,13 +144,14 @@ impl, P: SequencerPersistence, V: Versions> Sequence ))); let persistence = Arc::new(persistence); + let memberships = Arc::new(async_lock::RwLock::new(membership)); let handle = SystemContext::init( validator_config.public_key, validator_config.private_key.clone(), instance_state.node_id, config.clone(), - Arc::new(async_lock::RwLock::new(membership)), + memberships.clone(), network.clone(), initializer, ConsensusMetricsValue::new(metrics), @@ -145,21 +166,49 @@ impl, P: SequencerPersistence, V: Versions> Sequence state_signer = state_signer.with_relay_server(url); } - // Create the roll call info we will be using - let roll_call_info = external_event_handler::RollCallInfo { public_api_url }; + // Create the channel for sending outbound messages from the external event handler + let (outbound_message_sender, outbound_message_receiver) = channel(10); + let (request_response_sender, request_response_receiver) = channel(10); + + // Configure the request-response protocol + let request_response_config = RequestResponseConfig { + incoming_request_ttl: Duration::from_secs(40), + response_send_timeout: Duration::from_secs(5), + request_batch_size: 10, + request_batch_interval: Duration::from_secs(3), + max_outgoing_responses: 10, + response_validate_timeout: Duration::from_secs(1), + max_incoming_responses: 5, + }; + + // Create the request-response protocol + let request_response_protocol = RequestResponse::new( + request_response_config, + RequestResponseSender::new(outbound_message_sender), + request_response_receiver, + RecipientSource { memberships }, + DataSource {}, + ); // Create the external event handler let mut tasks = TaskList::default(); - let external_event_handler = - ExternalEventHandler::new(&mut tasks, network, roll_call_info, pub_key) - .await - .with_context(|| "Failed to create external event handler")?; + let external_event_handler = ExternalEventHandler::::new( + &mut tasks, + request_response_sender, + outbound_message_receiver, + network, + pub_key, + handle.hotshot.upgrade_lock.clone(), + ) + .await + .with_context(|| "Failed to create external event handler")?; Ok(Self::new( handle, persistence, state_signer, external_event_handler, + request_response_protocol, event_streamer, instance_state, network_config, @@ -179,6 +228,14 @@ impl, P: SequencerPersistence, V: Versions> Sequence persistence: Arc

, state_signer: StateSigner, external_event_handler: ExternalEventHandler, + request_response_protocol: RequestResponse< + RequestResponseSender, + Receiver, + Request, + RecipientSource, + DataSource, + PubKey, + >, event_streamer: Arc>>, node_state: NodeState, network_config: NetworkConfig, @@ -194,6 +251,7 @@ impl, P: SequencerPersistence, V: Versions> Sequence let mut ctx = Self { handle: Arc::new(RwLock::new(handle)), state_signer: Arc::new(state_signer), + request_response_protocol, tasks: Default::default(), detached: false, wait_for_orchestrator: None, diff --git a/sequencer/src/external_event_handler.rs b/sequencer/src/external_event_handler.rs index bcf5f9e23d..86659f946f 100644 --- a/sequencer/src/external_event_handler.rs +++ b/sequencer/src/external_event_handler.rs @@ -3,94 +3,67 @@ use crate::context::TaskList; use anyhow::{Context, Result}; use espresso_types::{PubKey, SeqTypes}; -use hotshot::types::{BLSPubKey, Message}; +use hotshot::types::Message; use hotshot_types::{ - message::MessageKind, + message::{MessageKind, UpgradeLock}, traits::{ network::{BroadcastDelay, ConnectedNetwork, Topic}, node_implementation::Versions, }, }; +use request_response::network::Bytes; use serde::{Deserialize, Serialize}; use std::{marker::PhantomData, sync::Arc}; -use tokio::sync::mpsc::channel; use tokio::sync::mpsc::{Receiver, Sender}; -use url::Url; /// An external message that can be sent to or received from a node #[derive(Debug, Serialize, Deserialize, Clone)] pub enum ExternalMessage { - /// A request for a node to respond with its identifier - /// Contains the public key of the node that is requesting the roll call - RollCallRequest(BLSPubKey), - - /// A response to a roll call request - /// Contains the identifier of the node - RollCallResponse(RollCallInfo), -} - -/// Information about a node that is used in a roll call response -#[derive(Debug, Serialize, Deserialize, Clone)] -pub struct RollCallInfo { - // The public API URL of the node - pub public_api_url: Option, + RequestResponse(Vec), } -/// The external event handler state +/// The external event handler +#[derive(Clone)] pub struct ExternalEventHandler { - // The `RollCallInfo` of the node (used in the roll call response) - pub roll_call_info: RollCallInfo, + /// The sender to the request-response protocol + request_response_sender: Sender, - // The public key of the node - pub public_key: BLSPubKey, - - // The outbound message queue - pub outbound_message_sender: Sender, - - _pd: PhantomData, + /// The type phantom + phantom: PhantomData, } // The different types of outbound messages (broadcast or direct) #[derive(Debug)] +#[allow(dead_code)] pub enum OutboundMessage { - Direct(Vec, PubKey), - Broadcast(Vec), + Direct(MessageKind, PubKey), + Broadcast(MessageKind), } impl ExternalEventHandler { - /// Creates a new `ExternalEventHandler` with the given network and roll call info + /// Creates a new `ExternalEventHandler` with the given network pub async fn new>( tasks: &mut TaskList, + request_response_sender: Sender, + outbound_message_receiver: Receiver, network: Arc, - roll_call_info: RollCallInfo, - public_key: BLSPubKey, + public_key: PubKey, + hotshot_upgrade_lock: UpgradeLock, ) -> Result { - // Create the outbound message queue - let (outbound_message_sender, outbound_message_receiver) = channel(10); - // Spawn the outbound message handling loop tasks.spawn( - "ExternalEventHandler (RollCall)", - Self::outbound_message_loop(outbound_message_receiver, network), + "ExternalEventHandler", + Self::outbound_message_loop( + outbound_message_receiver, + network, + public_key, + hotshot_upgrade_lock, + ), ); - // We just started, so queue an outbound RollCall message (if we have a public API URL) - if roll_call_info.public_api_url.is_some() { - let roll_call_message_bytes = - Self::create_roll_call_response(&public_key, &roll_call_info) - .await - .with_context(|| "Failed to create roll call response for initial broadcast")?; - - outbound_message_sender - .try_send(OutboundMessage::Broadcast(roll_call_message_bytes)) - .with_context(|| "External outbound message queue is somehow full")?; - } - Ok(Self { - roll_call_info, - public_key, - outbound_message_sender, - _pd: Default::default(), + request_response_sender, + phantom: PhantomData, }) } @@ -105,73 +78,67 @@ impl ExternalEventHandler { // Match the type match external_message { - ExternalMessage::RollCallRequest(pub_key) => { - if self.roll_call_info.public_api_url.is_none() { - // We don't have a public API URL, so we can't respond to the roll call - return Ok(()); - } - - let response_bytes = - Self::create_roll_call_response(&self.public_key, &self.roll_call_info) - .await - .with_context(|| { - "Failed to serialize roll call response for RollCallRequest" - })?; - - // Send the response - self.outbound_message_sender - .try_send(OutboundMessage::Direct(response_bytes, pub_key)) - .with_context(|| "External outbound message queue is full")?; - } - - _ => { - return Err(anyhow::anyhow!("Unknown external message type")); + ExternalMessage::RequestResponse(request_response) => { + // Send the inner message to the request-response protocol + self.request_response_sender + .send(request_response.into()) + .await?; } } Ok(()) } - /// Creates a roll call response message - async fn create_roll_call_response( - public_key: &BLSPubKey, - roll_call_info: &RollCallInfo, - ) -> Result> { - let response = ExternalMessage::RollCallResponse(roll_call_info.clone()); - - // Serialize the response - let response_bytes = bincode::serialize(&response) - .with_context(|| "Failed to serialize roll call response")?; - - let message = Message:: { - sender: *public_key, - kind: MessageKind::::External(response_bytes), - }; - - let response_bytes = bincode::serialize(&message) - .with_context(|| "Failed to serialize roll call response")?; - - Ok(response_bytes) - } - /// The main loop for sending outbound messages. async fn outbound_message_loop>( mut receiver: Receiver, network: Arc, + public_key: PubKey, + hotshot_upgrade_lock: UpgradeLock, ) { while let Some(message) = receiver.recv().await { // Match the message type match message { OutboundMessage::Direct(message, recipient) => { - // Send the message directly to the recipient - if let Err(err) = network.direct_message(message, recipient).await { + // Wrap it in the real message type + let message_inner = Message { + sender: public_key, + kind: message, + }; + + // Serialize it + let message_bytes = match hotshot_upgrade_lock.serialize(&message_inner).await { + Ok(message_bytes) => message_bytes, + Err(err) => { + tracing::warn!("Failed to serialize direct message: {}", err); + continue; + } + }; + + // Send the message to the recipient + if let Err(err) = network.direct_message(message_bytes, recipient).await { tracing::error!("Failed to send message: {:?}", err); }; } OutboundMessage::Broadcast(message) => { + // Wrap it in the real message type + let message_inner = Message { + sender: public_key, + kind: message, + }; + + // Serialize it + let message_bytes = match hotshot_upgrade_lock.serialize(&message_inner).await { + Ok(message_bytes) => message_bytes, + Err(err) => { + tracing::warn!("Failed to serialize broadcast message: {}", err); + continue; + } + }; + // Broadcast the message to the global topic if let Err(err) = network - .broadcast_message(message, Topic::Global, BroadcastDelay::None) + .broadcast_message(message_bytes, Topic::Global, BroadcastDelay::None) .await { tracing::error!("Failed to broadcast message: {:?}", err); diff --git a/sequencer/src/lib.rs b/sequencer/src/lib.rs index 9a041f6935..8081d04b9c 100644 --- a/sequencer/src/lib.rs +++ b/sequencer/src/lib.rs @@ -3,6 +3,7 @@ pub mod catchup; pub mod context; pub mod genesis; mod proposal_fetcher; +mod request_response; mod external_event_handler; pub mod options; @@ -541,7 +542,6 @@ pub async fn init_node( Some(network_params.state_relay_server_url), metrics, genesis.stake_table.capacity, - network_params.public_api_url, event_consumer, seq_versions, marketplace_config, @@ -1005,7 +1005,6 @@ pub mod testing { self.state_relay_url.clone(), metrics, stake_table_capacity, - None, // The public API URL event_consumer, bind_version, MarketplaceConfig::> { diff --git a/sequencer/src/request_response/data_source.rs b/sequencer/src/request_response/data_source.rs new file mode 100644 index 0000000000..df7476677e --- /dev/null +++ b/sequencer/src/request_response/data_source.rs @@ -0,0 +1,21 @@ +//! This file contains the [`DataSource`] trait. This trait allows the [`RequestResponseProtocol`] +//! to calculate/derive a response for a specific request. In the confirmation layer the implementer +//! would be something like a [`FeeMerkleTree`] for fee catchup + +use super::request::{Request, Response}; +use anyhow::Result; +use async_trait::async_trait; +use request_response::data_source::DataSource as DataSourceTrait; + +#[derive(Clone, Debug)] +pub struct DataSource {} + +/// Implement the trait that allows the [`RequestResponseProtocol`] to calculate/derive a response for a specific request +#[async_trait] +impl DataSourceTrait for DataSource { + async fn derive_response_for(&self, request: &Request) -> Result { + match request { + Request::Example => Ok(Response::Example), + } + } +} diff --git a/sequencer/src/request_response/mod.rs b/sequencer/src/request_response/mod.rs new file mode 100644 index 0000000000..fb75070a97 --- /dev/null +++ b/sequencer/src/request_response/mod.rs @@ -0,0 +1,4 @@ +pub mod data_source; +pub mod network; +pub mod recipient_source; +pub mod request; diff --git a/sequencer/src/request_response/network.rs b/sequencer/src/request_response/network.rs new file mode 100644 index 0000000000..38a80b2621 --- /dev/null +++ b/sequencer/src/request_response/network.rs @@ -0,0 +1,41 @@ +use crate::external_event_handler::ExternalMessage; +use crate::external_event_handler::OutboundMessage; +use anyhow::{Context, Result}; +use async_trait::async_trait; +use espresso_types::PubKey; +use espresso_types::SeqTypes; +use hotshot_types::message::MessageKind; +use request_response::network::Bytes; +use request_response::network::Sender as SenderTrait; +use tokio::sync::mpsc; + +/// A wrapper type that we will implement the `Sender` trait for +#[derive(Clone)] +pub struct Sender(mpsc::Sender); + +impl Sender { + pub fn new(sender: mpsc::Sender) -> Self { + Self(sender) + } +} + +/// Implement the `Sender` trait for the `RequestResponseSender` type. This tells +/// the request response protocol how to send messages to other nodes. +#[async_trait] +impl SenderTrait for Sender { + async fn send_message(&self, message: &Bytes, recipient: PubKey) -> Result<()> { + // Serialize the inner message + let message_bytes = bincode::serialize(&ExternalMessage::RequestResponse(message.to_vec())) + .with_context(|| "failed to serialize message")?; + + // Send the message + self.0 + .send(OutboundMessage::Direct( + MessageKind::External::(message_bytes), + recipient, + )) + .await + .with_context(|| "failed to send message over channel")?; + Ok(()) + } +} diff --git a/sequencer/src/request_response/recipient_source.rs b/sequencer/src/request_response/recipient_source.rs new file mode 100644 index 0000000000..a0dcbbd69d --- /dev/null +++ b/sequencer/src/request_response/recipient_source.rs @@ -0,0 +1,44 @@ +use std::sync::Arc; + +use async_lock::RwLock; +use async_trait::async_trait; +use espresso_types::{PubKey, SeqTypes}; +use hotshot_types::{ + data::EpochNumber, + traits::{ + election::Membership, + node_implementation::{ConsensusTime, NodeType}, + }, +}; +use request_response::recipient_source::RecipientSource as RecipientSourceTrait; + +use super::request::Request; + +#[derive(Clone, Debug)] +pub struct RecipientSource { + pub memberships: Arc::Membership>>, +} + +/// Implement the RecipientSourceTrait, which allows the request-response protocol to derive the +/// intended recipients for a given request +#[async_trait] +impl RecipientSourceTrait for RecipientSource { + async fn get_expected_responders(&self, request: &Request) -> Vec { + match request { + Request::Example => { + // Get the memberships + let memberships = self.memberships.read().await; + + // Get everyone in the stake table + + // NOTE: This is just an example request, therefore this is hardcoded to get members of epoch 0. + // When doing a real request, please choose the appropriate epoch to get members from. + memberships + .stake_table(Some(EpochNumber::new(0))) + .iter() + .map(|entry| entry.stake_table_entry.stake_key) + .collect() + } + } + } +} diff --git a/sequencer/src/request_response/request.rs b/sequencer/src/request_response/request.rs new file mode 100644 index 0000000000..ebb463a8ce --- /dev/null +++ b/sequencer/src/request_response/request.rs @@ -0,0 +1,94 @@ +use std::io::Cursor; + +use anyhow::{Context, Result}; +use async_trait::async_trait; +use byteorder::ReadBytesExt; +use request_response::{ + request::{Request as RequestTrait, Response as ResponseTrait}, + Serializable, +}; + +/// The outermost request type. This an enum that contains all the possible requests that the +/// sequencer can make. +#[derive(Debug, Clone)] +pub enum Request { + Example, +} + +/// Implement the `RequestTrait` trait for the `Request` type. This tells the request response +/// protocol how to validate the request and what the response type is. +#[async_trait] +impl RequestTrait for Request { + type Response = Response; + + async fn validate(&self) -> Result<()> { + Ok(()) + } +} + +/// The outermost response type. This an enum that contains all the possible responses that the +/// sequencer can make. +#[derive(Debug, Clone)] +pub enum Response { + Example, +} + +/// Implement the `ResponseTrait` trait for the `Response` type. This tells the request response +/// protocol how to validate the response and what the request type is. +#[async_trait] +impl ResponseTrait for Response { + async fn validate(&self, request: &Request) -> Result<()> { + // Match the type of the response and request + match (self, request) { + (Response::Example, Request::Example) => Ok(()), + } + } +} + +/// Implement the `Serializable` trait for the `Request` type. This tells the request response +/// protocol how to serialize and deserialize the request +impl Serializable for Request { + fn to_bytes(&self) -> Result> { + match self { + Request::Example => Ok(vec![0]), + } + } + + fn from_bytes(bytes: &[u8]) -> Result { + // Create a cursor so we can read the bytes in order + let mut cursor = Cursor::new(bytes); + + // Read the first byte, the request type + let request_type = cursor.read_u8().with_context(|| "invalid request type")?; + + // Deserialize the request based on the type + match request_type { + 0 => Ok(Request::Example), + _ => Err(anyhow::anyhow!("invalid request type")), + } + } +} + +/// Implement the `Serializable` trait for the `Response` type. This tells the request response +/// protocol how to serialize and deserialize the response. +impl Serializable for Response { + fn to_bytes(&self) -> Result> { + match self { + Response::Example => Ok(vec![0]), + } + } + + fn from_bytes(bytes: &[u8]) -> Result { + // Create a cursor so we can read the bytes in order + let mut cursor = Cursor::new(bytes); + + // Read the first byte, the response type + let response_type = cursor.read_u8().with_context(|| "invalid response type")?; + + // Deserialize the response based on the type + match response_type { + 0 => Ok(Response::Example), + _ => Err(anyhow::anyhow!("invalid response type")), + } + } +}