diff --git a/Cargo.lock b/Cargo.lock index 24d27052..c93ccc54 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -97,22 +97,22 @@ checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "alloy-chains" -version = "0.2.6" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4195a29a4b87137b2bb02105e746102873bc03561805cf45c0e510c961f160e6" +checksum = "ef8ff73a143281cb77c32006b04af9c047a6b8fe5860e85a88ad325328965355" dependencies = [ "alloy-primitives", "alloy-rlp", "num_enum", "serde", - "strum 0.27.1", + "strum 0.27.2", ] [[package]] name = "alloy-consensus" -version = "1.0.30" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d213580c17d239ae83c0d897ac3315db7cda83d2d4936a9823cc3517552f2e24" +checksum = "64a3bd0305a44fb457cae77de1e82856eadd42ea3cdf0dae29df32eb3b592979" dependencies = [ "alloy-eips", "alloy-primitives", @@ -131,14 +131,14 @@ dependencies = [ "secp256k1 0.30.0", "serde", "serde_with", - "thiserror 2.0.12", + "thiserror 2.0.16", ] [[package]] name = "alloy-consensus-any" -version = "1.0.30" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81443e3b8dccfeac7cd511aced15928c97ff253f4177acbb97de97178e543f6c" +checksum = "7a842b4023f571835e62ac39fb8d523d19fcdbacfa70bf796ff96e7e19586f50" dependencies = [ "alloy-consensus", "alloy-eips", @@ -178,7 +178,7 @@ dependencies = [ "crc", "rand 0.8.5", "serde", - "thiserror 2.0.12", + "thiserror 2.0.16", ] [[package]] @@ -207,14 +207,14 @@ dependencies = [ "rand 0.8.5", "serde", "serde_with", - "thiserror 2.0.12", + "thiserror 2.0.16", ] [[package]] name = "alloy-eips" -version = "1.0.30" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a15b4b0f6bab47aae017d52bb5a739bda381553c09fb9918b7172721ef5f5de" +checksum = "5cd749c57f38f8cbf433e651179fc5a676255e6b95044f467d49255d2b81725a" dependencies = [ "alloy-eip2124", "alloy-eip2930", @@ -232,7 +232,7 @@ dependencies = [ "serde", "serde_with", "sha2 0.10.9", - "thiserror 2.0.12", + "thiserror 2.0.16", ] [[package]] @@ -252,14 +252,14 @@ dependencies = [ "op-alloy-consensus", "op-revm", "revm", - "thiserror 2.0.12", + "thiserror 2.0.16", ] [[package]] name = "alloy-genesis" -version = "1.0.30" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ba1cbc25a07e0142e8875fcbe80e1fdb02be8160ae186b90f4b9a69a72ed2b" +checksum = "7d32cbf6c26d7d87e8a4e5925bbce41456e0bbeed95601add3443af277cd604e" dependencies = [ "alloy-eips", "alloy-primitives", @@ -271,9 +271,9 @@ dependencies = [ [[package]] name = "alloy-hardforks" -version = "0.3.1" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31c8616642b176f21e98e2740e27d28917b5d30d8612450cafff21772d4926bc" +checksum = "8d66cfdf265bf52c0c4a952960c854c3683c71ff2fc02c9b8c317c691fd3bc28" dependencies = [ "alloy-chains", "alloy-eip2124", @@ -297,24 +297,24 @@ dependencies = [ [[package]] name = "alloy-json-rpc" -version = "1.0.30" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8882ec8e4542cfd02aadc6dccbe90caa73038f60016d936734eb6ced53d2167" +checksum = "f614019a029c8fec14ae661aa7d4302e6e66bdbfb869dab40e78dcfba935fc97" dependencies = [ "alloy-primitives", "alloy-sol-types", "http", "serde", "serde_json", - "thiserror 2.0.12", + "thiserror 2.0.16", "tracing", ] [[package]] name = "alloy-network" -version = "1.0.30" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d6d87d588bda509881a7a66ae77c86514bd1193ac30fbff0e0f24db95eb5a5" +checksum = "be8b6d58e98803017bbfea01dde96c4d270a29e7aed3beb65c8d28b5ab464e0e" dependencies = [ "alloy-consensus", "alloy-consensus-any", @@ -333,14 +333,14 @@ dependencies = [ "futures-utils-wasm", "serde", "serde_json", - "thiserror 2.0.12", + "thiserror 2.0.16", ] [[package]] name = "alloy-network-primitives" -version = "1.0.30" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b14fa9ba5774e0b30ae6a04176d998211d516c8af69c9c530af7c6c42a8c508" +checksum = "db489617bffe14847bf89f175b1c183e5dd7563ef84713936e2c34255cfbd845" dependencies = [ "alloy-consensus", "alloy-eips", @@ -368,9 +368,9 @@ dependencies = [ [[package]] name = "alloy-op-hardforks" -version = "0.3.1" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07953246c78130f119855393ba0235d22539c60b6a627f737cdf0ae692f042f6" +checksum = "a8a2823360cd87c008df4b8b78794924948c3508e745dfed7d2b685774cb473e" dependencies = [ "alloy-chains", "alloy-hardforks", @@ -391,15 +391,15 @@ dependencies = [ "derive_more", "foldhash", "getrandom 0.3.3", - "hashbrown 0.15.4", - "indexmap 2.10.0", + "hashbrown 0.15.5", + "indexmap 2.11.3", "itoa", "k256", "keccak-asm", "paste", "proptest", "proptest-derive", - "rand 0.9.1", + "rand 0.9.2", "ruint", "rustc-hash 2.1.1", "serde", @@ -409,9 +409,9 @@ dependencies = [ [[package]] name = "alloy-provider" -version = "1.0.30" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "475a5141313c3665b75d818be97d5fa3eb5e0abb7e832e9767edd94746db28e3" +checksum = "ed90278374435e076a04dbddbb6d714bdd518eb274a64dbd70f65701429dd747" dependencies = [ "alloy-chains", "alloy-consensus", @@ -442,7 +442,7 @@ dependencies = [ "reqwest", "serde", "serde_json", - "thiserror 2.0.12", + "thiserror 2.0.16", "tokio", "tracing", "url", @@ -451,9 +451,9 @@ dependencies = [ [[package]] name = "alloy-pubsub" -version = "1.0.30" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f97c18795ce1ce8151c5539ce1e4200940389674173f677c7455f79bfb00e5df" +checksum = "9f539a4caaa5496ad54af38f5615adb54cc7b3ec1a42e530e706291cce074f4a" dependencies = [ "alloy-json-rpc", "alloy-primitives", @@ -490,14 +490,14 @@ checksum = "64b728d511962dda67c1bc7ea7c03736ec275ed2cf4c35d9585298ac9ccf3b73" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] name = "alloy-rpc-client" -version = "1.0.30" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25289674cd8c58fcca2568b5350423cb0dd7bca8c596c5e2869bfe4c5c57ed14" +checksum = "33732242ca63f107f5f8284190244038905fb233280f4b7c41f641d4f584d40d" dependencies = [ "alloy-json-rpc", "alloy-primitives", @@ -521,9 +521,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types" -version = "1.0.30" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39676beaa50db545cf15447fc94ec5513b64e85a48357a0625b9a04aef08a910" +checksum = "bb2683049c5f3037d64722902e2c1081f3d45de68696aca0511bbea834905746" dependencies = [ "alloy-primitives", "alloy-rpc-types-engine", @@ -534,9 +534,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-admin" -version = "1.0.30" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65acc9264342069decb617aa344847f55180ba3aeab1c8d1db062d0619881029" +checksum = "a345f6b7c1566264f1318d5b25e1a19a0c82ad94f4bec2b0c620057e0d570546" dependencies = [ "alloy-genesis", "alloy-primitives", @@ -546,9 +546,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-anvil" -version = "1.0.30" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9c8cad42fa936000be72ab80fcd97386a6a226c35c2989212756da9e76c1521" +checksum = "b757081f2a68e683de3731108494fa058036d5651bf10141ec2430bc1315c362" dependencies = [ "alloy-primitives", "alloy-rpc-types-eth", @@ -558,9 +558,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-any" -version = "1.0.30" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01bac57c987c93773787619e20f89167db74d460a2d1d40f591d94fb7c22c379" +checksum = "18f27c0c41a16cd0af4f5dbf791f7be2a60502ca8b0e840e0ad29803fac2d587" dependencies = [ "alloy-consensus-any", "alloy-rpc-types-eth", @@ -569,9 +569,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-beacon" -version = "1.0.30" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d3c0e6cc87a8be5582d08f929f96db25843f44cb636a0985a4a6bf02609c02f" +checksum = "45e8410078527399abfc76418d06b13737a49866e46a0574b45b43f2dd9c15bc" dependencies = [ "alloy-eips", "alloy-primitives", @@ -581,16 +581,16 @@ dependencies = [ "serde", "serde_json", "serde_with", - "thiserror 2.0.12", + "thiserror 2.0.16", "tree_hash", "tree_hash_derive", ] [[package]] name = "alloy-rpc-types-debug" -version = "1.0.30" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2fe118e6c152d54cb4549b9835fb87d38b12754bb121375183ee3ec84bd0849" +checksum = "d46cb226f1c8071875f4d0d8a0eb3ac571fcc49cd3bcdc20a5818de7b6ef0634" dependencies = [ "alloy-primitives", "derive_more", @@ -600,9 +600,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-engine" -version = "1.0.30" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72a41624eb84bc743e414198bf10eb48b611a5554d6a9fd6205f7384d57dfd7f" +checksum = "dec35a39206f0e04e8544d763c9fe324cc01f74de8821ef4b61e25ac329682f9" dependencies = [ "alloy-consensus", "alloy-eips", @@ -615,14 +615,14 @@ dependencies = [ "jsonwebtoken", "rand 0.8.5", "serde", - "strum 0.27.1", + "strum 0.27.2", ] [[package]] name = "alloy-rpc-types-eth" -version = "1.0.30" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd1e1b4dcdf13eaa96343e5c0dafc2d2e8ce5d20b90347169d46a1df0dec210" +checksum = "7f5812f81c3131abc2cd8953dc03c41999e180cff7252abbccaba68676e15027" dependencies = [ "alloy-consensus", "alloy-consensus-any", @@ -637,14 +637,14 @@ dependencies = [ "serde", "serde_json", "serde_with", - "thiserror 2.0.12", + "thiserror 2.0.16", ] [[package]] name = "alloy-rpc-types-mev" -version = "1.0.30" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01620baa48d3f49fc908c781eb91ded71f3226e719bb6404697c2851cac4e098" +checksum = "f999c26193d08e4f4a748ef5f45fb626b2fc4c1cd4dc99c0ebe1032516d37cba" dependencies = [ "alloy-consensus", "alloy-eips", @@ -657,23 +657,23 @@ dependencies = [ [[package]] name = "alloy-rpc-types-trace" -version = "1.0.30" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bc33d9d0e0b3cfe9c2e82a1a427c9ed516fcfebe764f0adf7ceb8107f702dd1" +checksum = "1070e7e92dae6a9c48885980f4f9ca9faa70f945fcd62fbb94472182ca08854f" dependencies = [ "alloy-primitives", "alloy-rpc-types-eth", "alloy-serde", "serde", "serde_json", - "thiserror 2.0.12", + "thiserror 2.0.16", ] [[package]] name = "alloy-rpc-types-txpool" -version = "1.0.30" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4fa9e9b3e613425d2a2ee1a322bdad5f1cedf835406fd4b59538822500b44bc" +checksum = "7f070754e160f6e34038305f472137eeb04170586d60d69c5d1e06fefe362a1f" dependencies = [ "alloy-primitives", "alloy-rpc-types-eth", @@ -683,9 +683,9 @@ dependencies = [ [[package]] name = "alloy-serde" -version = "1.0.30" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1b3b1078b8775077525bc9fe9f6577e815ceaecd6c412a4f3b4d8aa2836e8f6" +checksum = "04dfe41a47805a34b848c83448946ca96f3d36842e8c074bcf8fa0870e337d12" dependencies = [ "alloy-primitives", "arbitrary", @@ -695,9 +695,9 @@ dependencies = [ [[package]] name = "alloy-signer" -version = "1.0.30" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10ab1b8d4649bf7d0db8ab04e31658a6cc20364d920795484d886c35bed3bab4" +checksum = "f79237b4c1b0934d5869deea4a54e6f0a7425a8cd943a739d6293afdf893d847" dependencies = [ "alloy-primitives", "async-trait", @@ -705,14 +705,14 @@ dependencies = [ "either", "elliptic-curve", "k256", - "thiserror 2.0.12", + "thiserror 2.0.16", ] [[package]] name = "alloy-signer-local" -version = "1.0.30" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bdeec36c8d9823102b571b3eab8b323e053dc19c12da14a9687bd474129bf2a" +checksum = "d6e90a3858da59d1941f496c17db8d505f643260f7e97cdcdd33823ddca48fc1" dependencies = [ "alloy-consensus", "alloy-network", @@ -723,7 +723,7 @@ dependencies = [ "coins-bip39", "k256", "rand 0.8.5", - "thiserror 2.0.12", + "thiserror 2.0.16", "zeroize", ] @@ -738,7 +738,7 @@ dependencies = [ "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -750,11 +750,11 @@ dependencies = [ "alloy-sol-macro-input", "const-hex", "heck", - "indexmap 2.10.0", + "indexmap 2.11.3", "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.106", "syn-solidity", "tiny-keccak", ] @@ -771,7 +771,7 @@ dependencies = [ "macro-string", "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.106", "syn-solidity", ] @@ -799,9 +799,9 @@ dependencies = [ [[package]] name = "alloy-transport" -version = "1.0.30" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dce5129146a76ca6139a19832c75ad408857a56bcd18cd2c684183b8eacd78d8" +checksum = "cb43750e137fe3a69a325cd89a8f8e2bbf4f83e70c0f60fbe49f22511ca075e8" dependencies = [ "alloy-json-rpc", "alloy-primitives", @@ -813,7 +813,7 @@ dependencies = [ "parking_lot", "serde", "serde_json", - "thiserror 2.0.12", + "thiserror 2.0.16", "tokio", "tower 0.5.2", "tracing", @@ -823,9 +823,9 @@ dependencies = [ [[package]] name = "alloy-transport-http" -version = "1.0.30" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2379d998f46d422ec8ef2b61603bc28cda931e5e267aea1ebe71f62da61d101" +checksum = "f9b42c7d8b666eed975739201f407afc3320d3cd2e4d807639c2918fc736ea67" dependencies = [ "alloy-json-rpc", "alloy-transport", @@ -838,9 +838,9 @@ dependencies = [ [[package]] name = "alloy-transport-ipc" -version = "1.0.30" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "041aa5db2e907692a9a93a0a908057665c03e59364e1fbbeed613511a0159289" +checksum = "f07b920e2d4ec9b08cb12a32fa8e5e95dfcf706fe1d7f46453e24ee7089e29f0" dependencies = [ "alloy-json-rpc", "alloy-pubsub", @@ -858,9 +858,9 @@ dependencies = [ [[package]] name = "alloy-transport-ws" -version = "1.0.30" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6d44395e6793566e9c89bd82297cc4b0566655c1e78a1d69362640814784cc6" +checksum = "83db1cc29cce5f692844d6cf1b6b270ae308219c5d90a7246a74f3479b9201c2" dependencies = [ "alloy-pubsub", "alloy-transport", @@ -896,23 +896,17 @@ dependencies = [ [[package]] name = "alloy-tx-macros" -version = "1.0.30" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b5becb9c269a7d05a2f28d549f86df5a5dbc923e2667eff84fdecac8cda534c" +checksum = "e434e0917dce890f755ea774f59d6f12557bc8c7dd9fa06456af80cfe0f0181e" dependencies = [ "alloy-primitives", "darling 0.21.3", "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.106", ] -[[package]] -name = "android-tzdata" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" - [[package]] name = "android_system_properties" version = "0.1.5" @@ -924,9 +918,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.19" +version = "0.6.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "301af1932e46185686725e0fad2f8f2aa7da69dd70bf6ecc44d6b703844a3933" +checksum = "3ae563653d1938f79b1ab1b5e668c87c76a9930414574a6583a7b7e11a8e6192" dependencies = [ "anstyle", "anstyle-parse", @@ -954,29 +948,29 @@ dependencies = [ [[package]] name = "anstyle-query" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8bdeb6047d8983be085bab0ba1472e6dc604e7041dbf6fcd5e71523014fae9" +checksum = "9e231f6134f61b71076a3eab506c379d4f36122f2af15a9ff04415ea4c3339e2" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] name = "anstyle-wincon" -version = "3.0.9" +version = "3.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "403f75924867bb1033c59fbf0797484329750cfbe3c4325cd33127941fabc882" +checksum = "3e0633414522a32ffaac8ac6cc8f748e090c5717661fddeea04219e2344f5f2a" dependencies = [ "anstyle", "once_cell_polyfill", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] name = "anyhow" -version = "1.0.98" +version = "1.0.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" +checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100" [[package]] name = "aquamarine" @@ -989,14 +983,14 @@ dependencies = [ "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] name = "arbitrary" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223" +checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1" dependencies = [ "derive_arbitrary", ] @@ -1044,7 +1038,7 @@ dependencies = [ "ark-std 0.5.0", "educe", "fnv", - "hashbrown 0.15.4", + "hashbrown 0.15.5", "itertools 0.13.0", "num-bigint", "num-integer", @@ -1137,7 +1131,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62945a2f7e6de02a31fe400aa489f0e0f5b2502e69f95f853adb82a96c7a6b60" dependencies = [ "quote", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -1175,7 +1169,7 @@ dependencies = [ "num-traits", "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -1190,7 +1184,7 @@ dependencies = [ "ark-std 0.5.0", "educe", "fnv", - "hashbrown 0.15.4", + "hashbrown 0.15.5", ] [[package]] @@ -1264,7 +1258,7 @@ checksum = "213888f660fddcca0d257e88e54ac05bca01885f258ccdf695bafd77031bb69d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -1336,25 +1330,22 @@ dependencies = [ [[package]] name = "async-compression" -version = "0.4.25" +version = "0.4.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40f6024f3f856663b45fd0c9b6f2024034a702f453549449e0d84a305900dad4" +checksum = "977eb15ea9efd848bb8a4a1a2500347ed7f0bf794edf0dc3ddcf439f43d36b23" dependencies = [ - "brotli", - "flate2", + "compression-codecs", + "compression-core", "futures-core", - "memchr", "pin-project-lite", "tokio", - "zstd", - "zstd-safe", ] [[package]] name = "async-lock" -version = "3.4.0" +version = "3.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" +checksum = "5fd03604047cee9b6ce9de9f70c6cd540a0520c813cbd49bae61f33ab80ed1dc" dependencies = [ "event-listener", "event-listener-strategy", @@ -1380,18 +1371,18 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] name = "async-trait" -version = "0.1.88" +version = "0.1.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5" +checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -1429,7 +1420,7 @@ checksum = "ffdcb70bdbc4d478427380519163274ac86e52916e10f0a8889adf0f96d3fee7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -1440,9 +1431,9 @@ checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "aws-lc-rs" -version = "1.13.1" +version = "1.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fcc8f365936c834db5514fc45aee5b1202d677e6b40e48468aaaa8183ca8c7" +checksum = "5c953fe1ba023e6b7730c0d4b031d06f267f23a46167dcbd40316644b10a17ba" dependencies = [ "aws-lc-sys", "zeroize", @@ -1450,9 +1441,9 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.29.0" +version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61b1d86e7705efe1be1b569bab41d4fa1e14e220b60a160f78de2db687add079" +checksum = "dbfd150b5dbdb988bcc8fb1fe787eb6b7ee6180ca24da683b61ea5405f3d43ff" dependencies = [ "bindgen 0.69.5", "cc", @@ -1584,9 +1575,9 @@ dependencies = [ [[package]] name = "backon" -version = "1.5.1" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "302eaff5357a264a2c42f127ecb8bac761cf99749fc3dc95677e2743991f99e7" +checksum = "592277618714fbcecda9a02ba7a8781f319d26532a88553bbacc77ba5d2b3a8d" dependencies = [ "fastrand", "tokio", @@ -1664,7 +1655,7 @@ version = "0.69.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.4", "cexpr", "clang-sys", "itertools 0.12.1", @@ -1677,7 +1668,7 @@ dependencies = [ "regex", "rustc-hash 1.1.0", "shlex", - "syn 2.0.104", + "syn 2.0.106", "which", ] @@ -1687,7 +1678,7 @@ version = "0.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f49d8fed880d473ea71efb9bf597651e77201bdd4893efe54c9e5d65ae04ce6f" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.4", "cexpr", "clang-sys", "itertools 0.13.0", @@ -1696,7 +1687,7 @@ dependencies = [ "regex", "rustc-hash 1.1.0", "shlex", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -1738,9 +1729,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.9.1" +version = "2.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" +checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394" dependencies = [ "serde", ] @@ -1758,6 +1749,19 @@ dependencies = [ "wyz", ] +[[package]] +name = "blake3" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3888aaa89e4b2a40fca9848e400f6a658a5a3978de7be858e209cafa8be9a4a0" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if", + "constant_time_eq", +] + [[package]] name = "block-buffer" version = "0.9.0" @@ -1828,7 +1832,7 @@ dependencies = [ "serde_json", "serde_repr", "serde_urlencoded", - "thiserror 2.0.12", + "thiserror 2.0.16", "tokio", "tokio-util", "tower-service", @@ -1858,9 +1862,9 @@ dependencies = [ [[package]] name = "brotli" -version = "8.0.1" +version = "8.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9991eea70ea4f293524138648e41ee89b0b2b12ddef3b255effa43c8056e0e0d" +checksum = "4bd8b9603c7aa97359dbd97ecf258968c95f3adddd6db2f7e7a5bef101c84560" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -1918,9 +1922,9 @@ checksum = "175812e0be2bccb6abe50bb8d566126198344f707e304f45c648fd8f2cc0365e" [[package]] name = "bytemuck" -version = "1.23.1" +version = "1.23.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c76a5792e44e4abe34d3abf15636779261d45a7450612059293d1d2cfc63422" +checksum = "3995eaeebcdf32f91f980d360f78732ddc061097ab4e39991ae7a6ace9194677" [[package]] name = "byteorder" @@ -1955,11 +1959,11 @@ dependencies = [ [[package]] name = "camino" -version = "1.1.10" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0da45bc31171d8d6960122e222a67740df867c1dd53b4d51caa297084c185cab" +checksum = "e1de8bc0aa9e9385ceb3bf0c152e3a9b9544f6c4a912c8ae504e80c1f0368603" dependencies = [ - "serde", + "serde_core", ] [[package]] @@ -1979,7 +1983,7 @@ checksum = "4acbb09d9ee8e23699b9634375c72795d095bf268439da88562cf9b501f181fa" dependencies = [ "camino", "cargo-platform", - "semver 1.0.26", + "semver 1.0.27", "serde", "serde_json", ] @@ -1992,10 +1996,10 @@ checksum = "dd5eb614ed4c27c5d706420e4320fbe3216ab31fa1c33cd8246ac36dae4479ba" dependencies = [ "camino", "cargo-platform", - "semver 1.0.26", + "semver 1.0.27", "serde", "serde_json", - "thiserror 2.0.12", + "thiserror 2.0.16", ] [[package]] @@ -2006,9 +2010,9 @@ checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53" [[package]] name = "castaway" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0abae9be0aaf9ea96a3b1b8b1b55c602ca751eba1b1500220cea4ecbafe7c0d5" +checksum = "dec551ab6e7578819132c713a93c022a05d60159dc86e7a7050223577484c55a" dependencies = [ "rustversion", ] @@ -2041,9 +2045,9 @@ dependencies = [ [[package]] name = "cfg-if" -version = "1.0.1" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" +checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" [[package]] name = "cfg_aliases" @@ -2053,17 +2057,16 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "chrono" -version = "0.4.41" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" +checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" dependencies = [ - "android-tzdata", "iana-time-zone", "js-sys", "num-traits", "serde", "wasm-bindgen", - "windows-link", + "windows-link 0.2.0", ] [[package]] @@ -2089,9 +2092,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.40" +version = "4.5.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40b6887a1d8685cebccf115538db5c0efe625ccac9696ad45c409d96566e910f" +checksum = "7eac00902d9d136acd712710d71823fb8ac8004ca445a89e73a41d45aa712931" dependencies = [ "clap_builder", "clap_derive", @@ -2099,9 +2102,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.40" +version = "4.5.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0c66c08ce9f0c698cbce5c0279d0bb6ac936d8674174fe48f736533b964f59e" +checksum = "2ad9bbf750e73b5884fb8a211a9424a1906c1e156724260fdae972f31d70e1d6" dependencies = [ "anstream", "anstyle", @@ -2111,14 +2114,14 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.40" +version = "4.5.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2c7947ae4cc3d851207c1adb5b5e260ff0cca11446b1d6d1423788e442257ce" +checksum = "bbfd7eae0b0f1a6e63d4b13c9c478de77c2eb546fba158ad50b4203dc24b9f9c" dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -2205,11 +2208,11 @@ dependencies = [ [[package]] name = "comfy-table" -version = "7.1.4" +version = "7.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a65ebfec4fb190b6f90e944a817d60499ee0744e582530e2c9900a22e591d9a" +checksum = "b03b7db8e0b4b2fdad6c551e634134e99ec000e5c8c3b6856c65e8bbaded7a3b" dependencies = [ - "crossterm", + "crossterm 0.29.0", "unicode-segmentation", "unicode-width 0.2.0", ] @@ -2228,6 +2231,26 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "compression-codecs" +version = "0.4.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "485abf41ac0c8047c07c87c72c8fb3eb5197f6e9d7ded615dfd1a00ae00a0f64" +dependencies = [ + "brotli", + "compression-core", + "flate2", + "memchr", + "zstd", + "zstd-safe", +] + +[[package]] +name = "compression-core" +version = "0.4.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e47641d3deaf41fb1538ac1f54735925e275eaf3bf4d55c81b137fba797e5cbb" + [[package]] name = "concat-kdf" version = "0.1.0" @@ -2248,15 +2271,14 @@ dependencies = [ [[package]] name = "const-hex" -version = "1.14.1" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83e22e0ed40b96a48d3db274f72fd365bd78f67af39b6bbd47e8a15e1c6207ff" +checksum = "b6407bff74dea37e0fa3dc1c1c974e5d46405f0c987bf9997a0762adce71eda6" dependencies = [ "cfg-if", "cpufeatures", - "hex", "proptest", - "serde", + "serde_core", ] [[package]] @@ -2285,6 +2307,12 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "constant_time_eq" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" + [[package]] name = "convert_case" version = "0.7.1" @@ -2355,9 +2383,9 @@ checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" [[package]] name = "crc32fast" -version = "1.4.2" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" dependencies = [ "cfg-if", ] @@ -2408,7 +2436,7 @@ version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.4", "crossterm_winapi", "mio", "parking_lot", @@ -2418,6 +2446,20 @@ dependencies = [ "winapi", ] +[[package]] +name = "crossterm" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8b9f2e4c67f833b660cdb0a3523065869fb35570177239812ed4c905aeff87b" +dependencies = [ + "bitflags 2.9.4", + "crossterm_winapi", + "document-features", + "parking_lot", + "rustix 1.1.2", + "winapi", +] + [[package]] name = "crossterm_winapi" version = "0.9.1" @@ -2458,9 +2500,9 @@ dependencies = [ [[package]] name = "ctor" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4735f265ba6a1188052ca32d461028a7d1125868be18e287e756019da7607b5" +checksum = "ec09e802f5081de6157da9a75701d6c713d8dc3ba52571fd4bd25f412644e8a6" dependencies = [ "ctor-proc-macro", "dtor", @@ -2468,9 +2510,9 @@ dependencies = [ [[package]] name = "ctor-proc-macro" -version = "0.0.5" +version = "0.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f211af61d8efdd104f96e57adf5e426ba1bc3ed7a4ead616e15e5881fd79c4d" +checksum = "e2931af7e13dc045d8e9d26afccc6fa115d64e115c9c84b1166288b46f6782c2" [[package]] name = "ctr" @@ -2505,7 +2547,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -2539,7 +2581,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -2554,7 +2596,7 @@ dependencies = [ "quote", "serde", "strsim", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -2565,7 +2607,7 @@ checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" dependencies = [ "darling_core 0.20.11", "quote", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -2576,7 +2618,7 @@ checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" dependencies = [ "darling_core 0.21.3", "quote", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -2629,7 +2671,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d162beedaa69905488a8da94f5ac3edb4dd4788b732fadb7bd120b2625c1976" dependencies = [ "data-encoding", - "syn 1.0.109", + "syn 2.0.106", ] [[package]] @@ -2661,9 +2703,9 @@ dependencies = [ [[package]] name = "deranged" -version = "0.4.0" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" +checksum = "d630bccd429a5bb5a64b5e94f693bfc48c9f8566418fda4c494cc94f911f87cc" dependencies = [ "powerfmt", "serde", @@ -2682,24 +2724,24 @@ dependencies = [ [[package]] name = "derive-where" -version = "1.5.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "510c292c8cf384b1a340b816a9a6cf2599eb8f566a44949024af88418000c50b" +checksum = "ef941ded77d15ca19b40374869ac6000af1c9f2a4c0f3d4c70926287e6364a8f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] name = "derive_arbitrary" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30542c1ad912e0e3d22a1935c290e12e8a29d704a420177a31faad4a601a0800" +checksum = "1e567bd82dcff979e4b03460c307b3cdc9e96fde3d73bed1496d2bc75d9dd62a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -2720,7 +2762,7 @@ dependencies = [ "darling 0.20.11", "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -2730,7 +2772,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" dependencies = [ "derive_builder_core", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -2751,7 +2793,7 @@ dependencies = [ "convert_case", "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.106", "unicode-xid", ] @@ -2815,8 +2857,8 @@ checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab" dependencies = [ "libc", "option-ext", - "redox_users 0.5.0", - "windows-sys 0.60.2", + "redox_users 0.5.2", + "windows-sys 0.61.0", ] [[package]] @@ -2856,7 +2898,7 @@ dependencies = [ "parking_lot", "rand 0.8.5", "smallvec", - "socket2", + "socket2 0.5.10", "tokio", "tracing", "uint 0.10.0", @@ -2871,7 +2913,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -2897,6 +2939,15 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aac81fa3e28d21450aa4d2ac065992ba96a1d7303efbce51a95f4fd175b67562" +[[package]] +name = "document-features" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95249b50c6c185bee49034bcb378a49dc2b5dff0be90ff6616d31d64febab05d" +dependencies = [ + "litrs", +] + [[package]] name = "dotenvy" version = "0.15.7" @@ -2926,9 +2977,9 @@ checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" [[package]] name = "dyn-clone" -version = "1.0.19" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c7a8fb8a9fbf66c1f703fe16184d10ca0ee9d23be5b4436400408ba54a95005" +checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" [[package]] name = "ecdsa" @@ -2952,14 +3003,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" dependencies = [ "pkcs8", + "serde", "signature", ] [[package]] name = "ed25519-dalek" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871" +checksum = "70e796c081cee67dc755e1a36a0a172b897fab85fc3f6bc48307991f64e4eca9" dependencies = [ "curve25519-dalek", "ed25519", @@ -2979,7 +3031,7 @@ dependencies = [ "enum-ordinalize", "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -3055,7 +3107,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -3075,7 +3127,7 @@ checksum = "0d28318a75d4aead5c4db25382e8ef717932d0346600cacae6357eb5941bc5ff" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -3086,12 +3138,12 @@ checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "errno" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.60.2", + "windows-sys 0.61.0", ] [[package]] @@ -3162,14 +3214,14 @@ dependencies = [ "darling 0.20.11", "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] name = "event-listener" -version = "5.4.0" +version = "5.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3492acde4c3fc54c845eaab3eed8bd00c7a7d881f78bfc801e43a93dec1331ae" +checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab" dependencies = [ "concurrent-queue", "parking", @@ -3252,14 +3304,14 @@ checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" [[package]] name = "filetime" -version = "0.2.25" +version = "0.2.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35c0522e981e68cbfa8c3f978441a5f34b30b96e146b33cd3359176b50fe8586" +checksum = "bc0505cd1b6fa6580283f6bdf70a73fcf4aba1184038c90902b92b3dd0df63ed" dependencies = [ "cfg-if", "libc", "libredox", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] @@ -3348,7 +3400,7 @@ dependencies = [ "serde_json", "testcontainers", "testcontainers-modules", - "thiserror 2.0.12", + "thiserror 2.0.16", "tokio", "tokio-tungstenite", "tokio-util", @@ -3405,9 +3457,9 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "form_urlencoded" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" dependencies = [ "percent-encoding", ] @@ -3489,7 +3541,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -3540,9 +3592,9 @@ checksum = "42012b0f064e01aa58b545fe3727f90f7dd4020f4a3ea735b50344965f5a57e9" [[package]] name = "generator" -version = "0.8.5" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d18470a76cb7f8ff746cf1f7470914f900252ec36bbc40b569d74b1258446827" +checksum = "605183a538e3e2a9c1038635cc5c2d194e2ee8fd0d1b66b8349fad7dbacce5a2" dependencies = [ "cc", "cfg-if", @@ -3587,7 +3639,7 @@ dependencies = [ "js-sys", "libc", "r-efi", - "wasi 0.14.2+wasi-0.2.4", + "wasi 0.14.7+wasi-0.2.4", "wasm-bindgen", ] @@ -3613,7 +3665,7 @@ version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2deb07a133b1520dc1a5690e9bd08950108873d7ed5de38dcc74d3b5ebffa110" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.4", "libc", "libgit2-sys", "log", @@ -3622,9 +3674,9 @@ dependencies = [ [[package]] name = "glob" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" +checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" [[package]] name = "gloo-net" @@ -3674,12 +3726,12 @@ dependencies = [ [[package]] name = "gmp-mpfr-sys" -version = "1.6.5" +version = "1.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c66d61197a68f6323b9afa616cf83d55d69191e1bf364d4eb7d35ae18defe776" +checksum = "60f8970a75c006bb2f8ae79c6768a116dd215fa8346a87aed99bf9d82ca43394" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] @@ -3695,9 +3747,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17da50a276f1e01e0ba6c029e47b7100754904ee8a278f886546e98575380785" +checksum = "f3c0b69cfcb4e1b9f1bf2f53f95f766e4661169728ec61cd3fe5a0166f2d1386" dependencies = [ "atomic-waker", "bytes", @@ -3705,7 +3757,7 @@ dependencies = [ "futures-core", "futures-sink", "http", - "indexmap 2.10.0", + "indexmap 2.11.3", "slab", "tokio", "tokio-util", @@ -3741,9 +3793,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.4" +version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" dependencies = [ "allocator-api2", "equivalent", @@ -3787,9 +3839,6 @@ name = "hex" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" -dependencies = [ - "serde", -] [[package]] name = "hex-conservative" @@ -3816,10 +3865,10 @@ dependencies = [ "idna", "ipnet", "once_cell", - "rand 0.9.1", + "rand 0.9.2", "ring", "serde", - "thiserror 2.0.12", + "thiserror 2.0.16", "tinyvec", "tokio", "tracing", @@ -3839,11 +3888,11 @@ dependencies = [ "moka", "once_cell", "parking_lot", - "rand 0.9.1", + "rand 0.9.2", "resolv-conf", "serde", "smallvec", - "thiserror 2.0.12", + "thiserror 2.0.16", "tokio", "tracing", ] @@ -3883,7 +3932,7 @@ checksum = "a56f203cd1c76362b69e3863fd987520ac36cf70a8c92627449b2f64a8cf7d65" dependencies = [ "cfg-if", "libc", - "windows-link", + "windows-link 0.1.3", ] [[package]] @@ -3946,9 +3995,9 @@ checksum = "91f255a4535024abf7640cb288260811fc14794f62b063652ed349f9a6c2348e" [[package]] name = "humantime" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b112acc8b3adf4b107a8ec20977da0273a8c386765a3ec0229bd500a1443f9f" +checksum = "135b12329e5e3ce057a9f972339ea52bc954fe1e9358ef27f95e89716fbc5424" [[package]] name = "humantime-serde" @@ -3962,13 +4011,14 @@ dependencies = [ [[package]] name = "hyper" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80" +checksum = "eb3aa54a13a0dfe7fbe3a59e0c76093041720fdc77b110cc0fc260fafb4dc51e" dependencies = [ + "atomic-waker", "bytes", "futures-channel", - "futures-util", + "futures-core", "h2", "http", "http-body", @@ -3976,6 +4026,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", + "pin-utils", "smallvec", "tokio", "want", @@ -4012,7 +4063,7 @@ dependencies = [ "tokio", "tokio-rustls", "tower-service", - "webpki-roots 1.0.1", + "webpki-roots 1.0.2", ] [[package]] @@ -4046,9 +4097,9 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.14" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc2fdfdbff08affe55bb779f33b053aa1fe5dd5b54c257343c17edfa55711bdb" +checksum = "3c6995591a8f1380fcb4ba966a252a4b29188d51d2b89e3a252f5305be65aea8" dependencies = [ "base64 0.22.1", "bytes", @@ -4062,7 +4113,7 @@ dependencies = [ "libc", "percent-encoding", "pin-project-lite", - "socket2", + "socket2 0.6.0", "system-configuration", "tokio", "tower-service", @@ -4087,9 +4138,9 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.63" +version = "0.1.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" +checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -4097,7 +4148,7 @@ dependencies = [ "js-sys", "log", "wasm-bindgen", - "windows-core 0.61.2", + "windows-core 0.62.0", ] [[package]] @@ -4203,9 +4254,9 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "idna" -version = "1.0.3" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" dependencies = [ "idna_adapter", "smallvec", @@ -4249,7 +4300,7 @@ checksum = "a0eb5a3343abf848c0984fe4604b2b105da9539376e24fc0a3b0007411ae4fd9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -4273,9 +4324,9 @@ dependencies = [ [[package]] name = "indenter" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" +checksum = "964de6e86d545b246d84badc0fef527924ace5134f30641c203ef52ba83f58d5" [[package]] name = "indexmap" @@ -4290,14 +4341,15 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.10.0" +version = "2.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661" +checksum = "92119844f513ffa41556430369ab02c295a3578af21cf945caa3e9e0c2481ac3" dependencies = [ "arbitrary", "equivalent", - "hashbrown 0.15.4", + "hashbrown 0.15.5", "serde", + "serde_core", ] [[package]] @@ -4312,7 +4364,7 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f37dccff2791ab604f9babef0ba14fbe0be30bd368dc541e2b08d07c8aa908f3" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.4", "inotify-sys", "libc", ] @@ -4338,15 +4390,15 @@ dependencies = [ [[package]] name = "instability" -version = "0.3.7" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf9fed6d91cfb734e7476a06bde8300a1b94e217e1b523b6f0cd1a01998c71d" +checksum = "435d80800b936787d62688c927b6490e887c7ef5ff9ce922c6c6050fca75eb9a" dependencies = [ "darling 0.20.11", "indoc", "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -4373,13 +4425,24 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "io-uring" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "046fa2d4d00aea763528b4950358d0ead425372445dc8ff86312b3c69ff7727b" +dependencies = [ + "bitflags 2.9.4", + "cfg-if", + "libc", +] + [[package]] name = "ipconfig" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f" dependencies = [ - "socket2", + "socket2 0.5.10", "widestring", "windows-sys 0.48.0", "winreg", @@ -4473,9 +4536,9 @@ checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" [[package]] name = "jobserver" -version = "0.1.33" +version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38f262f097c174adebe41eb73d66ae9c06b2844fb0da69969647bbddd9b0538a" +checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" dependencies = [ "getrandom 0.3.3", "libc", @@ -4483,9 +4546,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.77" +version = "0.3.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +checksum = "6247da8b8658ad4e73a186e747fcc5fc2a29f979d6fe6269127fdb5fd08298d0" dependencies = [ "once_cell", "wasm-bindgen", @@ -4496,11 +4559,11 @@ name = "jsonrpsee" version = "0.25.1" source = "git+https://github.com/paritytech/jsonrpsee?rev=f04afa740e55db60dce20d9839758792f035ffff#f04afa740e55db60dce20d9839758792f035ffff" dependencies = [ - "jsonrpsee-core 0.25.1 (git+https://github.com/paritytech/jsonrpsee?rev=f04afa740e55db60dce20d9839758792f035ffff)", - "jsonrpsee-http-client 0.25.1 (git+https://github.com/paritytech/jsonrpsee?rev=f04afa740e55db60dce20d9839758792f035ffff)", + "jsonrpsee-core 0.25.1", + "jsonrpsee-http-client 0.25.1", "jsonrpsee-proc-macros 0.25.1", "jsonrpsee-server 0.25.1", - "jsonrpsee-types 0.25.1 (git+https://github.com/paritytech/jsonrpsee?rev=f04afa740e55db60dce20d9839758792f035ffff)", + "jsonrpsee-types 0.25.1", "tokio", "tracing", ] @@ -4540,7 +4603,7 @@ dependencies = [ "rustls-pki-types", "rustls-platform-verifier", "soketto", - "thiserror 2.0.12", + "thiserror 2.0.16", "tokio", "tokio-rustls", "tokio-util", @@ -4548,28 +4611,6 @@ dependencies = [ "url", ] -[[package]] -name = "jsonrpsee-core" -version = "0.25.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "693c93cbb7db25f4108ed121304b671a36002c2db67dff2ee4391a688c738547" -dependencies = [ - "async-trait", - "bytes", - "futures-util", - "http", - "http-body", - "http-body-util", - "jsonrpsee-types 0.25.1 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project", - "serde", - "serde_json", - "thiserror 2.0.12", - "tokio", - "tower 0.5.2", - "tracing", -] - [[package]] name = "jsonrpsee-core" version = "0.25.1" @@ -4581,14 +4622,14 @@ dependencies = [ "http", "http-body", "http-body-util", - "jsonrpsee-types 0.25.1 (git+https://github.com/paritytech/jsonrpsee?rev=f04afa740e55db60dce20d9839758792f035ffff)", + "jsonrpsee-types 0.25.1", "parking_lot", "pin-project", - "rand 0.9.1", + "rand 0.9.2", "rustc-hash 2.1.1", "serde", "serde_json", - "thiserror 2.0.12", + "thiserror 2.0.16", "tokio", "tower 0.5.2", "tracing", @@ -4610,11 +4651,11 @@ dependencies = [ "jsonrpsee-types 0.26.0", "parking_lot", "pin-project", - "rand 0.9.1", + "rand 0.9.2", "rustc-hash 2.1.1", "serde", "serde_json", - "thiserror 2.0.12", + "thiserror 2.0.16", "tokio", "tokio-stream", "tower 0.5.2", @@ -4622,29 +4663,6 @@ dependencies = [ "wasm-bindgen-futures", ] -[[package]] -name = "jsonrpsee-http-client" -version = "0.25.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6962d2bd295f75e97dd328891e58fce166894b974c1f7ce2e7597f02eeceb791" -dependencies = [ - "base64 0.22.1", - "http-body", - "hyper", - "hyper-rustls", - "hyper-util", - "jsonrpsee-core 0.25.1 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpsee-types 0.25.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rustls", - "rustls-platform-verifier", - "serde", - "serde_json", - "thiserror 2.0.12", - "tokio", - "tower 0.5.2", - "url", -] - [[package]] name = "jsonrpsee-http-client" version = "0.25.1" @@ -4655,13 +4673,13 @@ dependencies = [ "hyper", "hyper-rustls", "hyper-util", - "jsonrpsee-core 0.25.1 (git+https://github.com/paritytech/jsonrpsee?rev=f04afa740e55db60dce20d9839758792f035ffff)", - "jsonrpsee-types 0.25.1 (git+https://github.com/paritytech/jsonrpsee?rev=f04afa740e55db60dce20d9839758792f035ffff)", + "jsonrpsee-core 0.25.1", + "jsonrpsee-types 0.25.1", "rustls", "rustls-platform-verifier", "serde", "serde_json", - "thiserror 2.0.12", + "thiserror 2.0.16", "tokio", "tower 0.5.2", "url", @@ -4684,7 +4702,7 @@ dependencies = [ "rustls-platform-verifier", "serde", "serde_json", - "thiserror 2.0.12", + "thiserror 2.0.16", "tokio", "tower 0.5.2", "url", @@ -4699,7 +4717,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -4712,7 +4730,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -4726,14 +4744,14 @@ dependencies = [ "http-body-util", "hyper", "hyper-util", - "jsonrpsee-core 0.25.1 (git+https://github.com/paritytech/jsonrpsee?rev=f04afa740e55db60dce20d9839758792f035ffff)", - "jsonrpsee-types 0.25.1 (git+https://github.com/paritytech/jsonrpsee?rev=f04afa740e55db60dce20d9839758792f035ffff)", + "jsonrpsee-core 0.25.1", + "jsonrpsee-types 0.25.1", "pin-project", "route-recognizer", "serde", "serde_json", "soketto", - "thiserror 2.0.12", + "thiserror 2.0.16", "tokio", "tokio-stream", "tokio-util", @@ -4760,7 +4778,7 @@ dependencies = [ "serde", "serde_json", "soketto", - "thiserror 2.0.12", + "thiserror 2.0.16", "tokio", "tokio-stream", "tokio-util", @@ -4768,18 +4786,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "jsonrpsee-types" -version = "0.25.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66df7256371c45621b3b7d2fb23aea923d577616b9c0e9c0b950a6ea5c2be0ca" -dependencies = [ - "http", - "serde", - "serde_json", - "thiserror 2.0.12", -] - [[package]] name = "jsonrpsee-types" version = "0.25.1" @@ -4788,7 +4794,7 @@ dependencies = [ "http", "serde", "serde_json", - "thiserror 2.0.12", + "thiserror 2.0.16", ] [[package]] @@ -4800,7 +4806,7 @@ dependencies = [ "http", "serde", "serde_json", - "thiserror 2.0.12", + "thiserror 2.0.16", ] [[package]] @@ -4912,9 +4918,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.174" +version = "0.2.175" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" +checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543" [[package]] name = "libgit2-sys" @@ -4935,7 +4941,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" dependencies = [ "cfg-if", - "windows-targets 0.53.2", + "windows-targets 0.53.3", ] [[package]] @@ -4958,7 +4964,7 @@ dependencies = [ "multihash", "quick-protobuf", "sha2 0.10.9", - "thiserror 2.0.12", + "thiserror 2.0.16", "tracing", "zeroize", ] @@ -4976,13 +4982,13 @@ dependencies = [ [[package]] name = "libredox" -version = "0.1.4" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1580801010e535496706ba011c15f8532df6b42297d2e471fec38ceadd8c0638" +checksum = "416f7e718bdb06000964960ffa43b4335ad4012ae8b99060261aa4a8088d5ccb" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.4", "libc", - "redox_syscall 0.5.13", + "redox_syscall 0.5.17", ] [[package]] @@ -5067,9 +5073,9 @@ checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" [[package]] name = "linux-raw-sys" -version = "0.9.4" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" +checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" [[package]] name = "litemap" @@ -5077,6 +5083,12 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" +[[package]] +name = "litrs" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5e54036fe321fd421e10d732f155734c4e4afd610dd556d9a82833ab3ee0bed" + [[package]] name = "lock_api" version = "0.4.13" @@ -5090,9 +5102,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.27" +version = "0.4.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" +checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" [[package]] name = "loom" @@ -5113,7 +5125,7 @@ version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" dependencies = [ - "hashbrown 0.15.4", + "hashbrown 0.15.5", ] [[package]] @@ -5122,7 +5134,7 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "227748d55f2f0ab4735d87fd623798cb6b664512fe979705f829c9f81c934465" dependencies = [ - "hashbrown 0.15.4", + "hashbrown 0.15.5", ] [[package]] @@ -5173,7 +5185,7 @@ checksum = "1b27834086c65ec3f9387b096d66e99f221cf081c2b738042aa252bcd41204e3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -5205,9 +5217,9 @@ checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" [[package]] name = "memmap2" -version = "0.9.5" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd3f7eed9d3848f8b98834af67102b720745c4ec028fcd0aa0239277e7de374f" +checksum = "843a98750cd611cc2965a8213b53b43e715f13c37a9e096c6408e69990961db7" dependencies = [ "libc", ] @@ -5231,7 +5243,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -5245,7 +5257,7 @@ dependencies = [ "hyper", "hyper-rustls", "hyper-util", - "indexmap 2.10.0", + "indexmap 2.11.3", "ipnet", "metrics", "metrics-util 0.19.1", @@ -5266,12 +5278,12 @@ dependencies = [ "hyper", "hyper-rustls", "hyper-util", - "indexmap 2.10.0", + "indexmap 2.11.3", "ipnet", "metrics", "metrics-util 0.20.0", "quanta", - "thiserror 2.0.12", + "thiserror 2.0.16", "tokio", "tracing", ] @@ -5301,13 +5313,13 @@ dependencies = [ "aho-corasick", "crossbeam-epoch", "crossbeam-utils", - "hashbrown 0.15.4", - "indexmap 2.10.0", + "hashbrown 0.15.5", + "indexmap 2.11.3", "metrics", "ordered-float", "quanta", "radix_trie", - "rand 0.9.1", + "rand 0.9.2", "rand_xoshiro", "sketches-ddsketch", ] @@ -5320,10 +5332,10 @@ checksum = "fe8db7a05415d0f919ffb905afa37784f71901c9a773188876984b4f769ab986" dependencies = [ "crossbeam-epoch", "crossbeam-utils", - "hashbrown 0.15.4", + "hashbrown 0.15.5", "metrics", "quanta", - "rand 0.9.1", + "rand 0.9.2", "rand_xoshiro", "sketches-ddsketch", ] @@ -5519,12 +5531,11 @@ checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" [[package]] name = "notify" -version = "8.0.0" +version = "8.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fee8403b3d66ac7b26aee6e40a897d85dc5ce26f44da36b8b73e987cc52e943" +checksum = "4d3d07927151ff8575b7087f245456e549fea62edf0ec4e565a5ee50c8402bc3" dependencies = [ - "bitflags 2.9.1", - "filetime", + "bitflags 2.9.4", "fsevent-sys", "inotify", "kqueue", @@ -5533,7 +5544,7 @@ dependencies = [ "mio", "notify-types", "walkdir", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] @@ -5669,7 +5680,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -5738,7 +5749,7 @@ dependencies = [ "derive_more", "serde", "serde_with", - "thiserror 2.0.12", + "thiserror 2.0.16", ] [[package]] @@ -5789,7 +5800,7 @@ dependencies = [ "op-alloy-consensus", "serde", "serde_json", - "thiserror 2.0.12", + "thiserror 2.0.16", ] [[package]] @@ -5810,7 +5821,7 @@ dependencies = [ "op-alloy-consensus", "serde", "snap", - "thiserror 2.0.12", + "thiserror 2.0.16", ] [[package]] @@ -5836,7 +5847,7 @@ version = "0.10.73" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8505734d46c8ab1e19a1dce3aef597ad87dcb4c37e7188231769bd6bd51cebf8" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.4", "cfg-if", "foreign-types", "libc", @@ -5853,7 +5864,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -5884,7 +5895,7 @@ dependencies = [ "futures-sink", "js-sys", "pin-project-lite", - "thiserror 2.0.12", + "thiserror 2.0.16", "tracing", ] @@ -5918,7 +5929,7 @@ dependencies = [ "prost", "reqwest", "serde_json", - "thiserror 2.0.12", + "thiserror 2.0.16", "tokio", "tonic", "tracing", @@ -5954,7 +5965,7 @@ dependencies = [ "percent-encoding", "rand 0.8.5", "serde_json", - "thiserror 2.0.12", + "thiserror 2.0.16", "tokio", "tokio-stream", "tracing", @@ -6024,7 +6035,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -6051,7 +6062,7 @@ checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.5.13", + "redox_syscall 0.5.17", "smallvec", "windows-targets 0.52.6", ] @@ -6078,7 +6089,7 @@ dependencies = [ "regex", "regex-syntax", "structmeta", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -6109,18 +6120,18 @@ dependencies = [ [[package]] name = "percent-encoding" -version = "2.3.1" +version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "pest" -version = "2.8.1" +version = "2.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1db05f56d34358a8b1066f67cbb203ee3e7ed2ba674a6263a1d5ec6db2204323" +checksum = "21e0a3a33733faeaf8651dfee72dd0f388f0c8e5ad496a3478fa5a922f49cfa8" dependencies = [ "memchr", - "thiserror 2.0.12", + "thiserror 2.0.16", "ucd-trie", ] @@ -6165,7 +6176,7 @@ dependencies = [ "phf_shared", "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -6194,7 +6205,7 @@ checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -6254,9 +6265,9 @@ checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" [[package]] name = "potential_utf" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585" +checksum = "84df19adbe5b5a0782edcab45899906947ab039ccf4573713735ee7de1e6b08a" dependencies = [ "zerovec", ] @@ -6318,12 +6329,12 @@ dependencies = [ [[package]] name = "prettyplease" -version = "0.2.35" +version = "0.2.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "061c1221631e079b26479d25bbf2275bfe5917ae8419cd7e34f13bfc2aa7539a" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -6348,11 +6359,11 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "3.3.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edce586971a4dfaa28950c6f18ed55e0406c1ab88bbce2c6f6293a7aaba73d35" +checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" dependencies = [ - "toml_edit", + "toml_edit 0.23.5", ] [[package]] @@ -6374,14 +6385,14 @@ dependencies = [ "proc-macro-error-attr2", "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] name = "proc-macro2" -version = "1.0.95" +version = "1.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" +checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" dependencies = [ "unicode-ident", ] @@ -6392,7 +6403,7 @@ version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cc5b72d8145275d844d4b5f6d4e1eef00c8cd889edb6035c21675d1bb1f45c9f" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.4", "chrono", "flate2", "hex", @@ -6406,7 +6417,7 @@ version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "239df02d8349b06fc07398a3a1697b06418223b1c7725085e801e7c0fc6a12ec" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.4", "chrono", "hex", ] @@ -6419,10 +6430,10 @@ checksum = "6fcdab19deb5195a31cf7726a210015ff1496ba1464fd42cb4f537b8b01b471f" dependencies = [ "bit-set", "bit-vec", - "bitflags 2.9.1", + "bitflags 2.9.4", "lazy_static", "num-traits", - "rand 0.9.1", + "rand 0.9.2", "rand_chacha 0.9.0", "rand_xorshift", "regex-syntax", @@ -6449,7 +6460,7 @@ checksum = "4ee1c9ac207483d5e7db4940700de86a9aae46ef90c48b57f99fe7edb8345e49" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -6472,7 +6483,7 @@ dependencies = [ "itertools 0.14.0", "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -6481,7 +6492,7 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57206b407293d2bcd3af849ce869d52068623f19e1b5ff8e8778e3309439682b" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.4", "memchr", "unicase", ] @@ -6518,9 +6529,9 @@ dependencies = [ [[package]] name = "quinn" -version = "0.11.8" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "626214629cda6781b6dc1d316ba307189c85ba657213ce642d9c77670f8202c8" +checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" dependencies = [ "bytes", "cfg_aliases", @@ -6529,8 +6540,8 @@ dependencies = [ "quinn-udp", "rustc-hash 2.1.1", "rustls", - "socket2", - "thiserror 2.0.12", + "socket2 0.6.0", + "thiserror 2.0.16", "tokio", "tracing", "web-time", @@ -6538,20 +6549,20 @@ dependencies = [ [[package]] name = "quinn-proto" -version = "0.11.12" +version = "0.11.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49df843a9161c85bb8aae55f101bc0bac8bcafd637a620d9122fd7e0b2f7422e" +checksum = "f1906b49b0c3bc04b5fe5d86a77925ae6524a19b816ae38ce1e426255f1d8a31" dependencies = [ "bytes", "getrandom 0.3.3", "lru-slab", - "rand 0.9.1", + "rand 0.9.2", "ring", "rustc-hash 2.1.1", "rustls", "rustls-pki-types", "slab", - "thiserror 2.0.12", + "thiserror 2.0.16", "tinyvec", "tracing", "web-time", @@ -6559,16 +6570,16 @@ dependencies = [ [[package]] name = "quinn-udp" -version = "0.5.13" +version = "0.5.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcebb1209ee276352ef14ff8732e24cc2b02bbac986cd74a4c81bcb2f9881970" +checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" dependencies = [ "cfg_aliases", "libc", "once_cell", - "socket2", + "socket2 0.6.0", "tracing", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] @@ -6616,9 +6627,9 @@ dependencies = [ [[package]] name = "rand" -version = "0.9.1" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97" +checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" dependencies = [ "rand_chacha 0.9.0", "rand_core 0.9.3", @@ -6688,10 +6699,10 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eabd94c2f37801c20583fc49dd5cd6b0ba68c716787c2dd6ed18571e1e63117b" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.4", "cassowary", "compact_str", - "crossterm", + "crossterm 0.28.1", "indoc", "instability", "itertools 0.13.0", @@ -6705,18 +6716,18 @@ dependencies = [ [[package]] name = "raw-cpuid" -version = "11.5.0" +version = "11.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6df7ab838ed27997ba19a4664507e6f82b41fe6e20be42929332156e5e85146" +checksum = "498cd0dc59d73224351ee52a95fee0f1a617a2eae0e7d9d720cc622c73a54186" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.4", ] [[package]] name = "rayon" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f" dependencies = [ "either", "rayon-core", @@ -6724,9 +6735,9 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.12.1" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" dependencies = [ "crossbeam-deque", "crossbeam-utils", @@ -6751,7 +6762,7 @@ dependencies = [ "percent-encoding", "ryu", "sha1_smol", - "socket2", + "socket2 0.5.10", "url", ] @@ -6766,11 +6777,11 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.13" +version = "0.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d04b7d0ee6b4a0207a0a7adb104d23ecb0b47d6beae7152d0fa34b692b29fd6" +checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.4", ] [[package]] @@ -6786,13 +6797,13 @@ dependencies = [ [[package]] name = "redox_users" -version = "0.5.0" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd6f9d3d47bdd2ad6945c5015a226ec6155d0bcdfd8f7cd29f86b71f8de99d2b" +checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac" dependencies = [ "getrandom 0.2.16", "libredox", - "thiserror 2.0.12", + "thiserror 2.0.16", ] [[package]] @@ -6812,14 +6823,14 @@ checksum = "1165225c21bff1f3bbce98f5a1f889949bc902d3575308cc7b0de30b4f6d27c7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] name = "regex" -version = "1.11.1" +version = "1.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +checksum = "23d7fd106d8c02486a8d64e778353d1cffe08ce79ac2e82f540c86d0facf6912" dependencies = [ "aho-corasick", "memchr", @@ -6829,9 +6840,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +checksum = "6b9458fa0bfeeac22b5ca447c63aaf45f28439a709ccd244698632f9aa6394d6" dependencies = [ "aho-corasick", "memchr", @@ -6840,15 +6851,15 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +checksum = "caf4aa5b0f434c91fe5c7f1ecb6a5ece2130b02ad2a590589dda5146df959001" [[package]] name = "reqwest" -version = "0.12.21" +version = "0.12.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c8cea6b35bcceb099f30173754403d2eba0a5dc18cea3630fccd88251909288" +checksum = "d429f34c8092b2d42c7c93cec323bb4adeb7c67698f70839adec842ec10c7ceb" dependencies = [ "base64 0.22.1", "bytes", @@ -6890,14 +6901,14 @@ dependencies = [ "wasm-bindgen-futures", "wasm-streams", "web-sys", - "webpki-roots 1.0.1", + "webpki-roots 1.0.2", ] [[package]] name = "resolv-conf" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95325155c684b1c89f7765e30bc1c42e4a6da51ca513615660cb8a62ef9a88e3" +checksum = "6b3789b30bd25ba102de4beabd95d21ac45b69b1be7d14522bab988c526d6799" [[package]] name = "reth-basic-payload-builder" @@ -6937,7 +6948,7 @@ dependencies = [ "metrics", "parking_lot", "pin-project", - "rand 0.9.1", + "rand 0.9.2", "reth-chainspec", "reth-errors", "reth-ethereum-primitives", @@ -7001,7 +7012,7 @@ dependencies = [ "backon", "clap", "comfy-table", - "crossterm", + "crossterm 0.28.1", "eyre", "fdlimit", "futures", @@ -7087,7 +7098,7 @@ dependencies = [ "reth-fs-util", "secp256k1 0.30.0", "serde", - "thiserror 2.0.12", + "thiserror 2.0.16", ] [[package]] @@ -7118,7 +7129,7 @@ dependencies = [ "convert_case", "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -7146,7 +7157,7 @@ dependencies = [ "auto_impl", "reth-execution-types", "reth-primitives-traits", - "thiserror 2.0.12", + "thiserror 2.0.16", ] [[package]] @@ -7206,10 +7217,10 @@ dependencies = [ "reth-storage-errors", "reth-tracing", "rustc-hash 2.1.1", - "strum 0.27.1", + "strum 0.27.2", "sysinfo", "tempfile", - "thiserror 2.0.12", + "thiserror 2.0.16", ] [[package]] @@ -7266,7 +7277,7 @@ dependencies = [ "reth-trie-db", "serde", "serde_json", - "thiserror 2.0.12", + "thiserror 2.0.16", "tracing", ] @@ -7305,7 +7316,7 @@ dependencies = [ "schnellru", "secp256k1 0.30.0", "serde", - "thiserror 2.0.12", + "thiserror 2.0.16", "tokio", "tokio-stream", "tracing", @@ -7324,13 +7335,13 @@ dependencies = [ "futures", "itertools 0.14.0", "metrics", - "rand 0.9.1", + "rand 0.9.2", "reth-chainspec", "reth-ethereum-forks", "reth-metrics", "reth-network-peers", "secp256k1 0.30.0", - "thiserror 2.0.12", + "thiserror 2.0.16", "tokio", "tracing", ] @@ -7353,7 +7364,7 @@ dependencies = [ "secp256k1 0.30.0", "serde", "serde_with", - "thiserror 2.0.12", + "thiserror 2.0.16", "tokio", "tokio-stream", "tracing", @@ -7387,7 +7398,7 @@ dependencies = [ "reth-tasks", "reth-testing-utils", "tempfile", - "thiserror 2.0.12", + "thiserror 2.0.16", "tokio", "tokio-stream", "tokio-util", @@ -7474,7 +7485,7 @@ dependencies = [ "secp256k1 0.30.0", "sha2 0.10.9", "sha3", - "thiserror 2.0.12", + "thiserror 2.0.16", "tokio", "tokio-stream", "tokio-util", @@ -7527,7 +7538,7 @@ dependencies = [ "reth-primitives-traits", "reth-trie-common", "serde", - "thiserror 2.0.12", + "thiserror 2.0.16", "tokio", ] @@ -7551,7 +7562,7 @@ dependencies = [ "reth-prune", "reth-stages-api", "reth-tasks", - "thiserror 2.0.12", + "thiserror 2.0.16", ] [[package]] @@ -7603,7 +7614,7 @@ dependencies = [ "revm-primitives", "schnellru", "smallvec", - "thiserror 2.0.12", + "thiserror 2.0.16", "tokio", "tracing", ] @@ -7649,7 +7660,7 @@ dependencies = [ "ethereum_ssz_derive", "reth-ethereum-primitives", "snap", - "thiserror 2.0.12", + "thiserror 2.0.16", ] [[package]] @@ -7697,7 +7708,7 @@ dependencies = [ "reth-consensus", "reth-execution-errors", "reth-storage-errors", - "thiserror 2.0.12", + "thiserror 2.0.16", ] [[package]] @@ -7721,7 +7732,7 @@ dependencies = [ "reth-primitives-traits", "serde", "snap", - "thiserror 2.0.12", + "thiserror 2.0.16", "tokio", "tokio-stream", "tokio-util", @@ -7746,7 +7757,7 @@ dependencies = [ "reth-ethereum-primitives", "reth-primitives-traits", "serde", - "thiserror 2.0.12", + "thiserror 2.0.16", ] [[package]] @@ -7780,7 +7791,7 @@ dependencies = [ "reth-primitives-traits", "serde", "sha2 0.10.9", - "thiserror 2.0.12", + "thiserror 2.0.16", ] [[package]] @@ -7906,7 +7917,7 @@ dependencies = [ "alloy-rlp", "nybbles", "reth-storage-errors", - "thiserror 2.0.12", + "thiserror 2.0.16", ] [[package]] @@ -7959,7 +7970,7 @@ dependencies = [ "reth-tasks", "reth-tracing", "rmp-serde", - "thiserror 2.0.12", + "thiserror 2.0.16", "tokio", "tokio-util", "tracing", @@ -7986,7 +7997,7 @@ source = "git+https://github.com/paradigmxyz/reth?tag=v1.7.0#9d56da53ec0ad60e229 dependencies = [ "serde", "serde_json", - "thiserror 2.0.12", + "thiserror 2.0.16", ] [[package]] @@ -8028,7 +8039,7 @@ dependencies = [ "jsonrpsee 0.26.0", "pin-project", "serde_json", - "thiserror 2.0.12", + "thiserror 2.0.16", "tokio", "tokio-stream", "tokio-util", @@ -8041,15 +8052,15 @@ name = "reth-libmdbx" version = "1.7.0" source = "git+https://github.com/paradigmxyz/reth?tag=v1.7.0#9d56da53ec0ad60e229456a0c70b338501d923a5" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.4", "byteorder", "dashmap 6.1.0", "derive_more", - "indexmap 2.10.0", + "indexmap 2.11.3", "parking_lot", "reth-mdbx-sys", "smallvec", - "thiserror 2.0.12", + "thiserror 2.0.16", "tracing", ] @@ -8091,7 +8102,7 @@ dependencies = [ "if-addrs", "reqwest", "serde_with", - "thiserror 2.0.12", + "thiserror 2.0.16", "tokio", "tracing", ] @@ -8116,7 +8127,7 @@ dependencies = [ "parking_lot", "pin-project", "rand 0.8.5", - "rand 0.9.1", + "rand 0.9.2", "reth-chainspec", "reth-consensus", "reth-discv4", @@ -8144,7 +8155,7 @@ dependencies = [ "secp256k1 0.30.0", "serde", "smallvec", - "thiserror 2.0.12", + "thiserror 2.0.16", "tokio", "tokio-stream", "tokio-util", @@ -8171,7 +8182,7 @@ dependencies = [ "reth-network-types", "reth-tokio-util", "serde", - "thiserror 2.0.12", + "thiserror 2.0.16", "tokio", "tokio-stream", ] @@ -8209,7 +8220,7 @@ dependencies = [ "enr", "secp256k1 0.30.0", "serde_with", - "thiserror 2.0.12", + "thiserror 2.0.16", "tokio", "url", ] @@ -8240,7 +8251,7 @@ dependencies = [ "memmap2", "reth-fs-util", "serde", - "thiserror 2.0.12", + "thiserror 2.0.16", "tracing", "zstd", ] @@ -8323,7 +8334,7 @@ dependencies = [ "reth-rpc-builder", "reth-rpc-engine-api", "reth-rpc-eth-types", - "reth-rpc-layer 1.7.0", + "reth-rpc-layer", "reth-stages", "reth-static-file", "reth-tasks", @@ -8352,7 +8363,7 @@ dependencies = [ "eyre", "futures", "humantime", - "rand 0.9.1", + "rand 0.9.2", "reth-chainspec", "reth-cli-util", "reth-config", @@ -8380,8 +8391,8 @@ dependencies = [ "secp256k1 0.30.0", "serde", "shellexpand", - "strum 0.27.1", - "thiserror 2.0.12", + "strum 0.27.2", + "thiserror 2.0.16", "toml", "tracing", "url", @@ -8443,7 +8454,7 @@ dependencies = [ "reth-transaction-pool", "serde", "serde_json", - "thiserror 2.0.12", + "thiserror 2.0.16", "tokio", "tokio-stream", "tokio-tungstenite", @@ -8532,7 +8543,7 @@ dependencies = [ "serde", "serde_json", "tar-no-std", - "thiserror 2.0.12", + "thiserror 2.0.16", ] [[package]] @@ -8603,7 +8614,7 @@ dependencies = [ "reth-storage-errors", "reth-trie-common", "revm", - "thiserror 2.0.12", + "thiserror 2.0.16", "tracing", ] @@ -8632,7 +8643,7 @@ dependencies = [ "reth-rpc-eth-api", "reth-storage-errors", "revm", - "thiserror 2.0.12", + "thiserror 2.0.16", ] [[package]] @@ -8758,7 +8769,7 @@ dependencies = [ "revm", "serde", "sha2 0.10.9", - "thiserror 2.0.12", + "thiserror 2.0.16", "tracing", ] @@ -8834,7 +8845,7 @@ dependencies = [ "reth-transaction-pool", "revm", "serde_json", - "thiserror 2.0.12", + "thiserror 2.0.16", "tokio", "tower 0.5.2", "tracing", @@ -8887,7 +8898,7 @@ dependencies = [ "reth-storage-api", "reth-transaction-pool", "serde", - "thiserror 2.0.12", + "thiserror 2.0.16", "tokio", "tracing", ] @@ -8940,7 +8951,7 @@ dependencies = [ "reth-errors", "reth-primitives-traits", "serde", - "thiserror 2.0.12", + "thiserror 2.0.16", "tokio", ] @@ -9008,7 +9019,7 @@ dependencies = [ "secp256k1 0.30.0", "serde", "serde_with", - "thiserror 2.0.12", + "thiserror 2.0.16", ] [[package]] @@ -9051,7 +9062,7 @@ dependencies = [ "reth-trie-db", "revm-database", "revm-state", - "strum 0.27.1", + "strum 0.27.2", "tokio", "tracing", ] @@ -9079,7 +9090,7 @@ dependencies = [ "reth-static-file-types", "reth-tokio-util", "rustc-hash 2.1.1", - "thiserror 2.0.12", + "thiserror 2.0.16", "tokio", "tracing", ] @@ -9095,7 +9106,7 @@ dependencies = [ "modular-bitfield", "reth-codecs", "serde", - "thiserror 2.0.12", + "thiserror 2.0.16", ] [[package]] @@ -9181,7 +9192,7 @@ dependencies = [ "serde", "serde_json", "sha2 0.10.9", - "thiserror 2.0.12", + "thiserror 2.0.16", "tokio", "tokio-stream", "tower 0.5.2", @@ -9241,13 +9252,13 @@ dependencies = [ "reth-rpc-api", "reth-rpc-eth-api", "reth-rpc-eth-types", - "reth-rpc-layer 1.7.0", + "reth-rpc-layer", "reth-rpc-server-types", "reth-storage-api", "reth-tasks", "reth-transaction-pool", "serde", - "thiserror 2.0.12", + "thiserror 2.0.16", "tokio", "tokio-util", "tower 0.5.2", @@ -9277,7 +9288,7 @@ dependencies = [ "reth-primitives-traits", "reth-storage-api", "revm-context", - "thiserror 2.0.12", + "thiserror 2.0.16", ] [[package]] @@ -9305,7 +9316,7 @@ dependencies = [ "reth-tasks", "reth-transaction-pool", "serde", - "thiserror 2.0.12", + "thiserror 2.0.16", "tokio", "tracing", ] @@ -9374,7 +9385,7 @@ dependencies = [ "jsonrpsee-core 0.26.0", "jsonrpsee-types 0.26.0", "metrics", - "rand 0.9.1", + "rand 0.9.2", "reqwest", "reth-chain-state", "reth-chainspec", @@ -9395,26 +9406,12 @@ dependencies = [ "revm-inspectors", "schnellru", "serde", - "thiserror 2.0.12", + "thiserror 2.0.16", "tokio", "tokio-stream", "tracing", ] -[[package]] -name = "reth-rpc-layer" -version = "1.4.7" -source = "git+https://github.com/paradigmxyz/reth.git?tag=v1.4.7#dc7cb6e6670b0da294a0e5010e02855f5aaf6b49" -dependencies = [ - "alloy-rpc-types-engine", - "http", - "jsonrpsee-http-client 0.25.1 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project", - "tower 0.5.2", - "tower-http", - "tracing", -] - [[package]] name = "reth-rpc-layer" version = "1.7.0" @@ -9442,7 +9439,7 @@ dependencies = [ "reth-errors", "reth-network-api", "serde", - "strum 0.27.1", + "strum 0.27.2", ] [[package]] @@ -9488,7 +9485,7 @@ dependencies = [ "reth-trie", "reth-trie-db", "tempfile", - "thiserror 2.0.12", + "thiserror 2.0.16", "tokio", "tracing", ] @@ -9515,7 +9512,7 @@ dependencies = [ "reth-static-file", "reth-static-file-types", "reth-tokio-util", - "thiserror 2.0.12", + "thiserror 2.0.16", "tokio", "tracing", ] @@ -9563,7 +9560,7 @@ dependencies = [ "clap", "derive_more", "serde", - "strum 0.27.1", + "strum 0.27.2", ] [[package]] @@ -9602,7 +9599,7 @@ dependencies = [ "reth-prune-types", "reth-static-file-types", "revm-database-interface", - "thiserror 2.0.12", + "thiserror 2.0.16", ] [[package]] @@ -9617,7 +9614,7 @@ dependencies = [ "pin-project", "rayon", "reth-metrics", - "thiserror 2.0.12", + "thiserror 2.0.16", "tokio", "tracing", "tracing-futures", @@ -9633,7 +9630,7 @@ dependencies = [ "alloy-genesis", "alloy-primitives", "rand 0.8.5", - "rand 0.9.1", + "rand 0.9.2", "reth-ethereum-primitives", "reth-primitives-traits", "secp256k1 0.30.0", @@ -9675,13 +9672,13 @@ dependencies = [ "alloy-rlp", "aquamarine", "auto_impl", - "bitflags 2.9.1", + "bitflags 2.9.4", "futures-util", "metrics", "parking_lot", "paste", "pin-project", - "rand 0.9.1", + "rand 0.9.2", "reth-chain-state", "reth-chainspec", "reth-eth-wire-types", @@ -9699,7 +9696,7 @@ dependencies = [ "serde", "serde_json", "smallvec", - "thiserror 2.0.12", + "thiserror 2.0.16", "tokio", "tokio-stream", "tracing", @@ -9789,7 +9786,7 @@ dependencies = [ "reth-trie-common", "reth-trie-db", "reth-trie-sparse", - "thiserror 2.0.12", + "thiserror 2.0.16", "tokio", "tracing", ] @@ -9982,7 +9979,7 @@ dependencies = [ "revm", "serde", "serde_json", - "thiserror 2.0.12", + "thiserror 2.0.16", ] [[package]] @@ -10041,7 +10038,7 @@ version = "7.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f64fbacb86008394aaebd3454f9643b7d5a782bd251135e17c5b33da592d84d" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.4", "revm-bytecode", "revm-primitives", "serde", @@ -10153,18 +10150,23 @@ dependencies = [ "alloy-consensus", "alloy-eips", "alloy-primitives", + "alloy-rlp", "alloy-rpc-types-engine", "alloy-rpc-types-eth", "alloy-serde", "anyhow", + "arbitrary", "assert_cmd", + "blake3", "bytes", "clap", "ctor", "dashmap 6.1.0", "dotenvy", + "ed25519-dalek", "eyre", "futures", + "hex", "http", "http-body-util", "hyper", @@ -10184,16 +10186,17 @@ dependencies = [ "parking_lot", "paste", "predicates", - "rand 0.9.1", + "rand 0.9.2", "reqwest", "reth-optimism-payload-builder", - "reth-rpc-layer 1.4.7", + "reth-rpc-layer", "rustls", "serde", "serde_json", "sha2 0.10.9", + "tempfile", "testcontainers", - "thiserror 2.0.12", + "thiserror 2.0.16", "time", "tokio", "tokio-tungstenite", @@ -10216,9 +10219,9 @@ checksum = "afab94fb28594581f62d981211a9a4d53cc8130bbcbbb89a0440d9b8e81a7746" [[package]] name = "rug" -version = "1.27.0" +version = "1.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4207e8d668e5b8eb574bda8322088ccd0d7782d3d03c7e8d562e82ed82bdcbc3" +checksum = "58ad2e973fe3c3214251a840a621812a4f40468da814b1a3d6947d433c2af11f" dependencies = [ "az", "gmp-mpfr-sys", @@ -10228,9 +10231,9 @@ dependencies = [ [[package]] name = "ruint" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11256b5fe8c68f56ac6f39ef0720e592f33d2367a4782740d9c9142e889c7fb4" +checksum = "9ecb38f82477f20c5c3d62ef52d7c4e536e38ea9b73fb570a20c5cae0e14bcf6" dependencies = [ "alloy-rlp", "arbitrary", @@ -10246,7 +10249,7 @@ dependencies = [ "primitive-types", "proptest", "rand 0.8.5", - "rand 0.9.1", + "rand 0.9.2", "rlp", "ruint-macro", "serde", @@ -10262,9 +10265,9 @@ checksum = "48fd7bd8a6377e15ad9d42a8ec25371b94ddc67abe7c8b9127bec79bebaaae18" [[package]] name = "rustc-demangle" -version = "0.1.25" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "989e6739f80c4ad5b13e0fd7fe89531180375b18520cc8c82080e4dc4035b84f" +checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" [[package]] name = "rustc-hash" @@ -10302,7 +10305,7 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ - "semver 1.0.26", + "semver 1.0.27", ] [[package]] @@ -10311,7 +10314,7 @@ version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.4", "errno", "libc", "linux-raw-sys 0.4.15", @@ -10320,22 +10323,22 @@ dependencies = [ [[package]] name = "rustix" -version = "1.0.7" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266" +checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.4", "errno", "libc", - "linux-raw-sys 0.9.4", - "windows-sys 0.59.0", + "linux-raw-sys 0.11.0", + "windows-sys 0.61.0", ] [[package]] name = "rustls" -version = "0.23.28" +version = "0.23.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7160e3e10bf4535308537f3c4e1641468cd0e485175d6163087c0393c7d46643" +checksum = "c0ebcbd2f03de0fc1122ad9bb24b127a5a6cd51d72604a3f3c50ac459762b6cc" dependencies = [ "aws-lc-rs", "log", @@ -10356,7 +10359,7 @@ dependencies = [ "openssl-probe", "rustls-pki-types", "schannel", - "security-framework 3.2.0", + "security-framework 3.4.0", ] [[package]] @@ -10393,7 +10396,7 @@ dependencies = [ "rustls-native-certs", "rustls-platform-verifier-android", "rustls-webpki", - "security-framework 3.2.0", + "security-framework 3.4.0", "security-framework-sys", "webpki-root-certs 0.26.11", "windows-sys 0.59.0", @@ -10407,9 +10410,9 @@ checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" [[package]] name = "rustls-webpki" -version = "0.103.3" +version = "0.103.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4a72fe2bcf7a6ac6fd7d0b9e5cb68aeb7d4c0a0271730218b3e92d43b4eb435" +checksum = "0a17884ae0c1b773f1ccd2bd4a8c72f16da897310a98b0e84bf349ad5ead92fc" dependencies = [ "aws-lc-rs", "ring", @@ -10419,9 +10422,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.21" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] name = "rusty-fork" @@ -10452,11 +10455,11 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" +checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.61.0", ] [[package]] @@ -10473,9 +10476,9 @@ dependencies = [ [[package]] name = "schemars" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1375ba8ef45a6f15d83fa8748f1079428295d403d6ea991d09ab100155fbc06d" +checksum = "82d20c4491bc164fa2f6c5d44565947a52ad80b9505d8e36f8d54c27c739fcd0" dependencies = [ "dyn-clone", "ref-cast", @@ -10540,7 +10543,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c3c81b43dc2d8877c216a3fccf76677ee1ebccd429566d3e67447290d0c42b2" dependencies = [ "bitcoin_hashes", - "rand 0.9.1", + "rand 0.9.2", "secp256k1-sys 0.11.0", ] @@ -10568,7 +10571,7 @@ version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.4", "core-foundation 0.9.4", "core-foundation-sys", "libc", @@ -10577,11 +10580,11 @@ dependencies = [ [[package]] name = "security-framework" -version = "3.2.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271720403f46ca04f7ba6f55d438f8bd878d6b8ca0a1046e8228c4145bcbb316" +checksum = "60b369d18893388b345804dc0007963c99b7d665ae71d275812d828c6f089640" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.4", "core-foundation 0.10.1", "core-foundation-sys", "libc", @@ -10590,9 +10593,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.14.0" +version = "2.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" +checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0" dependencies = [ "core-foundation-sys", "libc", @@ -10609,11 +10612,12 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.26" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" +checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" dependencies = [ "serde", + "serde_core", ] [[package]] @@ -10639,45 +10643,57 @@ checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" [[package]] name = "serde" -version = "1.0.219" +version = "1.0.225" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +checksum = "fd6c24dee235d0da097043389623fb913daddf92c76e9f5a1db88607a0bcbd1d" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.225" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "659356f9a0cb1e529b24c01e43ad2bdf520ec4ceaf83047b83ddcc2251f96383" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.219" +version = "1.0.225" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +checksum = "0ea936adf78b1f766949a4977b91d2f5595825bd6ec079aa9543ad2685fc4516" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] name = "serde_json" -version = "1.0.143" +version = "1.0.145" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d401abef1d108fbd9cbaebc3e46611f4b1021f714a0597a71f41ee463f5f4a5a" +checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" dependencies = [ - "indexmap 2.10.0", + "indexmap 2.11.3", "itoa", "memchr", "ryu", "serde", + "serde_core", ] [[package]] name = "serde_path_to_error" -version = "0.1.17" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59fab13f937fa393d08645bf3a84bdfe86e296747b506ada67bb15f10f218b2a" +checksum = "10a9ff822e371bb5403e391ecd83e182e0e77ba7f6fe0160b795797109d1b457" dependencies = [ "itoa", "serde", + "serde_core", ] [[package]] @@ -10688,7 +10704,7 @@ checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -10722,9 +10738,9 @@ dependencies = [ "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.10.0", + "indexmap 2.11.3", "schemars 0.9.0", - "schemars 1.0.3", + "schemars 1.0.4", "serde", "serde_derive", "serde_json", @@ -10741,7 +10757,7 @@ dependencies = [ "darling 0.20.11", "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -10862,9 +10878,9 @@ dependencies = [ [[package]] name = "signal-hook-registry" -version = "1.4.5" +version = "1.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9203b8055f63a2a00e2f593bb0510367fe707d7ff1e5c872de2f537b339e5410" +checksum = "b2a4719bff48cee6b39d12c020eeb490953ad2443b7055bd0b21fca26bd8c28b" dependencies = [ "libc", ] @@ -10887,7 +10903,7 @@ checksum = "297f631f50729c8c99b84667867963997ec0b50f32b2a7dbcab828ef0541e8bb" dependencies = [ "num-bigint", "num-traits", - "thiserror 2.0.12", + "thiserror 2.0.16", "time", ] @@ -10950,6 +10966,16 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "socket2" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807" +dependencies = [ + "libc", + "windows-sys 0.59.0", +] + [[package]] name = "soketto" version = "0.8.1" @@ -11003,7 +11029,7 @@ dependencies = [ "proc-macro2", "quote", "structmeta-derive", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -11014,7 +11040,7 @@ checksum = "152a0b65a590ff6c3da95cabe2353ee04e6167c896b28e3b14478c2636c922fc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -11028,11 +11054,11 @@ dependencies = [ [[package]] name = "strum" -version = "0.27.1" +version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f64def088c51c9510a8579e3c5d67c65349dcf755e5479ad3d010aa6454e2c32" +checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf" dependencies = [ - "strum_macros 0.27.1", + "strum_macros 0.27.2", ] [[package]] @@ -11045,20 +11071,19 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] name = "strum_macros" -version = "0.27.1" +version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c77a8c5abcaf0f9ce05d62342b7d298c346515365c36b673df4ebe3ced01fde8" +checksum = "7695ce3845ea4b33927c055a39dc438a45b059f7c1b3d91d38d10355fb8cbca7" dependencies = [ "heck", "proc-macro2", "quote", - "rustversion", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -11080,9 +11105,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.104" +version = "2.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" +checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" dependencies = [ "proc-macro2", "quote", @@ -11098,7 +11123,7 @@ dependencies = [ "paste", "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -11118,7 +11143,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -11140,7 +11165,7 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.4", "core-foundation 0.9.4", "system-configuration-sys", ] @@ -11180,27 +11205,26 @@ dependencies = [ [[package]] name = "tar-no-std" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15574aa79d3c04a12f3cb53ff976d5571e53b9d8e0bdbe4021df0a06473dd1c9" +checksum = "ac9ee8b664c9f1740cd813fea422116f8ba29997bb7c878d1940424889802897" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.4", "log", - "memchr", "num-traits", ] [[package]] name = "tempfile" -version = "3.20.0" +version = "3.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1" +checksum = "84fa4d11fadde498443cca10fd3ac23c951f0dc59e080e9f4b93d4df4e4eea53" dependencies = [ "fastrand", "getrandom 0.3.3", "once_cell", - "rustix 1.0.7", - "windows-sys 0.59.0", + "rustix 1.1.2", + "windows-sys 0.61.0", ] [[package]] @@ -11230,7 +11254,7 @@ dependencies = [ "serde", "serde_json", "serde_with", - "thiserror 2.0.12", + "thiserror 2.0.16", "tokio", "tokio-stream", "tokio-tar", @@ -11258,11 +11282,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.12" +version = "2.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" +checksum = "3467d614147380f2e4e374161426ff399c91084acd2363eaf549172b3d5e60c0" dependencies = [ - "thiserror-impl 2.0.12", + "thiserror-impl 2.0.16", ] [[package]] @@ -11273,18 +11297,18 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] name = "thiserror-impl" -version = "2.0.12" +version = "2.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" +checksum = "6c5e1be1c48b9172ee610da68fd9cd2770e7a4056cb3fc98710ee6906f0c7960" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -11307,12 +11331,11 @@ dependencies = [ [[package]] name = "time" -version = "0.3.41" +version = "0.3.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" +checksum = "83bde6f1ec10e72d583d91623c939f623002284ef622b87de38cfd546cbf2031" dependencies = [ "deranged", - "itoa", "libc", "num-conv", "num_threads", @@ -11324,15 +11347,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.4" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" +checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b" [[package]] name = "time-macros" -version = "0.2.22" +version = "0.2.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" +checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3" dependencies = [ "num-conv", "time-core", @@ -11359,9 +11382,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09b3661f17e86524eccd4371ab0429194e0d7c008abb45f7a7495b1719463c71" +checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" dependencies = [ "tinyvec_macros", ] @@ -11374,20 +11397,22 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.45.1" +version = "1.47.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75ef51a33ef1da925cea3e4eb122833cb377c61439ca401b770f54902b806779" +checksum = "89e49afdadebb872d3145a5638b59eb0691ea23e46ca484037cfab3b76b95038" dependencies = [ "backtrace", "bytes", + "io-uring", "libc", "mio", "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2", + "slab", + "socket2 0.6.0", "tokio-macros", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -11398,7 +11423,7 @@ checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -11469,9 +11494,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.15" +version = "0.7.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66a539a9ad6d5d281510d5bd368c973d636c02dbf8a67300bfb6b950696ad7df" +checksum = "14307c986784f72ef81c89db7d9e28d6ac26d16213b109ea501696195e6e3ce5" dependencies = [ "bytes", "futures-core", @@ -11490,8 +11515,8 @@ checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" dependencies = [ "serde", "serde_spanned", - "toml_datetime", - "toml_edit", + "toml_datetime 0.6.11", + "toml_edit 0.22.27", ] [[package]] @@ -11503,20 +11528,50 @@ dependencies = [ "serde", ] +[[package]] +name = "toml_datetime" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a197c0ec7d131bfc6f7e82c8442ba1595aeab35da7adbf05b6b73cd06a16b6be" +dependencies = [ + "serde_core", +] + [[package]] name = "toml_edit" version = "0.22.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" dependencies = [ - "indexmap 2.10.0", + "indexmap 2.11.3", "serde", "serde_spanned", - "toml_datetime", + "toml_datetime 0.6.11", "toml_write", "winnow", ] +[[package]] +name = "toml_edit" +version = "0.23.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2ad0b7ae9cfeef5605163839cb9221f453399f15cfb5c10be9885fcf56611f9" +dependencies = [ + "indexmap 2.11.3", + "toml_datetime 0.7.1", + "toml_parser", + "winnow", +] + +[[package]] +name = "toml_parser" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b551886f449aa90d4fe2bdaa9f4a2577ad2dde302c61ecf262d80b116db95c10" +dependencies = [ + "winnow", +] + [[package]] name = "toml_write" version = "0.1.2" @@ -11544,7 +11599,7 @@ dependencies = [ "percent-encoding", "pin-project", "prost", - "socket2", + "socket2 0.5.10", "tokio", "tokio-stream", "tower 0.4.13", @@ -11582,7 +11637,7 @@ dependencies = [ "futures-core", "futures-util", "hdrhistogram", - "indexmap 2.10.0", + "indexmap 2.11.3", "pin-project-lite", "slab", "sync_wrapper", @@ -11601,7 +11656,7 @@ checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" dependencies = [ "async-compression", "base64 0.22.1", - "bitflags 2.9.1", + "bitflags 2.9.4", "bytes", "futures-core", "futures-util", @@ -11668,7 +11723,7 @@ checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -11805,7 +11860,7 @@ dependencies = [ "darling 0.20.11", "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -11842,11 +11897,11 @@ dependencies = [ "httparse", "log", "native-tls", - "rand 0.9.1", + "rand 0.9.2", "rustls", "rustls-pki-types", "sha1", - "thiserror 2.0.12", + "thiserror 2.0.16", "utf-8", ] @@ -11900,9 +11955,9 @@ checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" [[package]] name = "unicode-ident" -version = "1.0.18" +version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" +checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d" [[package]] name = "unicode-segmentation" @@ -11963,9 +12018,9 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" -version = "2.5.4" +version = "2.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" +checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b" dependencies = [ "form_urlencoded", "idna", @@ -11993,9 +12048,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.17.0" +version = "1.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cf4199d1e5d15ddd86a694e4d0dffa9c323ce759fea589f00fef9d81cc1931d" +checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2" dependencies = [ "getrandom 0.3.3", "js-sys", @@ -12069,7 +12124,7 @@ checksum = "d674d135b4a8c1d7e813e2f8d1c9a58308aee4a680323066025e53132218bd91" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -12108,44 +12163,54 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasi" -version = "0.14.2+wasi-0.2.4" +version = "0.14.7+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "883478de20367e224c0090af9cf5f9fa85bed63a95c1abf3afc5c083ebc06e8c" +dependencies = [ + "wasip2", +] + +[[package]] +name = "wasip2" +version = "1.0.1+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" dependencies = [ - "wit-bindgen-rt", + "wit-bindgen", ] [[package]] name = "wasm-bindgen" -version = "0.2.100" +version = "0.2.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +checksum = "4ad224d2776649cfb4f4471124f8176e54c1cca67a88108e30a0cd98b90e7ad3" dependencies = [ "cfg-if", "once_cell", "rustversion", "wasm-bindgen-macro", + "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.100" +version = "0.2.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" +checksum = "3a1364104bdcd3c03f22b16a3b1c9620891469f5e9f09bc38b2db121e593e732" dependencies = [ "bumpalo", "log", "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.106", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.50" +version = "0.4.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" +checksum = "9c0a08ecf5d99d5604a6666a70b3cde6ab7cc6142f5e641a8ef48fc744ce8854" dependencies = [ "cfg-if", "js-sys", @@ -12156,9 +12221,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.100" +version = "0.2.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +checksum = "0d7ab4ca3e367bb1ed84ddbd83cc6e41e115f8337ed047239578210214e36c76" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -12166,22 +12231,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.100" +version = "0.2.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +checksum = "4a518014843a19e2dbbd0ed5dfb6b99b23fb886b14e6192a00803a3e14c552b0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.106", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.100" +version = "0.2.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +checksum = "255eb0aa4cc2eea3662a00c2bbd66e93911b7361d5e0fcd62385acfd7e15dcee" dependencies = [ "unicode-ident", ] @@ -12201,9 +12266,9 @@ dependencies = [ [[package]] name = "wasmtimer" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8d49b5d6c64e8558d9b1b065014426f35c18de636895d24893dbbd329743446" +checksum = "1c598d6b99ea013e35844697fc4670d08339d5cda15588f193c6beedd12f644b" dependencies = [ "futures", "js-sys", @@ -12215,9 +12280,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.77" +version = "0.3.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" +checksum = "50462a022f46851b81d5441d1a6f5bac0b21a1d72d64bd4906fbdd4bf7230ec7" dependencies = [ "js-sys", "wasm-bindgen", @@ -12239,14 +12304,14 @@ version = "0.26.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75c7f0ef91146ebfb530314f5f1d24528d7f0767efbfd31dce919275413e393e" dependencies = [ - "webpki-root-certs 1.0.1", + "webpki-root-certs 1.0.2", ] [[package]] name = "webpki-root-certs" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86138b15b2b7d561bc4469e77027b8dd005a43dc502e9031d1f5afc8ce1f280e" +checksum = "4e4ffd8df1c57e87c325000a3d6ef93db75279dc3a231125aac571650f22b12a" dependencies = [ "rustls-pki-types", ] @@ -12257,14 +12322,14 @@ version = "0.26.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9" dependencies = [ - "webpki-roots 1.0.1", + "webpki-roots 1.0.2", ] [[package]] name = "webpki-roots" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8782dd5a41a24eed3a4f40b606249b3e236ca61adf1f25ea4d45c73de122b502" +checksum = "7e8983c3ab33d6fb807cfcdad2491c4ea8cbc8ed839181c7dfd9c67c83e261b2" dependencies = [ "rustls-pki-types", ] @@ -12305,11 +12370,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.9" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.61.0", ] [[package]] @@ -12347,7 +12412,7 @@ dependencies = [ "windows-collections", "windows-core 0.61.2", "windows-future", - "windows-link", + "windows-link 0.1.3", "windows-numerics", ] @@ -12393,11 +12458,24 @@ checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" dependencies = [ "windows-implement 0.60.0", "windows-interface 0.59.1", - "windows-link", + "windows-link 0.1.3", "windows-result 0.3.4", "windows-strings 0.4.2", ] +[[package]] +name = "windows-core" +version = "0.62.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57fe7168f7de578d2d8a05b07fd61870d2e73b4020e9f49aa00da8471723497c" +dependencies = [ + "windows-implement 0.60.0", + "windows-interface 0.59.1", + "windows-link 0.2.0", + "windows-result 0.4.0", + "windows-strings 0.5.0", +] + [[package]] name = "windows-future" version = "0.2.1" @@ -12405,7 +12483,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e" dependencies = [ "windows-core 0.61.2", - "windows-link", + "windows-link 0.1.3", "windows-threading", ] @@ -12417,7 +12495,7 @@ checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -12428,7 +12506,7 @@ checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -12439,7 +12517,7 @@ checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -12450,7 +12528,7 @@ checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -12461,7 +12539,7 @@ checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -12472,7 +12550,7 @@ checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -12481,6 +12559,12 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" +[[package]] +name = "windows-link" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45e46c0661abb7180e7b9c281db115305d49ca1709ab8242adf09666d2173c65" + [[package]] name = "windows-numerics" version = "0.2.0" @@ -12488,7 +12572,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1" dependencies = [ "windows-core 0.61.2", - "windows-link", + "windows-link 0.1.3", ] [[package]] @@ -12497,7 +12581,7 @@ version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b8a9ed28765efc97bbc954883f4e6796c33a06546ebafacbabee9696967499e" dependencies = [ - "windows-link", + "windows-link 0.1.3", "windows-result 0.3.4", "windows-strings 0.4.2", ] @@ -12526,7 +12610,16 @@ version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" dependencies = [ - "windows-link", + "windows-link 0.1.3", +] + +[[package]] +name = "windows-result" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7084dcc306f89883455a206237404d3eaf961e5bd7e0f312f7c91f57eb44167f" +dependencies = [ + "windows-link 0.2.0", ] [[package]] @@ -12545,7 +12638,16 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" dependencies = [ - "windows-link", + "windows-link 0.1.3", +] + +[[package]] +name = "windows-strings" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7218c655a553b0bed4426cf54b20d7ba363ef543b52d515b3e48d7fd55318dda" +dependencies = [ + "windows-link 0.2.0", ] [[package]] @@ -12590,7 +12692,16 @@ version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" dependencies = [ - "windows-targets 0.53.2", + "windows-targets 0.53.3", +] + +[[package]] +name = "windows-sys" +version = "0.61.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e201184e40b2ede64bc2ea34968b28e33622acdbbf37104f0e4a33f7abe657aa" +dependencies = [ + "windows-link 0.2.0", ] [[package]] @@ -12641,10 +12752,11 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.53.2" +version = "0.53.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c66f69fcc9ce11da9966ddb31a40968cad001c5bedeb5c2b82ede4253ab48aef" +checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" dependencies = [ + "windows-link 0.1.3", "windows_aarch64_gnullvm 0.53.0", "windows_aarch64_msvc 0.53.0", "windows_i686_gnu 0.53.0", @@ -12661,7 +12773,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6" dependencies = [ - "windows-link", + "windows-link 0.1.3", ] [[package]] @@ -12846,9 +12958,9 @@ checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" [[package]] name = "winnow" -version = "0.7.11" +version = "0.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74c7b26e3480b707944fc872477815d29a8e429d2f93a1ce000f5fa84a15cbcd" +checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf" dependencies = [ "memchr", ] @@ -12864,13 +12976,10 @@ dependencies = [ ] [[package]] -name = "wit-bindgen-rt" -version = "0.39.0" +name = "wit-bindgen" +version = "0.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" -dependencies = [ - "bitflags 2.9.1", -] +checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" [[package]] name = "writeable" @@ -12891,7 +13000,7 @@ dependencies = [ "pharos", "rustc_version 0.4.1", "send_wrapper 0.6.0", - "thiserror 2.0.12", + "thiserror 2.0.16", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", @@ -12913,7 +13022,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af3a19837351dc82ba89f8a125e22a3c475f05aba604acc023d62b2739ae2909" dependencies = [ "libc", - "rustix 1.0.7", + "rustix 1.1.2", ] [[package]] @@ -12942,28 +13051,28 @@ checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.106", "synstructure", ] [[package]] name = "zerocopy" -version = "0.8.26" +version = "0.8.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" +checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.26" +version = "0.8.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" +checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -12983,7 +13092,7 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.106", "synstructure", ] @@ -13004,7 +13113,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -13020,9 +13129,9 @@ dependencies = [ [[package]] name = "zerovec" -version = "0.11.2" +version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a05eb080e015ba39cc9e23bbe5e7fb04d5fb040350f99f34e338d5fdd294428" +checksum = "e7aa2bd55086f1ab526693ecbe444205da57e25f4489879da80635a46d90e73b" dependencies = [ "yoke", "zerofrom", @@ -13037,7 +13146,7 @@ checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.106", ] [[package]] @@ -13060,9 +13169,9 @@ dependencies = [ [[package]] name = "zstd-sys" -version = "2.0.15+zstd.1.5.7" +version = "2.0.16+zstd.1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb81183ddd97d0c74cedf1d50d85c8d08c1b8b68ee863bdee9e706eedba1a237" +checksum = "91e19ebc2adc8f83e43039e79776e3fda8ca919132d68a1fed6a5faca2683748" dependencies = [ "cc", "pkg-config", diff --git a/Cargo.toml b/Cargo.toml index f0c99548..77f471d3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,6 +9,7 @@ members = [ [workspace.dependencies] rollup-boost = { path = "crates/rollup-boost" } +flashblocks-rpc = { path = "crates/flashblocks-rpc" } tracing = "0.1.4" tracing-subscriber = { version = "0.3.20", features = ["env-filter", "json"] } @@ -20,12 +21,15 @@ serde_json = "1.0.96" metrics = "0.24.0" metrics-derive = "0.1" tokio = { version = "1", features = ["full"] } +tokio-stream = "0.1.17" eyre = "0.6.12" url = "2.2.0" sha2 = { version = "0.10", default-features = false } +arbitrary = { version = "=1.4.2", features = ["derive"] } # Reth deps reth-optimism-payload-builder = { git = "https://github.com/paradigmxyz/reth", tag = "v1.7.0" } +reth-rpc-layer = { git = "https://github.com/paradigmxyz/reth", tag = "v1.7.0" } # Alloy libraries alloy-rpc-types-engine = "1.0.30" @@ -38,6 +42,7 @@ alloy-consensus = "1.0.30" alloy-rpc-types = "1.0.30" alloy-genesis = "1.0.30" alloy-rpc-client = "1.0.30" +alloy-rlp = "0.3.10" alloy-provider = "1.0.30" op-alloy-network = "0.19.1" op-alloy-rpc-types-engine = "0.19.1" diff --git a/Dockerfile b/Dockerfile index ce53fdd2..c41abb37 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,7 +15,7 @@ RUN cargo install sccache --version ^0.9 RUN cargo install cargo-chef --version ^0.1 RUN apt-get update \ - && apt-get install -y clang libclang-dev + && apt-get install -y clang libclang-dev gcc ENV CARGO_HOME=/usr/local/cargo ENV RUSTC_WRAPPER=sccache diff --git a/crates/rollup-boost/Cargo.toml b/crates/rollup-boost/Cargo.toml index ef5785f4..084cd774 100644 --- a/crates/rollup-boost/Cargo.toml +++ b/crates/rollup-boost/Cargo.toml @@ -17,6 +17,7 @@ tokio.workspace = true eyre.workspace = true url.workspace = true sha2.workspace = true +arbitrary.workspace = true reth-optimism-payload-builder.workspace = true op-alloy-rpc-types-engine.workspace = true @@ -24,6 +25,7 @@ alloy-rpc-types-engine.workspace = true alloy-rpc-types-eth.workspace = true alloy-primitives.workspace = true alloy-serde.workspace = true +alloy-rlp.workspace = true tokio-tungstenite.workspace = true metrics-derive.workspace = true @@ -66,7 +68,14 @@ parking_lot = "0.12.3" tokio-util = { version = "0.7.13" } dashmap = "6.1.0" +ed25519-dalek = { version = "2", features = ["serde"] } +blake3 = "1" # fast hashing for payload IDs +hex = "0.4" +bytes = "1.2" + [dev-dependencies] +reth-rpc-layer.workspace = true +tempfile = "3.20.0" rand = "0.9.0" time = { version = "0.3.36", features = ["macros", "formatting", "parsing"] } op-alloy-consensus.workspace = true @@ -76,8 +85,6 @@ anyhow = "1.0" assert_cmd = "2.0.10" predicates = "3.1.2" tokio-util = { version = "0.7.13" } -bytes = "1.2" -reth-rpc-layer = { git = "https://github.com/paradigmxyz/reth.git", tag = "v1.4.7" } ctor = "0.4.1" reqwest = "0.12.15" diff --git a/crates/rollup-boost/src/cli.rs b/crates/rollup-boost/src/cli.rs index 914a770a..1e4774ac 100644 --- a/crates/rollup-boost/src/cli.rs +++ b/crates/rollup-boost/src/cli.rs @@ -13,7 +13,8 @@ use tokio::signal::unix::{SignalKind, signal as unix_signal}; use tracing::{Level, info}; use crate::{ - BlockSelectionPolicy, Flashblocks, FlashblocksArgs, ProxyLayer, RollupBoostServer, RpcClient, + BlockSelectionPolicy, Flashblocks, FlashblocksP2PArgs, FlashblocksP2PKeys, FlashblocksWsArgs, + ProxyLayer, RollupBoostServer, RpcClient, client::rpc::{BuilderArgs, L2ClientArgs}, debug_api::ExecutionMode, get_version, init_metrics, @@ -103,7 +104,10 @@ pub struct RollupBoostArgs { pub ignore_unhealthy_builders: bool, #[clap(flatten)] - pub flashblocks: FlashblocksArgs, + pub flashblocks_p2p: Option, + + #[clap(flatten)] + pub flashblocks_ws: Option, } impl RollupBoostArgs { @@ -127,6 +131,7 @@ impl RollupBoostArgs { l2_auth_jwt, l2_client_args.l2_timeout, PayloadSource::L2, + None, )?; let builder_args = self.builder; @@ -138,65 +143,71 @@ impl RollupBoostArgs { bail!("Missing Builder JWT secret"); }; + let flashblocks_keys = self.flashblocks_p2p.as_ref().map(|fb| FlashblocksP2PKeys { + authorization_sk: fb.flashblocks_authorizer_sk.clone(), + builder_pk: fb.flashblocks_builder_vk.clone(), + }); + let builder_client = RpcClient::new( builder_args.builder_url.clone(), builder_auth_jwt, builder_args.builder_timeout, PayloadSource::Builder, + flashblocks_keys, )?; let (probe_layer, probes) = ProbeLayer::new(); let execution_mode = Arc::new(Mutex::new(self.execution_mode)); - let (rpc_module, health_handle): (RpcModule<()>, _) = if self.flashblocks.flashblocks { - let flashblocks_args = self.flashblocks; - let inbound_url = flashblocks_args.flashblocks_builder_url; - let outbound_addr = SocketAddr::new( - IpAddr::from_str(&flashblocks_args.flashblocks_host)?, - flashblocks_args.flashblocks_port, - ); - - let builder_client = Arc::new(Flashblocks::run( - builder_client.clone(), - inbound_url, - outbound_addr, - flashblocks_args.flashblock_builder_ws_reconnect_ms, - )?); - - let rollup_boost = RollupBoostServer::new( - l2_client, - builder_client, - execution_mode.clone(), - self.block_selection_policy, - probes.clone(), - self.external_state_root, - self.ignore_unhealthy_builders, - ); - - let health_handle = rollup_boost - .spawn_health_check(self.health_check_interval, self.max_unsafe_interval); - - // Spawn the debug server - rollup_boost.start_debug_server(debug_addr.as_str()).await?; - (rollup_boost.try_into()?, health_handle) - } else { - let rollup_boost = RollupBoostServer::new( - l2_client, - Arc::new(builder_client), - execution_mode.clone(), - self.block_selection_policy, - probes.clone(), - self.external_state_root, - self.ignore_unhealthy_builders, - ); - - let health_handle = rollup_boost - .spawn_health_check(self.health_check_interval, self.max_unsafe_interval); - - // Spawn the debug server - rollup_boost.start_debug_server(debug_addr.as_str()).await?; - (rollup_boost.try_into()?, health_handle) - }; + let (rpc_module, health_handle): (RpcModule<()>, _) = + if let Some(flashblocks_ws) = self.flashblocks_ws { + let inbound_url = flashblocks_ws.flashblocks_builder_url; + let outbound_addr = SocketAddr::new( + IpAddr::from_str(&flashblocks_ws.flashblocks_host)?, + flashblocks_ws.flashblocks_port, + ); + + let builder_client = Arc::new(Flashblocks::run( + builder_client.clone(), + inbound_url, + outbound_addr, + flashblocks_ws.flashblock_builder_ws_reconnect_ms, + )?); + + let rollup_boost = RollupBoostServer::new( + l2_client, + builder_client, + execution_mode.clone(), + self.block_selection_policy, + probes.clone(), + self.external_state_root, + self.ignore_unhealthy_builders, + ); + + let health_handle = rollup_boost + .spawn_health_check(self.health_check_interval, self.max_unsafe_interval); + + // Spawn the debug server + rollup_boost.start_debug_server(debug_addr.as_str()).await?; + (rollup_boost.try_into()?, health_handle) + } else { + let rollup_boost = RollupBoostServer::new( + l2_client, + Arc::new(builder_client), + execution_mode.clone(), + self.block_selection_policy, + probes.clone(), + self.external_state_root, + self.ignore_unhealthy_builders, + ); + + let health_handle = rollup_boost + .spawn_health_check(self.health_check_interval, self.max_unsafe_interval); + + // Spawn the debug server + rollup_boost.start_debug_server(debug_addr.as_str()).await?; + (rollup_boost.try_into()?, health_handle) + }; // Build and start the server info!("Starting server on :{}", self.rpc_port); @@ -264,3 +275,265 @@ impl std::str::FromStr for LogFormat { } } } + +#[cfg(test)] +pub mod tests { + use std::result::Result; + + use super::*; + + const SECRET: &str = "f79ae8046bc11c9927afe911db7143c51a806c4a537cc08e0d37140b0192f430"; + const FLASHBLOCKS_SK: &str = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"; + const FLASHBLOCKS_VK: &str = "fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210"; + + #[test] + fn test_parse_args_minimal() -> Result<(), Box> { + let args = RollupBoostArgs::try_parse_from(["rollup-boost"])?; + + assert!(!args.tracing); + assert!(!args.metrics); + assert_eq!(args.rpc_host, "127.0.0.1"); + assert_eq!(args.rpc_port, 8081); + assert!(args.flashblocks_ws.is_none()); + assert!(args.flashblocks_p2p.is_none()); + + Ok(()) + } + + #[test] + fn test_parse_args_missing_flashblocks_flag() -> Result<(), Box> { + let args = RollupBoostArgs::try_parse_from([ + "rollup-boost", + "--builder-jwt-token", + SECRET, + "--l2-jwt-token", + SECRET, + "--flashblocks-authorizer-sk", + FLASHBLOCKS_SK, + "--flashblocks-builder-vk", + FLASHBLOCKS_VK, + ]); + + assert!( + args.is_err(), + "flashblocks args should be invalid without --flashblocks flag" + ); + + Ok(()) + } + + #[test] + fn test_parse_args_with_flashblocks_flag() -> Result<(), Box> { + let args = RollupBoostArgs::try_parse_from([ + "rollup-boost", + "--builder-jwt-token", + SECRET, + "--l2-jwt-token", + SECRET, + "--flashblocks-ws", + "--flashblocks-authorizer-sk", + FLASHBLOCKS_SK, + "--flashblocks-builder-vk", + FLASHBLOCKS_VK, + ])?; + + let flashblocks = args + .flashblocks_ws + .expect("flashblocks should be Some when flag is passed"); + assert!(flashblocks.flashblocks_ws); + + Ok(()) + } + + #[test] + fn test_parse_args_with_flashblocks_custom_values() -> Result<(), Box> { + let args = RollupBoostArgs::try_parse_from([ + "rollup-boost", + "--builder-jwt-token", + SECRET, + "--l2-jwt-token", + SECRET, + "--flashblocks-ws", + "--flashblocks-authorizer-sk", + FLASHBLOCKS_SK, + "--flashblocks-builder-vk", + FLASHBLOCKS_VK, + ])?; + + let flashblocks = args + .flashblocks_ws + .expect("flashblocks should be Some when flag is passed"); + assert!(flashblocks.flashblocks_ws); + + Ok(()) + } + + #[test] + fn test_parse_args_with_all_options() -> Result<(), Box> { + let args = RollupBoostArgs::try_parse_from([ + "rollup-boost", + "--builder-jwt-token", + SECRET, + "--l2-jwt-token", + SECRET, + "--health-check-interval", + "120", + "--max-unsafe-interval", + "20", + "--rpc-host", + "0.0.0.0", + "--rpc-port", + "9090", + "--tracing", + "--metrics", + "--metrics-host", + "192.168.1.1", + "--metrics-port", + "8080", + "--log-level", + "debug", + "--log-format", + "json", + "--debug-host", + "localhost", + "--debug-server-port", + "6666", + "--execution-mode", + "disabled", + "--flashblocks-ws", + "--flashblocks-authorizer-sk", + FLASHBLOCKS_SK, + "--flashblocks-builder-vk", + FLASHBLOCKS_VK, + ])?; + + assert_eq!(args.health_check_interval, 120); + assert_eq!(args.max_unsafe_interval, 20); + assert_eq!(args.rpc_host, "0.0.0.0"); + assert_eq!(args.rpc_port, 9090); + assert!(args.tracing); + assert!(args.metrics); + assert_eq!(args.metrics_host, "192.168.1.1"); + assert_eq!(args.metrics_port, 8080); + assert_eq!(args.log_level, Level::DEBUG); + assert_eq!(args.debug_host, "localhost"); + assert_eq!(args.debug_server_port, 6666); + + let flashblocks = args + .flashblocks_ws + .expect("flashblocks should be Some when flag is passed"); + assert!(flashblocks.flashblocks_ws); + + Ok(()) + } + + #[test] + fn test_parse_args_missing_jwt_succeeds_at_parse_time() { + // JWT validation happens at runtime, not parse time, so this should succeed + let result = + RollupBoostArgs::try_parse_from(["rollup-boost", "--builder-jwt-token", SECRET]); + + assert!(result.is_ok()); + let args = result.unwrap(); + assert!(args.builder.builder_jwt_token.is_some()); + assert!(args.l2_client.l2_jwt_token.is_none()); + } + + #[test] + fn test_parse_args_invalid_flashblocks_sk() { + let result = RollupBoostArgs::try_parse_from([ + "rollup-boost", + "--builder-jwt-token", + SECRET, + "--l2-jwt-token", + SECRET, + "--flashblocks-ws", + "--flashblocks-authorizer-sk", + "invalid_hex", + "--flashblocks-builder-vk", + FLASHBLOCKS_VK, + ]); + + assert!(result.is_err()); + } + + #[test] + fn test_parse_args_invalid_flashblocks_vk() { + let result = RollupBoostArgs::try_parse_from([ + "rollup-boost", + "--builder-jwt-token", + SECRET, + "--l2-jwt-token", + SECRET, + "--flashblocks-ws", + "--flashblocks-authorizer-sk", + FLASHBLOCKS_SK, + "--flashblocks-builder-vk", + "invalid_hex", + ]); + + assert!(result.is_err()); + } + + #[test] + fn test_log_format_parsing() -> Result<(), Box> { + let json_args = RollupBoostArgs::try_parse_from([ + "rollup-boost", + "--builder-jwt-token", + SECRET, + "--l2-jwt-token", + SECRET, + "--log-format", + "json", + ])?; + + match json_args.log_format { + LogFormat::Json => {} + LogFormat::Text => panic!("Expected Json format"), + } + + let text_args = RollupBoostArgs::try_parse_from([ + "rollup-boost", + "--builder-jwt-token", + SECRET, + "--l2-jwt-token", + SECRET, + "--log-format", + "text", + ])?; + + match text_args.log_format { + LogFormat::Text => {} + LogFormat::Json => panic!("Expected Text format"), + } + + Ok(()) + } + + #[test] + fn test_parse_args_with_jwt_paths() -> Result<(), Box> { + use std::io::Write; + use tempfile::NamedTempFile; + + let mut builder_jwt_file = NamedTempFile::new()?; + writeln!(builder_jwt_file, "{}", SECRET)?; + let builder_jwt_path = builder_jwt_file.path(); + + let mut l2_jwt_file = NamedTempFile::new()?; + writeln!(l2_jwt_file, "{}", SECRET)?; + let l2_jwt_path = l2_jwt_file.path(); + + let args = RollupBoostArgs::try_parse_from([ + "rollup-boost", + "--builder-jwt-path", + builder_jwt_path.to_str().unwrap(), + "--l2-jwt-path", + l2_jwt_path.to_str().unwrap(), + ])?; + + assert!(args.builder.builder_jwt_path.is_some()); + assert!(args.l2_client.l2_jwt_path.is_some()); + + Ok(()) + } +} diff --git a/crates/rollup-boost/src/client/rpc.rs b/crates/rollup-boost/src/client/rpc.rs index 6633e643..995e3e4b 100644 --- a/crates/rollup-boost/src/client/rpc.rs +++ b/crates/rollup-boost/src/client/rpc.rs @@ -1,8 +1,8 @@ -use crate::EngineApiExt; use crate::client::auth::AuthLayer; use crate::payload::{NewPayload, OpExecutionPayloadEnvelope, PayloadSource, PayloadVersion}; use crate::server::EngineApiClient; use crate::version::{CARGO_PKG_VERSION, VERGEN_GIT_SHA}; +use crate::{Authorization, EngineApiExt, FlashblocksEngineApiClient}; use alloy_primitives::{B256, Bytes}; use alloy_rpc_types_engine::{ ExecutionPayloadV3, ForkchoiceState, ForkchoiceUpdated, JwtError, JwtSecret, PayloadId, @@ -10,6 +10,7 @@ use alloy_rpc_types_engine::{ }; use alloy_rpc_types_eth::{Block, BlockNumberOrTag}; use clap::{Parser, arg}; +use ed25519_dalek::{SigningKey, VerifyingKey}; use http::{HeaderMap, Uri}; use jsonrpsee::core::async_trait; use jsonrpsee::core::middleware::layer::RpcLogger; @@ -22,6 +23,7 @@ use op_alloy_rpc_types_engine::{ }; use opentelemetry::trace::SpanKind; use paste::paste; +use reth_optimism_payload_builder::payload_id_optimism; use std::path::PathBuf; use std::time::Duration; use thiserror::Error; @@ -97,6 +99,14 @@ impl From for ErrorObjectOwned { } } +#[derive(Clone)] +pub struct FlashblocksP2PKeys { + /// Flashblocks Authorization Secret + pub authorization_sk: SigningKey, + /// Flashblocks builder vk + pub builder_pk: VerifyingKey, +} + /// Client interface for interacting with execution layer node's Engine API. /// /// - **Engine API** calls are faciliated via the `auth_client` (requires JWT authentication). @@ -109,6 +119,10 @@ pub struct RpcClient { auth_rpc: Uri, /// The source of the payload payload_source: PayloadSource, + /// Flashblocks keys + /// + /// `None` if p2p flashblocks are disabled + flashblocks_p2p_keys: Option, } impl RpcClient { @@ -118,6 +132,7 @@ impl RpcClient { auth_rpc_jwt_secret: JwtSecret, timeout: u64, payload_source: PayloadSource, + flashblocks_p2p_keys: Option, ) -> Result { let version = format!("{CARGO_PKG_VERSION}-{VERGEN_GIT_SHA}"); let mut headers = HeaderMap::new(); @@ -134,6 +149,7 @@ impl RpcClient { auth_client, auth_rpc, payload_source, + flashblocks_p2p_keys, }) } @@ -155,11 +171,30 @@ impl RpcClient { payload_attributes: Option, ) -> ClientResult { info!("Sending fork_choice_updated_v3 to {}", self.payload_source); - let res = self - .auth_client - .fork_choice_updated_v3(fork_choice_state, payload_attributes.clone()) - .await - .set_code()?; + let res = match (&payload_attributes, &self.flashblocks_p2p_keys) { + (Some(attrs), Some(flashblocks)) => { + let payload_id = payload_id_optimism(&fork_choice_state.head_block_hash, attrs, 3); + let authorization = Authorization::new( + payload_id, + attrs.payload_attributes.timestamp, + &flashblocks.authorization_sk, + flashblocks.builder_pk.clone(), + ); + self.auth_client + .flashblocks_fork_choice_updated_v3( + fork_choice_state, + payload_attributes.clone(), + Some(authorization), + ) + .await + .set_code()? + } + _ => self + .auth_client + .fork_choice_updated_v3(fork_choice_state, payload_attributes.clone()) + .await + .set_code()?, + }; if let Some(payload_id) = res.payload_id { tracing::Span::current().record("payload_id", payload_id.to_string()); @@ -457,7 +492,7 @@ pub mod tests { let port = get_available_port(); let secret = JwtSecret::from_hex(SECRET).unwrap(); let auth_rpc = Uri::from_str(&format!("http://{}:{}", AUTH_ADDR, port)).unwrap(); - let client = RpcClient::new(auth_rpc, secret, 1000, PayloadSource::L2).unwrap(); + let client = RpcClient::new(auth_rpc, secret, 1000, PayloadSource::L2, None).unwrap(); let response = send_request(client.auth_client, port).await; assert!(response.is_ok()); assert_eq!(response.unwrap(), "You are the dark lord"); diff --git a/crates/rollup-boost/src/flashblocks/args.rs b/crates/rollup-boost/src/flashblocks/args.rs index 1b5a7780..088f1b82 100644 --- a/crates/rollup-boost/src/flashblocks/args.rs +++ b/crates/rollup-boost/src/flashblocks/args.rs @@ -1,11 +1,21 @@ -use clap::Parser; +use clap::Args; +use ed25519_dalek::{SigningKey, VerifyingKey}; use url::Url; -#[derive(Parser, Clone, Debug)] -pub struct FlashblocksArgs { +use hex::FromHex; + +#[derive(Args, Clone, Debug)] +#[group(requires = "flashblocks_ws")] +pub struct FlashblocksWsArgs { /// Enable Flashblocks client - #[arg(long, env, default_value = "false")] - pub flashblocks: bool, + #[arg( + long, + id = "flashblocks_ws", + conflicts_with = "flashblocks_p2p", + env, + default_value = "false" + )] + pub flashblocks_ws: bool, /// Flashblocks Builder WebSocket URL #[arg(long, env, default_value = "ws://127.0.0.1:1111")] @@ -23,3 +33,43 @@ pub struct FlashblocksArgs { #[arg(long, env, default_value = "5000")] pub flashblock_builder_ws_reconnect_ms: u64, } + +#[derive(Args, Clone, Debug)] +#[group(requires = "flashblocks_p2p")] +pub struct FlashblocksP2PArgs { + /// Enable Flashblocks client + #[arg( + long, + id = "flashblocks_p2p", + conflicts_with = "flashblocks_ws", + env, + required = false + )] + pub flashblocks_p2p: bool, + + #[arg( + long, + env = "FLASHBLOCKS_AUTHORIZER_SK", + value_parser = parse_sk, + required = false, + )] + pub flashblocks_authorizer_sk: SigningKey, + + #[arg( + long, + env = "FLASHBLOCKS_BUILDER_VK", + value_parser = parse_vk, + required = false, + )] + pub flashblocks_builder_vk: VerifyingKey, +} + +pub fn parse_sk(s: &str) -> eyre::Result { + let bytes = <[u8; 32]>::from_hex(s.trim())?; + Ok(SigningKey::from_bytes(&bytes)) +} + +pub fn parse_vk(s: &str) -> eyre::Result { + let bytes = <[u8; 32]>::from_hex(s.trim())?; + Ok(VerifyingKey::from_bytes(&bytes)?) +} diff --git a/crates/rollup-boost/src/flashblocks/error.rs b/crates/rollup-boost/src/flashblocks/error.rs new file mode 100644 index 00000000..079394fa --- /dev/null +++ b/crates/rollup-boost/src/flashblocks/error.rs @@ -0,0 +1,25 @@ +use thiserror::Error; + +#[derive(Debug, Error, PartialEq)] +pub enum FlashblocksError { + #[error("invalid authorizer signature")] + InvalidAuthorizerSig, + #[error("invalid builder signature")] + InvalidBuilderSig, + #[error("input too short")] + InputTooShort, + #[error("unknown message type")] + UnknownMessageType, + #[error("invalid builder signature")] + Rlp(#[from] alloy_rlp::Error), + #[error("Missing base payload for initial flashblock")] + MissingBasePayload, + #[error("Unexpected base payload for non-initial flashblock")] + UnexpectedBasePayload, + #[error("Missing delta for flashblock")] + MissingDelta, + #[error("Invalid index for flashblock")] + InvalidIndex, + #[error("Missing payload")] + MissingPayload, +} diff --git a/crates/rollup-boost/src/flashblocks/mod.rs b/crates/rollup-boost/src/flashblocks/mod.rs index 3cdd3e7e..7a459662 100644 --- a/crates/rollup-boost/src/flashblocks/mod.rs +++ b/crates/rollup-boost/src/flashblocks/mod.rs @@ -15,3 +15,8 @@ mod args; pub use args::*; mod metrics; + +mod error; + +mod p2p; +pub use p2p::*; diff --git a/crates/rollup-boost/src/flashblocks/p2p.rs b/crates/rollup-boost/src/flashblocks/p2p.rs new file mode 100644 index 00000000..02f77ba2 --- /dev/null +++ b/crates/rollup-boost/src/flashblocks/p2p.rs @@ -0,0 +1,787 @@ +use std::marker::PhantomData; + +use alloy_primitives::{B64, Bytes}; +use alloy_rlp::{Decodable, Encodable, Header}; +use alloy_rpc_types_engine::PayloadId; +use bytes::{Buf as _, BufMut as _, BytesMut}; +use ed25519_dalek::{Signature, Signer, SigningKey, Verifier, VerifyingKey}; +use serde::{Deserialize, Serialize}; + +use crate::{FlashblocksPayloadV1, flashblocks::error::FlashblocksError}; + +/// An authorization token that grants a builder permission to publish flashblocks for a specific payload. +/// +/// The `authorizer_sig` is made over the `payload_id`, `timestamp`, and `builder_vk`. This is +/// useful because it allows the authorizer to control which builders can publish flashblocks in +/// real time, without relying on consumers to verify the builder's public key against a +/// pre-defined list. +#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +pub struct Authorization { + /// The unique identifier of the payload this authorization applies to + pub payload_id: PayloadId, + /// Unix timestamp when this authorization was created + pub timestamp: u64, + /// The public key of the builder who is authorized to sign messages + pub builder_vk: VerifyingKey, + /// The authorizer's signature over the payload_id, timestamp, and builder_vk + pub authorizer_sig: Signature, +} + +/// A message requesting to start publishing flashblock payloads +#[derive(Copy, Clone, Debug, PartialEq, Deserialize, Serialize, Eq)] +pub struct StartPublish; +/// A message requesting to stop publishing flashblock payloads. +/// +/// This is a simple marker message with no fields that indicates the sender +/// wants to stop publishing flashblock payloads. +#[derive(Copy, Clone, Debug, PartialEq, Deserialize, Serialize, Eq)] +pub struct StopPublish; + +/// A message that can be sent over the Flashblocks P2P network. +/// +/// This enum represents the top-level message types that can be transmitted +/// over the P2P network. Currently all messages are wrapped in authorization to ensure +/// only authorized builders can create new messages. +#[repr(u8)] +#[derive(Clone, Debug, PartialEq, Deserialize, Serialize, Eq)] +pub enum FlashblocksP2PMsg { + /// An authorized message containing a signed and authorized payload + Authorized(Authorized) = 0x00, +} + +/// The different types of authorized messages that can be sent over the Flashblocks P2P network. +/// +/// This enum represents the actual payload types that can be wrapped in authorization. +/// Each variant corresponds to a specific type of operation or data transmission. +#[allow(clippy::large_enum_variant)] +#[repr(u8)] +#[derive(Clone, Debug, PartialEq, Deserialize, Serialize, Eq)] +pub enum AuthorizedMsg { + /// A flashblock payload containing a list of transactions and associated metadata + FlashblocksPayloadV1(FlashblocksPayloadV1) = 0x00, + /// A declaration to start publishing flashblock payloads from a specific block number + StartPublish(StartPublish) = 0x01, + /// A declaration to stop publishing flashblock payloads + StopPublish(StopPublish) = 0x02, +} + +impl From for AuthorizedMsg { + fn from(payload: FlashblocksPayloadV1) -> Self { + Self::FlashblocksPayloadV1(payload) + } +} + +impl From for AuthorizedMsg { + fn from(req: StartPublish) -> Self { + Self::StartPublish(req) + } +} + +impl From for AuthorizedMsg { + fn from(res: StopPublish) -> Self { + Self::StopPublish(res) + } +} + +impl Authorization { + /// Creates a new authorization token for a builder to publish messages for a specific payload. + /// + /// This function creates a cryptographic authorization by signing a message containing the + /// payload ID, timestamp, and builder's public key using the authorizer's signing key. + /// + /// # Arguments + /// + /// * `payload_id` - The unique identifier of the payload this authorization applies to + /// * `timestamp` - Unix timestamp associated with this `payload_id` + /// * `authorizer_sk` - The authorizer's signing key used to create the signature + /// * `actor_vk` - The verifying key of the actor being authorized + /// + /// # Returns + /// + /// A new `Authorization` instance with the generated signature + pub fn new( + payload_id: PayloadId, + timestamp: u64, + authorizer_sk: &SigningKey, + actor_vk: VerifyingKey, + ) -> Self { + let mut msg = payload_id.0.to_vec(); + msg.extend_from_slice(×tamp.to_le_bytes()); + msg.extend_from_slice(actor_vk.as_bytes()); + let hash = blake3::hash(&msg); + let sig = authorizer_sk.sign(hash.as_bytes()); + + Self { + payload_id, + timestamp, + builder_vk: actor_vk, + authorizer_sig: sig, + } + } + + /// Verifies the authorization signature against the provided authorizer's verifying key. + /// + /// This function reconstructs the signed message from the authorization data and verifies + /// that the signature was created by the holder of the authorizer's private key. + /// + /// # Arguments + /// + /// * `authorizer_sk` - The verifying key of the authorizer to verify against + /// + /// # Returns + /// + /// * `Ok(())` if the signature is valid + /// * `Err(FlashblocksP2PError::InvalidAuthorizerSig)` if the signature is invalid + pub fn verify(&self, authorizer_sk: VerifyingKey) -> Result<(), FlashblocksError> { + let mut msg = self.payload_id.0.to_vec(); + msg.extend_from_slice(&self.timestamp.to_le_bytes()); + msg.extend_from_slice(self.builder_vk.as_bytes()); + let hash = blake3::hash(&msg); + authorizer_sk + .verify(hash.as_bytes(), &self.authorizer_sig) + .map_err(|_| FlashblocksError::InvalidAuthorizerSig) + } +} + +impl Encodable for Authorization { + fn encode(&self, out: &mut dyn alloy_rlp::BufMut) { + // pre-serialize the key & sig once so we can reuse the bytes & lengths + let pub_bytes = Bytes::copy_from_slice(self.builder_vk.as_bytes()); // 33 bytes + let sig_bytes = Bytes::copy_from_slice(&self.authorizer_sig.to_bytes()); // 64 bytes + + let payload_len = self.payload_id.0.length() + + self.timestamp.length() + + pub_bytes.length() + + sig_bytes.length(); + + Header { + list: true, + payload_length: payload_len, + } + .encode(out); + + // 1. payload_id (inner B64 already Encodable) + self.payload_id.0.encode(out); + // 2. timestamp + self.timestamp.encode(out); + // 3. builder_pub + pub_bytes.encode(out); + // 4. authorizer_sig + sig_bytes.encode(out); + } + + fn length(&self) -> usize { + let pub_bytes = Bytes::copy_from_slice(self.builder_vk.as_bytes()); + let sig_bytes = Bytes::copy_from_slice(&self.authorizer_sig.to_bytes()); + + let payload_len = self.payload_id.0.length() + + self.timestamp.length() + + pub_bytes.length() + + sig_bytes.length(); + + Header { + list: true, + payload_length: payload_len, + } + .length() + + payload_len + } +} + +impl Decodable for Authorization { + fn decode(buf: &mut &[u8]) -> Result { + let header = Header::decode(buf)?; + if !header.list { + return Err(alloy_rlp::Error::UnexpectedString); + } + let mut body = &buf[..header.payload_length as usize]; + + // 1. payload_id + let payload_id = alloy_rpc_types_engine::PayloadId(B64::decode(&mut body)?.into()); + + // 2. timestamp + let timestamp = u64::decode(&mut body)?; + + // 3. builder_pub + let pub_bytes = Bytes::decode(&mut body)?; + let builder_pub = VerifyingKey::try_from(pub_bytes.as_ref()) + .map_err(|_| alloy_rlp::Error::Custom("bad builder_pub"))?; + + // 4. authorizer_sig + let sig_bytes = Bytes::decode(&mut body)?; + let authorizer_sig = Signature::try_from(sig_bytes.as_ref()) + .map_err(|_| alloy_rlp::Error::Custom("bad signature"))?; + + // advance caller’s slice cursor + *buf = &buf[header.payload_length as usize..]; + + Ok(Self { + payload_id, + timestamp, + builder_vk: builder_pub, + authorizer_sig, + }) + } +} + +/// A type-safe wrapper around an authorized message for the Flashblocks P2P network. +/// +/// This struct provides type safety by encoding the specific message type `T` +/// at the type level while wrapping the underlying `Authorized` message. It uses a +/// phantom type marker to maintain type information without runtime overhead. +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +pub struct AuthorizedPayload { + /// The underlying authorized message containing the actual payload and signatures + pub authorized: Authorized, + /// Phantom type marker to maintain type safety for the specific message type + pub _marker: PhantomData, +} + +impl AuthorizedPayload +where + T: Into, +{ + /// Creates a new type-safe authorized payload. + /// + /// This constructor creates an authorized message by wrapping the provided message + /// with authorization and signing it with the actor's signing key. + /// + /// # Arguments + /// + /// * `actor_sk` - The signing key of the actor (builder) creating the message + /// * `authorization` - The authorization token granting permission to send this message + /// * `msg` - The message payload to be authorized and signed + /// + /// # Returns + /// + /// A new `AuthorizedPayload` instance with type safety for the message type + pub fn new(actor_sk: &SigningKey, authorization: Authorization, msg: T) -> Self { + let msg = msg.into(); + let authorized = Authorized::new(actor_sk, authorization, msg); + + Self { + authorized, + _marker: PhantomData, + } + } +} + +/// A signed and authorized message that can be sent over the Flashblocks P2P network. +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +pub struct Authorized { + /// The msg that is being authorized and signed over. + pub msg: AuthorizedMsg, + /// The authorization that grants permission to send this message. + pub authorization: Authorization, + /// The signature of the actor, made over the hash of the message and authorization. + pub actor_sig: Signature, +} + +impl Authorized { + /// Creates a new authorized message by combining a message with authorization and signing it. + /// + /// This function takes a message and authorization token, encodes them together, creates + /// a hash of the combined data, and signs it with the actor's signing key. + /// + /// # Arguments + /// + /// * `actor_sk` - The signing key of the actor (builder) creating the message + /// * `authorization` - The authorization token granting permission to send this message + /// * `msg` - The message to be authorized and signed + /// + /// # Returns + /// + /// A new `Authorized` instance containing the message, authorization, and signature + pub fn new(actor_sk: &SigningKey, authorization: Authorization, msg: AuthorizedMsg) -> Self { + let mut encoded = Vec::new(); + msg.encode(&mut encoded); + authorization.encode(&mut encoded); + + let hash = blake3::hash(&encoded); + let actor_sig = actor_sk.sign(hash.as_bytes()); + + Self { + msg, + authorization, + actor_sig, + } + } + + /// Verifies both the authorization and actor signatures. + /// + /// This function performs a two-step verification process: + /// 1. Verifies that the authorization signature is valid for the given authorizer + /// 2. Verifies that the actor signature is valid for the message and authorization + /// + /// # Arguments + /// + /// * `authorizer_sk` - The public key of the authorizer to verify against + /// + /// # Returns + /// + /// * `Ok(())` if both signatures are valid + /// * `Err(FlashblocksP2PError::InvalidAuthorizerSig)` if the authorization signature is invalid + /// * `Err(FlashblocksP2PError::InvalidBuilderSig)` if the actor signature is invalid + pub fn verify(&self, authorizer_sk: VerifyingKey) -> Result<(), FlashblocksError> { + self.authorization.verify(authorizer_sk)?; + + let mut encoded = Vec::new(); + self.msg.encode(&mut encoded); + self.authorization.encode(&mut encoded); + + let hash = blake3::hash(&encoded); + self.authorization + .builder_vk + .verify(hash.as_bytes(), &self.actor_sig) + .map_err(|_| FlashblocksError::InvalidBuilderSig) + } + + /// Converts this `Authorized` message into a type-safe `AuthorizedPayload` without verification. + /// + /// This is an unchecked conversion that bypasses type checking. The caller must ensure + /// that the contained message is actually of type `T`. + /// + /// # Type Parameters + /// + /// * `T` - The expected type of the contained message + /// + /// # Returns + /// + /// An `AuthorizedPayload` wrapper around this authorized message + pub fn into_unchecked(self) -> AuthorizedPayload { + AuthorizedPayload:: { + authorized: self, + _marker: PhantomData, + } + } +} + +impl AuthorizedPayload +where + AuthorizedMsg: AsRef, +{ + /// Returns a reference to the underlying message of type `T`. + /// + /// This method provides type-safe access to the contained message by leveraging + /// the `AsRef` trait implementation to extract the specific message type. + /// + /// # Returns + /// + /// A reference to the message of type `T` + pub fn msg(&self) -> &T { + self.authorized.msg.as_ref() + } +} + +impl Encodable for Authorized { + fn encode(&self, out: &mut dyn alloy_rlp::BufMut) { + // encode once so we know the length beforehand + let sig_bytes = Bytes::copy_from_slice(&self.actor_sig.to_bytes()); + let payload_len = self.msg.length() + self.authorization.length() + sig_bytes.length(); + + Header { + list: true, + payload_length: payload_len, + } + .encode(out); + + // 1. payload + self.msg.encode(out); + // 2. authorization + self.authorization.encode(out); + // 3. builder signature + sig_bytes.encode(out); + } + + fn length(&self) -> usize { + let sig_bytes = Bytes::copy_from_slice(&self.actor_sig.to_bytes()); + let payload_len = self.msg.length() + self.authorization.length() + sig_bytes.length(); + + Header { + list: true, + payload_length: payload_len, + } + .length() + + payload_len + } +} + +impl Decodable for Authorized { + fn decode(buf: &mut &[u8]) -> Result { + let header = Header::decode(buf)?; + if !header.list { + return Err(alloy_rlp::Error::UnexpectedString); + } + + let mut body = &buf[..header.payload_length as usize]; + + // 1. payload + let payload = AuthorizedMsg::decode(&mut body)?; + // 2. authorization + let authorization = Authorization::decode(&mut body)?; + // 3. builder signature + let sig_bytes = Bytes::decode(&mut body)?; + let builder_sig = Signature::try_from(sig_bytes.as_ref()) + .map_err(|_| alloy_rlp::Error::Custom("bad signature"))?; + + // advance caller’s cursor + *buf = &buf[header.payload_length as usize..]; + + Ok(Self { + msg: payload, + authorization, + actor_sig: builder_sig, + }) + } +} + +impl FlashblocksP2PMsg { + pub fn encode(&self) -> BytesMut { + let mut buf = BytesMut::new(); + match self { + FlashblocksP2PMsg::Authorized(payload) => { + buf.put_u8(0x00); + payload.encode(&mut buf); + } + } + buf + } + + pub fn decode(buf: &mut &[u8]) -> Result { + if buf.is_empty() { + return Err(FlashblocksError::InputTooShort); + } + let id = buf[0]; + buf.advance(1); + match id { + 0x00 => { + let payload = Authorized::decode(buf)?; + Ok(FlashblocksP2PMsg::Authorized(payload)) + } + _ => Err(FlashblocksError::UnknownMessageType), + } + } +} + +impl AsRef for AuthorizedMsg { + fn as_ref(&self) -> &FlashblocksPayloadV1 { + match self { + Self::FlashblocksPayloadV1(p) => p, + _ => panic!("not a FlashblocksPayloadV1 message"), + } + } +} + +impl AsRef for AuthorizedMsg { + fn as_ref(&self) -> &StartPublish { + match self { + Self::StartPublish(req) => req, + _ => panic!("not a StartPublish message"), + } + } +} + +impl AsRef for AuthorizedMsg { + fn as_ref(&self) -> &StopPublish { + match self { + Self::StopPublish(res) => res, + _ => panic!("not a StopPublish message"), + } + } +} + +impl Encodable for StartPublish { + fn encode(&self, _out: &mut dyn alloy_rlp::BufMut) {} + + fn length(&self) -> usize { + 0 + } +} + +impl Decodable for StartPublish { + fn decode(_buf: &mut &[u8]) -> Result { + Ok(StartPublish) + } +} + +impl Encodable for StopPublish { + fn encode(&self, _out: &mut dyn alloy_rlp::BufMut) {} + + fn length(&self) -> usize { + 0 + } +} + +impl Decodable for StopPublish { + fn decode(_buf: &mut &[u8]) -> Result { + Ok(StopPublish) + } +} + +impl Encodable for AuthorizedMsg { + fn encode(&self, out: &mut dyn alloy_rlp::BufMut) { + match self { + Self::FlashblocksPayloadV1(payload) => { + Header { + list: true, + payload_length: 1 + payload.length(), + } + .encode(out); + 0u32.encode(out); + payload.encode(out); + } + Self::StartPublish(start) => { + Header { + list: true, + payload_length: 1 + start.length(), + } + .encode(out); + 1u32.encode(out); + start.encode(out); + } + Self::StopPublish(stop) => { + Header { + list: true, + payload_length: 1 + stop.length(), + } + .encode(out); + 2u32.encode(out); + stop.encode(out); + } + }; + } + + fn length(&self) -> usize { + let body_len = match self { + Self::FlashblocksPayloadV1(payload) => 1 + payload.length(), + Self::StartPublish(start) => 1 + start.length(), + Self::StopPublish(stop) => 1 + stop.length(), + }; + + Header { + list: true, + payload_length: body_len, + } + .length() + + body_len + } +} + +impl Decodable for AuthorizedMsg { + fn decode(buf: &mut &[u8]) -> Result { + let hdr = Header::decode(buf)?; + if !hdr.list { + return Err(alloy_rlp::Error::Custom( + "AuthorizedMsg must be an RLP list", + )); + } + + let tag = u8::decode(buf)?; + let value = match tag { + 0 => Self::FlashblocksPayloadV1(FlashblocksPayloadV1::decode(buf)?), + 1 => Self::StartPublish(StartPublish::decode(buf)?), + 2 => Self::StopPublish(StopPublish::decode(buf)?), + _ => return Err(alloy_rlp::Error::Custom("unknown tag")), + }; + + Ok(value) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::{ExecutionPayloadBaseV1, ExecutionPayloadFlashblockDeltaV1}; + use alloy_primitives::{Address, B256, Bloom, U256}; + use alloy_rlp::{Decodable, Encodable, encode}; + use alloy_rpc_types_eth::Withdrawal; + use bytes::{BufMut, BytesMut}; + + fn key_pair(seed: u8) -> (SigningKey, VerifyingKey) { + let bytes = [seed; 32]; + let sk = SigningKey::from_bytes(&bytes); + let vk = sk.verifying_key(); + (sk, vk) + } + + fn sample_authorization() -> (Authorization, VerifyingKey) { + let (authorizer_sk, authorizer_vk) = key_pair(1); + let (_, builder_vk) = key_pair(2); + + ( + Authorization::new( + PayloadId::default(), + 1_700_000_001, + &authorizer_sk, + builder_vk, + ), + authorizer_vk, + ) + } + + fn sample_diff() -> ExecutionPayloadFlashblockDeltaV1 { + ExecutionPayloadFlashblockDeltaV1 { + state_root: B256::from([0x11; 32]), + receipts_root: B256::from([0x22; 32]), + logs_bloom: Bloom::default(), + gas_used: 21_000, + block_hash: B256::from([0x33; 32]), + transactions: vec![Bytes::from_static(b"\xDE\xAD\xBE\xEF")], + withdrawals: vec![Withdrawal::default()], + withdrawals_root: B256::from([0x44; 32]), + } + } + + fn sample_base() -> ExecutionPayloadBaseV1 { + ExecutionPayloadBaseV1 { + parent_beacon_block_root: B256::from([0x55; 32]), + parent_hash: B256::from([0x66; 32]), + fee_recipient: Address::default(), + prev_randao: B256::from([0x77; 32]), + block_number: 1_234, + gas_limit: 30_000_000, + timestamp: 1_700_000_999, + extra_data: Bytes::from_static(b"hi"), + base_fee_per_gas: U256::from(1_000_000_000u64), + } + } + + fn sample_flashblocks_payload() -> FlashblocksPayloadV1 { + FlashblocksPayloadV1 { + payload_id: PayloadId::default(), + index: 42, + diff: sample_diff(), + metadata: serde_json::json!({ "ok": true }), + base: Some(sample_base()), + } + } + + #[test] + fn authorization_rlp_roundtrip_and_verify() { + let (authorizer_sk, authorizer_vk) = key_pair(1); + let (_, builder_vk) = key_pair(2); + + let auth = Authorization::new( + PayloadId::default(), + 1_700_000_123, + &authorizer_sk, + builder_vk, + ); + + let encoded = encode(auth); + assert_eq!(encoded.len(), auth.length(), "length impl correct"); + + let mut slice = encoded.as_ref(); + let decoded = Authorization::decode(&mut slice).expect("decoding succeeds"); + assert!(slice.is_empty(), "decoder consumed all bytes"); + assert_eq!(decoded, auth, "round-trip preserves value"); + + // Signature is valid + decoded.verify(authorizer_vk).expect("signature verifies"); + } + + #[test] + fn authorization_signature_tamper_is_detected() { + let (authorizer_sk, authorizer_vk) = key_pair(1); + let (_, builder_vk) = key_pair(2); + + let mut auth = Authorization::new(PayloadId::default(), 42, &authorizer_sk, builder_vk); + + let mut sig_bytes = auth.authorizer_sig.to_bytes(); + sig_bytes[0] ^= 1; + auth.authorizer_sig = Signature::try_from(sig_bytes.as_ref()).unwrap(); + + assert!(auth.verify(authorizer_vk).is_err()); + } + + #[test] + fn authorized_rlp_roundtrip_and_verify() { + let (builder_sk, _builder_vk) = key_pair(2); + let (authorization, authorizer_vk) = sample_authorization(); + + let payload = sample_flashblocks_payload(); + let msg = AuthorizedMsg::FlashblocksPayloadV1(payload); + + let authorized = Authorized::new(&builder_sk, authorization.clone(), msg); + + // Encode → decode + let encoded = encode(&authorized); + assert_eq!(encoded.len(), authorized.length()); + + let mut slice = encoded.as_ref(); + let decoded = Authorized::decode(&mut slice).expect("decoding succeeds"); + assert!(slice.is_empty()); + assert_eq!(decoded, authorized); + + decoded + .verify(authorizer_vk) + .expect("composite verification succeeds"); + } + + #[test] + fn authorized_builder_signature_tamper_is_detected() { + let (builder_sk, _) = key_pair(2); + let (authorization, authorizer_vk) = sample_authorization(); + let payload = sample_flashblocks_payload(); + let msg = AuthorizedMsg::FlashblocksPayloadV1(payload); + + let mut authorized = Authorized::new(&builder_sk, authorization, msg); + + let mut sig_bytes = authorized.actor_sig.to_bytes(); + sig_bytes[0] ^= 1; + authorized.actor_sig = Signature::try_from(sig_bytes.as_ref()).unwrap(); + + assert!(authorized.verify(authorizer_vk).is_err()); + } + + #[test] + fn authorized_msg_variants_rlp_roundtrip() { + let variants = [ + AuthorizedMsg::FlashblocksPayloadV1(sample_flashblocks_payload()), + AuthorizedMsg::StartPublish(StartPublish), + AuthorizedMsg::StopPublish(StopPublish), + ]; + + for msg in variants { + let encoded = encode(&msg); + assert_eq!(encoded.len(), msg.length()); + + let mut slice = encoded.as_ref(); + let decoded = AuthorizedMsg::decode(&mut slice).expect("decodes"); + assert!(slice.is_empty()); + assert_eq!(decoded, msg); + } + } + + #[test] + fn p2p_msg_roundtrip() { + let (builder_sk, _) = key_pair(2); + let (authorization, _authorizer_vk) = sample_authorization(); + let payload = sample_flashblocks_payload(); + let msg = AuthorizedMsg::FlashblocksPayloadV1(payload); + + let authorized = Authorized::new(&builder_sk, authorization, msg); + let p2p = FlashblocksP2PMsg::Authorized(authorized.clone()); + + let encoded = p2p.encode(); + + let mut view: &[u8] = &encoded; + let decoded = FlashblocksP2PMsg::decode(&mut view).expect("decoding succeeds"); + assert!(view.is_empty(), "all bytes consumed"); + + match decoded { + FlashblocksP2PMsg::Authorized(inner) => assert_eq!(inner, authorized), + } + } + + #[test] + fn p2p_msg_unknown_type_errors() { + let mut buf = BytesMut::new(); + buf.put_u8(0xFF); // unknown discriminator + + let mut slice: &[u8] = &buf; + let err = + FlashblocksP2PMsg::decode(&mut slice).expect_err("should fail on unknown message type"); + assert_eq!(err, FlashblocksError::UnknownMessageType); + } +} diff --git a/crates/rollup-boost/src/flashblocks/primitives.rs b/crates/rollup-boost/src/flashblocks/primitives.rs index f6089a3a..8ece9660 100644 --- a/crates/rollup-boost/src/flashblocks/primitives.rs +++ b/crates/rollup-boost/src/flashblocks/primitives.rs @@ -1,4 +1,5 @@ -use alloy_primitives::{Address, B256, Bloom, Bytes, U256}; +use alloy_primitives::{Address, B64, B256, Bloom, Bytes, U256}; +use alloy_rlp::{Decodable, Encodable, Header, RlpDecodable, RlpEncodable}; use alloy_rpc_types_engine::PayloadId; use alloy_rpc_types_eth::Withdrawal; use serde::{Deserialize, Serialize}; @@ -9,7 +10,9 @@ use serde_json::Value; /// such as state root, receipts, logs, and new transactions. Other immutable block fields /// like parent hash and block number are excluded since they remain constant throughout /// the block's construction. -#[derive(Clone, Debug, PartialEq, Default, Deserialize, Serialize)] +#[derive( + Clone, Debug, PartialEq, Default, Deserialize, Serialize, Eq, RlpEncodable, RlpDecodable, +)] pub struct ExecutionPayloadFlashblockDeltaV1 { /// The state root of the block. pub state_root: B256, @@ -34,7 +37,9 @@ pub struct ExecutionPayloadFlashblockDeltaV1 { /// throughout block construction. This includes fundamental block properties like /// parent hash, block number, and other header fields that are determined at /// block creation and cannot be modified. -#[derive(Clone, Debug, PartialEq, Default, Deserialize, Serialize)] +#[derive( + Clone, Debug, PartialEq, Default, Deserialize, Serialize, Eq, RlpEncodable, RlpDecodable, +)] pub struct ExecutionPayloadBaseV1 { /// Ecotone parent beacon block root pub parent_beacon_block_root: B256, @@ -59,17 +64,228 @@ pub struct ExecutionPayloadBaseV1 { pub base_fee_per_gas: U256, } -#[derive(Clone, Debug, PartialEq, Default, Deserialize, Serialize)] +#[derive(Clone, Debug, PartialEq, Default, Deserialize, Serialize, Eq)] pub struct FlashblocksPayloadV1 { /// The payload id of the flashblock pub payload_id: PayloadId, /// The index of the flashblock in the block pub index: u64, - /// The base execution payload configuration - #[serde(skip_serializing_if = "Option::is_none")] - pub base: Option, /// The delta/diff containing modified portions of the execution payload pub diff: ExecutionPayloadFlashblockDeltaV1, /// Additional metadata associated with the flashblock pub metadata: Value, + /// The base execution payload configuration + #[serde(skip_serializing_if = "Option::is_none")] + pub base: Option, +} + +/// Manual RLP implementation because `PayloadId` and `serde_json::Value` are +/// outside of alloy-rlp’s blanket impls. +impl Encodable for FlashblocksPayloadV1 { + fn encode(&self, out: &mut dyn alloy_rlp::BufMut) { + // ---- compute payload length ------------------------------------------------- + let json_bytes = Bytes::from( + serde_json::to_vec(&self.metadata).expect("serialising `metadata` to JSON never fails"), + ); + + // encoded-len helper — empty string is one byte (`0x80`) + let empty_len = 1usize; + + let base_len = self.base.as_ref().map(|b| b.length()).unwrap_or(empty_len); + + let payload_len = self.payload_id.0.length() + + self.index.length() + + self.diff.length() + + json_bytes.length() + + base_len; + + Header { + list: true, + payload_length: payload_len, + } + .encode(out); + + // 1. `payload_id` – the inner `B64` already impls `Encodable` + self.payload_id.0.encode(out); + + // 2. `index` + self.index.encode(out); + + // 3. `diff` + self.diff.encode(out); + + // 4. `metadata` (as raw JSON bytes) + json_bytes.encode(out); + + // 5. `base` (`Option` as “value | empty string”) + if let Some(base) = &self.base { + base.encode(out); + } else { + // RLP encoding for empty value + out.put_u8(0x80); + } + } + + fn length(&self) -> usize { + let json_bytes = Bytes::from( + serde_json::to_vec(&self.metadata).expect("serialising `metadata` to JSON never fails"), + ); + + let empty_len = 1usize; + + let base_len = self.base.as_ref().map(|b| b.length()).unwrap_or(empty_len); + + // list header length + payload length + let payload_length = self.payload_id.0.length() + + self.index.length() + + self.diff.length() + + json_bytes.length() + + base_len; + + Header { + list: true, + payload_length, + } + .length() + + payload_length + } +} + +impl Decodable for FlashblocksPayloadV1 { + fn decode(buf: &mut &[u8]) -> Result { + let header = Header::decode(buf)?; + if !header.list { + return Err(alloy_rlp::Error::UnexpectedString); + } + + // Limit the decoding window to the list payload only. + let mut body = &buf[..header.payload_length as usize]; + + let payload_id = B64::decode(&mut body)?.into(); + let index = u64::decode(&mut body)?; + let diff = ExecutionPayloadFlashblockDeltaV1::decode(&mut body)?; + + // metadata – stored as raw JSON bytes + let meta_bytes = Bytes::decode(&mut body)?; + let metadata: Value = serde_json::from_slice(&meta_bytes) + .map_err(|_| alloy_rlp::Error::Custom("bad JSON"))?; + + // base (`Option`) + let base = if body.first() == Some(&0x80) { + None + } else { + Some(ExecutionPayloadBaseV1::decode(&mut body)?) + }; + + // advance the original buffer cursor + *buf = &buf[header.payload_length as usize..]; + + Ok(Self { + payload_id, + index, + diff, + metadata, + base, + }) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use alloy_rlp::{Decodable, encode}; + + fn sample_diff() -> ExecutionPayloadFlashblockDeltaV1 { + ExecutionPayloadFlashblockDeltaV1 { + state_root: B256::from([1u8; 32]), + receipts_root: B256::from([2u8; 32]), + logs_bloom: Bloom::default(), + gas_used: 21_000, + block_hash: B256::from([3u8; 32]), + transactions: vec![Bytes::from(vec![0xde, 0xad, 0xbe, 0xef])], + withdrawals: vec![Withdrawal::default()], + withdrawals_root: B256::from([4u8; 32]), + } + } + + fn sample_base() -> ExecutionPayloadBaseV1 { + ExecutionPayloadBaseV1 { + parent_beacon_block_root: B256::from([5u8; 32]), + parent_hash: B256::from([6u8; 32]), + fee_recipient: Address::from([0u8; 20]), + prev_randao: B256::from([7u8; 32]), + block_number: 123, + gas_limit: 30_000_000, + timestamp: 1_700_000_000, + extra_data: Bytes::from(b"hello".to_vec()), + base_fee_per_gas: U256::from(1_000_000_000u64), + } + } + + #[test] + fn roundtrip_without_base() { + let original = FlashblocksPayloadV1 { + payload_id: PayloadId::default(), + index: 0, + diff: sample_diff(), + metadata: serde_json::json!({ "key": "value" }), + base: None, + }; + + let encoded = encode(&original); + assert_eq!( + encoded.len(), + original.length(), + "length() must match actually-encoded size" + ); + + let mut slice = encoded.as_ref(); + let decoded = FlashblocksPayloadV1::decode(&mut slice).expect("decode succeeds"); + assert_eq!(original, decoded, "round-trip must be loss-less"); + assert!( + slice.is_empty(), + "decoder should consume the entire input buffer" + ); + } + + #[test] + fn roundtrip_with_base() { + let original = FlashblocksPayloadV1 { + payload_id: PayloadId::default(), + index: 42, + diff: sample_diff(), + metadata: serde_json::json!({ "foo": 1, "bar": [1, 2, 3] }), + base: Some(sample_base()), + }; + + let encoded = encode(&original); + assert_eq!(encoded.len(), original.length()); + + let mut slice = encoded.as_ref(); + let decoded = FlashblocksPayloadV1::decode(&mut slice).expect("decode succeeds"); + assert_eq!(original, decoded); + assert!(slice.is_empty()); + } + + #[test] + fn invalid_rlp_is_rejected() { + let valid = FlashblocksPayloadV1 { + payload_id: PayloadId::default(), + index: 1, + diff: sample_diff(), + metadata: serde_json::json!({}), + base: None, + }; + + // Encode, then truncate the last byte to corrupt the payload. + let mut corrupted = encode(&valid); + corrupted.pop(); + + let mut slice = corrupted.as_ref(); + let result = FlashblocksPayloadV1::decode(&mut slice); + assert!( + result.is_err(), + "decoder must flag malformed / truncated input" + ); + } } diff --git a/crates/rollup-boost/src/flashblocks/service.rs b/crates/rollup-boost/src/flashblocks/service.rs index 4d693c95..b44bc724 100644 --- a/crates/rollup-boost/src/flashblocks/service.rs +++ b/crates/rollup-boost/src/flashblocks/service.rs @@ -2,6 +2,7 @@ use super::outbound::WebSocketPublisher; use super::primitives::{ ExecutionPayloadBaseV1, ExecutionPayloadFlashblockDeltaV1, FlashblocksPayloadV1, }; +use crate::flashblocks::error::FlashblocksError; use crate::flashblocks::metrics::FlashblocksServiceMetrics; use crate::{ ClientResult, EngineApiExt, NewPayload, OpExecutionPayloadEnvelope, PayloadVersion, RpcClient, @@ -23,25 +24,10 @@ use serde::{Deserialize, Serialize}; use std::io; use std::sync::Arc; use std::sync::atomic::{AtomicU64, Ordering}; -use thiserror::Error; use tokio::sync::RwLock; use tokio::sync::mpsc; use tracing::{debug, error, info}; -#[derive(Debug, Error, PartialEq)] -pub enum FlashblocksError { - #[error("Missing base payload for initial flashblock")] - MissingBasePayload, - #[error("Unexpected base payload for non-initial flashblock")] - UnexpectedBasePayload, - #[error("Missing delta for flashblock")] - MissingDelta, - #[error("Invalid index for flashblock")] - InvalidIndex, - #[error("Missing payload")] - MissingPayload, -} - #[derive(Debug, Deserialize, Serialize)] struct FlashbotsMessage { method: String, @@ -420,6 +406,7 @@ mod tests { jwt_secret, 2000, PayloadSource::Builder, + None, )?; let service = @@ -449,6 +436,7 @@ mod tests { jwt_secret, 2000, PayloadSource::Builder, + None, )?; let service = diff --git a/crates/rollup-boost/src/health.rs b/crates/rollup-boost/src/health.rs index fed2e27c..0af8f450 100644 --- a/crates/rollup-boost/src/health.rs +++ b/crates/rollup-boost/src/health.rs @@ -273,6 +273,7 @@ mod tests { JwtSecret::random(), 100, PayloadSource::Builder, + None, )?); let health_handle = HealthHandle { @@ -304,6 +305,7 @@ mod tests { JwtSecret::random(), 100, PayloadSource::Builder, + None, )?); let health_handle = HealthHandle { @@ -336,6 +338,7 @@ mod tests { JwtSecret::random(), 100, PayloadSource::Builder, + None, )?); let health_handle = HealthHandle { @@ -368,6 +371,7 @@ mod tests { JwtSecret::random(), 100, PayloadSource::Builder, + None, )?); let health_handle = HealthHandle { @@ -393,6 +397,7 @@ mod tests { JwtSecret::random(), 100, PayloadSource::Builder, + None, )?); let health_handle = HealthHandle { diff --git a/crates/rollup-boost/src/lib.rs b/crates/rollup-boost/src/lib.rs index 5d79271e..99e231cb 100644 --- a/crates/rollup-boost/src/lib.rs +++ b/crates/rollup-boost/src/lib.rs @@ -44,3 +44,7 @@ pub use engine_api::*; mod version; pub use version::*; + +pub mod ed25519_dalek { + pub use ed25519_dalek::*; +} diff --git a/crates/rollup-boost/src/server.rs b/crates/rollup-boost/src/server.rs index f3cc328f..e05bcfb6 100644 --- a/crates/rollup-boost/src/server.rs +++ b/crates/rollup-boost/src/server.rs @@ -1,5 +1,5 @@ use crate::debug_api::ExecutionMode; -use crate::{BlockSelectionPolicy, EngineApiExt}; +use crate::{Authorization, BlockSelectionPolicy, EngineApiExt}; use crate::{ client::rpc::RpcClient, debug_api::DebugServer, @@ -364,6 +364,19 @@ where } } +#[rpc(client)] +pub trait FlashblocksEngineApi { + /// When flashblocks is enabled + /// we add an additional parameter `authorization` to the FCU + #[method(name = "flashblocks_forkchoiceUpdatedV3")] + async fn flashblocks_fork_choice_updated_v3( + &self, + fork_choice_state: ForkchoiceState, + payload_attributes: Option, + authorization: Option, + ) -> RpcResult; +} + #[rpc(server, client)] pub trait EngineApi { #[method(name = "engine_forkchoiceUpdatedV3")] @@ -752,8 +765,14 @@ pub mod tests { let (builder_server, builder_server_addr) = spawn_server(builder_mock.clone()).await; let l2_auth_rpc = Uri::from_str(&format!("http://{l2_server_addr}")).unwrap(); - let l2_client = - RpcClient::new(l2_auth_rpc.clone(), jwt_secret, 2000, PayloadSource::L2).unwrap(); + let l2_client = RpcClient::new( + l2_auth_rpc.clone(), + jwt_secret, + 2000, + PayloadSource::L2, + None, + ) + .unwrap(); let builder_auth_rpc = Uri::from_str(&format!("http://{builder_server_addr}")).unwrap(); let builder_client = Arc::new( @@ -762,6 +781,7 @@ pub mod tests { jwt_secret, 2000, PayloadSource::Builder, + None, ) .unwrap(), ); @@ -1113,7 +1133,7 @@ pub mod tests { .rpc_client .fork_choice_updated_v3(fcu, Some(payload_attributes.clone())) .await; - assert!(fcu_response.is_ok()); + fcu_response.unwrap(); // no tx pool is false so should return the builder payload let get_payload_response = test_harness.rpc_client.get_payload_v3(payload_id).await; diff --git a/specs/flashblocks_p2p.md b/specs/flashblocks_p2p.md new file mode 100644 index 00000000..83ea64fe --- /dev/null +++ b/specs/flashblocks_p2p.md @@ -0,0 +1,193 @@ +# Flashblocks P2P Extension + +*This document is an extension to the original Flashblocks specification, modifying the flashblock propagation mechanism to use a peer-to-peer (P2P) network instead of WebSockets. It highlights the new P2P protocol and the changes in Rollup-Boost and builder interactions, aimed at simplifying distribution and improving fault tolerance in High Availability (HA) sequencer setups.* + +**Table of Contents** + +* [Abstract](#abstract) +* [Motivation](#motivation) +* [Specification](#specification) + + * [Terminology](#terminology) + * [Data Structures](#data-structures) + + * [**`Authorization`**](#authorization) + * [**`Authorized Message`**](#authorized-message) + * [**`StartPublish`**](#startpublish) + * [**`StopPublish`**](#stoppublish) + * [Flashblocks P2P Protocol](#flashblocks-p2p-protocol) + + * [Protocol Overview](#protocol-overview) + * [Message Types](#message-types) + * [Authorization and Security](#authorization-and-security) + * [Multi-Builder Coordination](#multi-builder-coordination) + * [Rollup-Boost and Builder Communication](#rollup-boost-and-builder-communication) + +# Abstract + +This document introduces an enhancement to Flashblocks where the propagation of partial blocks (“flashblocks”) is done over an Ethereum P2P subprotocol instead of a WebSocket broadcast. By integrating flashblock distribution into the peer-to-peer network, we eliminate the need for a dedicated WebSocket proxy and enable more robust, decentralized propagation of flashblock data. Crucially, this P2P approach uses cryptographic authorization to ensure that only an **authorized** block builder (and its designated successors in an HA setup) can publish flashblocks, improving fault tolerance during sequencer failovers. The end result is a simpler and more resilient system for delivering rapid preconfirmation data to users, without altering the core OP Stack protocol. + +# Motivation + +The original Flashblocks design relied on a centralized broadcast (via Rollup-Boost and a WebSocket proxy) to propagate flashblocks to RPC providers. While effective, that design introduced operational complexity and potential single points of failure: + +* **Operational Complexity:** Sequencer operators had to manage a WebSocket broadcasting service (e.g. Rollup-Boost’s WebSocket proxy) to fan-out flashblocks to providers. In multi-sequencer (HA) configurations, handing off this connection or migrating subscribers was cumbersome. +* **Failover Challenges:** In a High Availability sequencer setup, if the active sequencer failed the act of switching to a new sequencer/rollup-boost/builder combo would mean that already published flashblocks would not make it in the new block produced by the new builder. This breaks the promise that flashblocks makes to its consumers. +* **Scalability and Decentralization:** Relying on a single hub (the sequencer’s Rollup-Boost) to redistribute flashblocks could become a bottleneck. A P2P approach can naturally scale out to many peers and align with Ethereum’s existing propagation model for blocks and transactions. + +**P2P Propagation** addresses these issues by leveraging a gossip network for flashblocks. In this model, any number of RPC provider nodes (or other interested parties) can connect to the flashblock P2P network to receive preconfirmation updates. Failover is handled gracefully through the RLPx protocol: if a new sequencer takes over, its builder is already aware of previously published flashblocks, and so it can build on top of what has already been promised to the network. + +# Specification + +## Terminology + +We inherit all terminology from the original Flashblocks spec (Sequencer, Block Builder, Rollup-Boost, etc.), with a few new terms introduced: + +* **Authorizer** – The entity that vouches for a block builder’s legitimacy to produce flashblocks. In practice, this is rollup-boost who signs an authorization for a given builder each block cycle. +* **Builder Public Key** – A cryptographic public key identifying a builder on the flashblocks P2P network. This is distinct from an Ethereum address; it’s used for signing/validating flashblock messages. +* **Flashblocks P2P Network** – The peer-to-peer overlay network (using Ethereum’s devp2p protocols) through which flashblock messages are gossiped. Participants include all builders and one or more subscribing nodes (e.g. RPC providers, possibly other sequencer nodes in standby). +* **Publisher** – The current active builder that is publishing flashblocks for the ongoing L2 block. In an HA setup, the role of publisher can transfer to a new builder if the sequencer fails over. + +## Data Structures + +The fundamental flashblock data structures (`FlashblocksPayloadV1`, `ExecutionPayloadFlashblockResultV1`, `ExecutionPayloadStaticV1`, and the various Metadata containers) remain unchanged. Flashblocks are still represented as a sequence of incremental payloads culminating in a full block. + +To support P2P propagation and authorization, we introduce several new structures: + +### **`Authorization`** + +Represents a sequencer’s cryptographic authorization for a specific builder to produce a block with a given payload context. This is essentially a signed token from the sequencer (authorizer) that the builder includes with its flashblocks. + +```rust +pub struct Authorization { + pub payload_id: PayloadId, + pub timestamp: u64, + pub builder_vk: VerifyingKey, + pub authorizer_sig: Signature, +} +``` + +* `payload_id`: The unique ID for this block’s payload (as provided by `engine_forkchoiceUpdated` in the OP Stack Engine API). All flashblocks for the block share this ID. +* `timestamp`: The timestamp associated with this payload +* `builder_vk`: The verifying key identifying the builder authorized to publish this block’s flashblocks. Peers will use this to verify the builder’s signatures on messages. +* `authorizer_sig`: A signature produced by the sequencer (authorizer) over the concatenation of `payload_id`, `timestamp`, and `builder_vk`. This proves that the sequencer has approved the given builder (and key) to act for this block. Only one authorizer key (controlled by the rollup-boost operator) is recognized by the network, and all peers are configured with its public key for verification. + +### **`Authorized Message`** + +Container for any flashblocks P2P message that requires authorization. It bundles a payload (one of the message types defined below) with the authorization and a builder’s signature. + +```rust +pub struct Authorized { + pub msg: AuthorizedMsg, + pub authorization: Authorization, + pub actor_sig: Signature, +} +``` + +```rust +pub enum AuthorizedMsg { + FlashblocksPayloadV1(FlashblocksPayloadV1) = 0x00, + StartPublish(StartPublish) = 0x01, + StopPublish(StopPublish) = 0x02, +} +``` + +* `authorization`: The Authorization object, as described above. +* `msg`: The message content. This is a tagged union that can be one of: + + * A **Flashblock Payload** – Contains a `FlashblocksPayloadV1` (partial block delta), see below. + * A **StartPublish** signal – Indicates the builder is starting to publish a new block (detailed in [StartPublish](#startpublish)). + * A **StopPublish** signal – Indicates the builder is stopping publication (detailed in [StopPublish](#stoppublish)). + +* `actor_sig`: The builder’s signature over the combination of the `msg` and the `authorization`. This attests that the message indeed comes from the holder of the `builder_sk` in the Authorization, and that it hasn’t been tampered with in transit. + +Every P2P message in the Flashblocks protocol is sent as an `AuthorizedMessage`. This double-signature scheme (authorizer + builder) provides two layers of security: + +1. Only a builder with a valid Authorization (signed by the sequencer) can get its messages accepted by peers. +2. Only the genuine builder (holding the private key corresponding to `builder_sk`) can produce a valid `builder_signature` on the message content. + +### **`StartPublish`** + +A small message indicating the intention to begin publishing flashblocks for a new L2 block. + +```rust +pub struct StartPublish; +``` + +The `StartPublish` message is always sent wrapped in an `AuthorizedMessage` (with the appropriate authorization and signatures). It serves as an announcement to the network that *“Builder X is about to start publishing”* + +### **`StopPublish`** + +An authorized message indicating that the builder will no longer publish any flashblocks + +```rust +pub struct StopPublish; +``` + +**Note:** A builder will typically send a `StopPublish` when it receives a `ForkChoiceUpdated` without an accompanying `Authorization` from rollup-boost or upon handing off flashblock production to a new builder. + +## Flashblocks P2P Protocol + +### Protocol Overview + +Flashblocks P2P communication is implemented as a custom Ethereum subprotocol. Specifically, it defines a new devp2p capability: + +* **Protocol Name:** `flblk` (flashblocks) +* **Version:** `1` + +Nodes that support flashblocks will advertise this capability when establishing devp2p connections. Once connected, they can exchange flashblock messages as defined in this spec. + +All flashblock messages are encoded in a compact binary format (analogous to Ethereum block gossip). Each message begins with a one-byte type discriminator, followed by the serialized content. The primary message type is an `AuthorizedMessage` (discriminator `0x00`), which, as described, contains a nested payload type. + +**Key design features of the P2P protocol:** + +* **Multipeer Gossip:** A builder’s flashblock is forwarded to all connected peers, who in turn may forward it to their peers, etc., ensuring the payload reaches all participants without needing a single central broadcaster. The protocol includes basic duplicate suppression so that flashblocks aren’t endlessly propagated in loops. +* **Real-time Coordination:** Using `StartPublish` and `StopPublish` signals, multiple potential publishers (builders) can coordinate access to the network. This prevents conflicts where two builders might try to publish simultaneously, and allows a smooth handoff in failover scenarios (detailed below). + +### Message Types + +Within the `AuthorizedMsg` union, we define the following variants and their semantics: + +* **Flashblock Payload Message:** Carries a `FlashblocksPayloadV1` (as defined in the original spec) for a specific partial block. This includes the incremental transactions, updated state root, receipts root, logs bloom, etc., up through that flashblock. Peers receiving this message will apply the included state updates to their preconfirmation cache. Each Flashblock message has an `index` (the flashblock sequence number) and may include the `base` section if it’s the first flashblock (index 0) for that block. +* **StartPublish Message:** Announces the start of a new publishers flashblock sequence. Peers use this to note which builder is now active for a given L2 block number, possibly resetting any previous state or halting their own publishing. +* **StopPublish Message:** Indicates the end of the flashblock sequence for the current publisher. After this message, no further flashblocks from that publisher should arrive. Inactive or waiting publishers use this as a cue that they may now take over for subsequent flashblocks. + +All these are encapsulated in `AuthorizedMsg` with the requisite signatures. + +### Authorization and Security + +The P2P protocol introduces a trust model wherein peers accept flashblocks only from an **authorized builder**. The security measures include: + +* **Authorizer Signature Verification:** Upon receiving any `AuthorizedMessage`, a peer will first verify the `authorizer_sig` in the `Authorization` against the known authorizer public key. This confirms that rollup-boost has indeed permitted the stated builder to produce the block with the given `payload_id` and timestamp. If this signature is missing or invalid, the message is discarded as untrusted. +* **Builder Signature Verification:** Next, the peer verifies the `builder_signature` on the message content using the `builder_vk` provided in the Authorization. This ensures the message was genuinely produced by the authorized builder and not altered. If this check fails, the message is rejected. +* **Payload Consistency Checks:** Peers also check that the fields in the message are self-consistent and match expectations: + + * The `payload_id` in the Authorization must match the `FlashblocksPayloadV1.payload_id` (for flashblock messages). Each builder’s flashblock messages carry the same payload\_id that was authorized, ensuring they all belong to the same block-building session. + * **Freshness:** The `timestamp` in Authorization helps guard against replay of old messages. If a flashblock or StartPublish arrives with a significantly older timestamp (or for an already completed block), peers will ignore it and decrement the sender's reputation. + +These measures ensure that **only** the rollup-boost sanctioned builder’s data is propagated and that it’s cryptographically sound. Unauthorized parties cannot inject false flashblocks or tamper with content without detection. This design also allows dynamic builder changes: as long as the sequencer signs a new Authorization, the peers will accept the new builder’s messages even if they have never seen that builder before, because trust is transitive from the authorizers’s key. + +### Multi-Builder Coordination + +A major benefit of the P2P approach is the ability to coordinate multiple builders in an HA (High Availability) setting. The `StartPublish` and `StopPublish` messages, in conjunction with a small amount of logic in Rollup-Boost and the network, handle the arbitration: + +* **Single Publisher Rule:** The network expects at most one builder to be actively publishing flashblocks for a given L2 block number at any time. If two different builders both attempt to publish for the same block, the conflict must be resolved to maintain a consistent preconfirmation state. +* **Announcing Intent – `StartPublish`:** When Rollup-Boost (sequencer) initiates a new block with an external builder, it immediately broadcasts a `StartPublish` message (as an AuthorizedMessage) from that builder. This tells all peers: “Builder X is about to start publishing” If any other builder was thinking of building block N (perhaps there was a recent failover), it will see this and **stand down**. +* **Graceful Yield – reacting to `StartPublish`:** If a builder is currently publishing and receives a `StartPublish` from a *different* builder for the same or next block, it means a failover or override is happening. The expected behavior is that the current publisher will cease publishing (and issue a `StopPublish`). The protocol is designed such that the honest builder who is not supposed to publish will yield to the authorized one. The reference implementation will automatically send a `StopPublish` if it is publishing and learns that another builder has taken over authority for the block. The new builder will wait until it receives the `StopPublish` before continuing. +* **Completion – `StopPublish`:** When a builder receives the next FCU _without_ an accompanying `Authorization`, it will send out a `StopPublish`. This removes the builder from the “active publisher” role in the eyes of the network. If there was another builder in waiting (perhaps one that had attempted to start earlier but was told to wait), that waiting builder will now see that the coast is clear. +* **Timeouts and Fallback:** There is an implicit timeout in the coordination. If a builder is in a waiting state after announcing `StartPublish` but for some reason the previous publisher fails to produce a `StopPublish` (for example, if it crashed mid-block), other participants will not wait indefinitely. In our design, if a new block number is reached and the previous publisher hasn’t stopped we assume the previous builder is incapacitated and proceed with the new publisher. + +This coordination ensures that in an HA setup with multiple sequencer instances and multiple builders, **preconfirmation data remains consistent**: only one set of flashblocks is ever in flight for a given block. If a sequencer failover occurs, the worst-case scenario (which occurs only during a very rare race condition) is a single block publication gap or discontinuity at a block boundary. In the far more likely case, there will be exactly no flashblock disruption. The next publisher will simply start where the last publisher left off, even if that is mid block. + +## Rollup-Boost and Builder Communication + +In the P2P-enhanced design, Rollup-Boost’s interaction with the external block builder is slightly adjusted: + +* **Authorization Delivery:** When the sequencer (op-node) triggers a new block proposal via `engine_forkchoiceUpdated` (with payload attributes), Rollup-Boost creates an `Authorization` for the chosen builder. This requires that Rollup-Boost knows the builder’s public key in advance. In practice, the builder can be configured or registered with Rollup-Boost, providing its long-term public key. Rollup-Boost uses its **authorizer private key** (associated with the L2 chain or sequencer) to sign the authorization (covering payload\_id, timestamp, builder’s key). +* **Forkchoice Updated Forwarding:** Rollup-Boost forwards the fork choice update to the builder as usual (so the builder can start building the block). In this modified protocol, the fork choice update (or a parallel communication) includes the newly created `Authorization`. For example, a custom field or side-channel could convey the authorizer’s signature to the builder. **(Implementation-wise, this might be an extension of the Engine API or an internal call – the key point is the builder receives the Authorization token before it begins sending flashblocks.)** +* **StartPublish Broadcast:** If the builder was not previously publishing, then immediately after receiving the authorization it will emit a `StartPublish` message over the P2P network. This tells all listening nodes that the authorized builder will begin flashblock publication. +* **Streaming Flashblocks:** The builder executes transactions and produces flashblocks incrementally just as described in the original spec’s Flashblock Construction Process. However, instead of returning these payloads to Rollup-Boost, the builder now signs each flashblock with its key and directly broadcasts an Authorized Flashblock message to the P2P network. +* **No Inline Validation by Sequencer:** In the original design, Rollup-Boost would validate each flashblock against the local execution engine before propagating it. In the P2P model, this is not done synchronously for each flashblock (it would negate some latency benefits). Instead, trust is managed via the Authorization. The sequencer trusts its chosen builder to only send valid blocks (and will ultimately verify the final block when `engine_getPayload` is called). Peers trust the flashblocks because they trust the Rollup-Boost’s signature. + +In summary, Rollup-Boost’s role shifts from being a **middleman for data** to being a **controller and coordinator**. It authorizes the builder and informs the network about which builder is active, but it doesn’t need to ferry every flashblock through itself. This streamlines the path from builder to RPC providers. +