diff --git a/Cargo.lock b/Cargo.lock index bdc82574b2..23e08cc530 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -65,7 +65,7 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" dependencies = [ - "cfg-if", + "cfg-if 1.0.1", "cipher", "cpufeatures", ] @@ -87,7 +87,7 @@ version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" dependencies = [ - "cfg-if", + "cfg-if 1.0.1", "once_cell", "version_check", "zerocopy 0.8.26", @@ -259,7 +259,7 @@ checksum = "ccb3ead547f4532bc8af961649942f0b9c16ee9226e26caa3f38420651cc0bf4" dependencies = [ "alloy-rlp", "bytes", - "cfg-if", + "cfg-if 1.0.1", "const-hex", "derive_more 0.99.20", "hex-literal", @@ -281,7 +281,7 @@ checksum = "8c77490fe91a0ce933a1f219029521f20fc28c2c0ca95d53fa4da9c00b8d9d4e" dependencies = [ "alloy-rlp", "bytes", - "cfg-if", + "cfg-if 1.0.1", "const-hex", "derive_more 2.0.1", "foldhash", @@ -307,7 +307,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6177ed26655d4e84e00b65cb494d4e0b8830e7cae7ef5d63087d445a2600fb55" dependencies = [ "bytes", - "cfg-if", + "cfg-if 1.0.1", "const-hex", "derive_more 2.0.1", "hashbrown 0.15.4", @@ -1271,7 +1271,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" dependencies = [ "addr2line 0.24.2", - "cfg-if", + "cfg-if 1.0.1", "libc", "miniz_oxide 0.8.9", "object 0.36.7", @@ -1511,7 +1511,7 @@ dependencies = [ "arrayref", "arrayvec", "cc", - "cfg-if", + "cfg-if 1.0.1", "constant_time_eq 0.3.1", ] @@ -1815,6 +1815,12 @@ dependencies = [ "nom", ] +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + [[package]] name = "cfg-if" version = "1.0.1" @@ -2135,7 +2141,7 @@ version = "1.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "83e22e0ed40b96a48d3db274f72fd365bd78f67af39b6bbd47e8a15e1c6207ff" dependencies = [ - "cfg-if", + "cfg-if 1.0.1", "cpufeatures", "hex", "proptest", @@ -2244,7 +2250,7 @@ version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96e58d342ad113c2b878f16d5d034c03be492ae460cdbc02b7f0f2284d310c7d" dependencies = [ - "cfg-if", + "cfg-if 1.0.1", ] [[package]] @@ -2277,7 +2283,7 @@ version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" dependencies = [ - "cfg-if", + "cfg-if 1.0.1", ] [[package]] @@ -2324,13 +2330,48 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" +[[package]] +name = "crossbeam" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69323bff1fb41c635347b8ead484a5ca6c3f11914d784170b158d8449ab07f8e" +dependencies = [ + "cfg-if 0.1.10", + "crossbeam-channel 0.4.4", + "crossbeam-deque 0.7.4", + "crossbeam-epoch 0.8.2", + "crossbeam-queue 0.2.3", + "crossbeam-utils 0.7.2", +] + +[[package]] +name = "crossbeam-channel" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b153fe7cbef478c567df0f972e02e6d736db11affe43dfc9c56a9374d1adfb87" +dependencies = [ + "crossbeam-utils 0.7.2", + "maybe-uninit", +] + [[package]] name = "crossbeam-channel" version = "0.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" dependencies = [ - "crossbeam-utils", + "crossbeam-utils 0.8.21", +] + +[[package]] +name = "crossbeam-deque" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20ff29ded3204c5106278a81a38f4b482636ed4fa1e6cfbeef193291beb29ed" +dependencies = [ + "crossbeam-epoch 0.8.2", + "crossbeam-utils 0.7.2", + "maybe-uninit", ] [[package]] @@ -2339,8 +2380,23 @@ version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" dependencies = [ - "crossbeam-epoch", - "crossbeam-utils", + "crossbeam-epoch 0.9.18", + "crossbeam-utils 0.8.21", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace" +dependencies = [ + "autocfg", + "cfg-if 0.1.10", + "crossbeam-utils 0.7.2", + "lazy_static", + "maybe-uninit", + "memoffset 0.5.6", + "scopeguard", ] [[package]] @@ -2349,7 +2405,18 @@ version = "0.9.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" dependencies = [ - "crossbeam-utils", + "crossbeam-utils 0.8.21", +] + +[[package]] +name = "crossbeam-queue" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "774ba60a54c213d409d5353bda12d49cd68d14e45036a285234c8d6f91f92570" +dependencies = [ + "cfg-if 0.1.10", + "crossbeam-utils 0.7.2", + "maybe-uninit", ] [[package]] @@ -2358,7 +2425,18 @@ version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115" dependencies = [ - "crossbeam-utils", + "crossbeam-utils 0.8.21", +] + +[[package]] +name = "crossbeam-utils" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" +dependencies = [ + "autocfg", + "cfg-if 0.1.10", + "lazy_static", ] [[package]] @@ -2522,7 +2600,7 @@ version = "4.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e77a43b28d0668df09411cb0bc9a8c2adc40f9a048afe863e05fd43251e8e39c" dependencies = [ - "cfg-if", + "cfg-if 1.0.1", "num_cpus", "serde", ] @@ -2533,7 +2611,7 @@ version = "5.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" dependencies = [ - "cfg-if", + "cfg-if 1.0.1", "hashbrown 0.14.5", "lock_api", "once_cell", @@ -2580,7 +2658,7 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee99d08031ca34a4d044efbbb21dff9b8c54bb9d8c82a189187c0651ffdb9fbf" dependencies = [ - "cfg-if", + "cfg-if 1.0.1", "dashu-base", "num-modular", "num-order", @@ -2669,7 +2747,7 @@ dependencies = [ "deno_unsync", "futures", "libc", - "memoffset", + "memoffset 0.9.1", "parking_lot 0.12.4", "percent-encoding", "pin-project", @@ -2919,7 +2997,7 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" dependencies = [ - "cfg-if", + "cfg-if 1.0.1", "dirs-sys-next", ] @@ -3169,7 +3247,7 @@ version = "0.8.35" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" dependencies = [ - "cfg-if", + "cfg-if 1.0.1", ] [[package]] @@ -3625,7 +3703,7 @@ version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "66244a771d9163282646dbeffe0e6eca4dda4146b6498644e678ac6089b11edd" dependencies = [ - "cfg-if", + "cfg-if 1.0.1", "const-hex", "dirs 5.0.1", "dunce", @@ -3657,7 +3735,7 @@ version = "0.1.0" dependencies = [ "anyhow", "bytes", - "cfg-if", + "cfg-if 1.0.1", "clap 4.5.40", "clap_complete", "criterion", @@ -3702,7 +3780,7 @@ name = "ethrex-blockchain" version = "0.1.0" dependencies = [ "bytes", - "cfg-if", + "cfg-if 1.0.1", "ethrex-common", "ethrex-metrics", "ethrex-rlp", @@ -3773,7 +3851,7 @@ dependencies = [ "aligned-sdk", "bincode", "bytes", - "cfg-if", + "cfg-if 1.0.1", "directories", "envy", "ethereum-types 0.15.1", @@ -3921,6 +3999,8 @@ dependencies = [ "serde_json", "sha3", "snap", + "spawned-concurrency", + "spawned-rt", "thiserror 2.0.12", "tokio", "tokio-stream", @@ -3935,7 +4015,7 @@ dependencies = [ "anyhow", "bincode", "bytes", - "cfg-if", + "cfg-if 1.0.1", "clap 4.5.40", "ethereum-types 0.15.1", "ethrex-blockchain", @@ -4020,7 +4100,7 @@ dependencies = [ "axum 0.8.4", "axum-extra", "bytes", - "cfg-if", + "cfg-if 1.0.1", "envy", "ethereum-types 0.15.1", "ethrex-blockchain", @@ -4155,7 +4235,7 @@ version = "0.1.0" dependencies = [ "bincode", "bytes", - "cfg-if", + "cfg-if 1.0.1", "derive_more 1.0.0", "dyn-clone", "ethereum-types 0.15.1", @@ -4668,7 +4748,7 @@ version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" dependencies = [ - "cfg-if", + "cfg-if 1.0.1", "libc", "wasi 0.9.0+wasi-snapshot-preview1", ] @@ -4679,7 +4759,7 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" dependencies = [ - "cfg-if", + "cfg-if 1.0.1", "js-sys", "libc", "wasi 0.11.1+wasi-snapshot-preview1", @@ -4692,7 +4772,7 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" dependencies = [ - "cfg-if", + "cfg-if 1.0.1", "js-sys", "libc", "r-efi", @@ -4900,7 +4980,7 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "459196ed295495a68f7d7fe1d84f6c4b7ff0e21fe3017b2f283c6fac3ad803c9" dependencies = [ - "cfg-if", + "cfg-if 1.0.1", "crunchy", ] @@ -5529,7 +5609,7 @@ version = "0.4.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d89fd380afde86567dfba715db065673989d6253f42b88179abd3eae47bda4b" dependencies = [ - "crossbeam-deque", + "crossbeam-deque 0.8.6", "globset", "log", "memchr", @@ -5697,7 +5777,7 @@ version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" dependencies = [ - "cfg-if", + "cfg-if 1.0.1", ] [[package]] @@ -5709,6 +5789,17 @@ dependencies = [ "rustversion", ] +[[package]] +name = "io-uring" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b86e202f00093dcba4275d4636b93ef9dd75d025ae560d2521b45ea28ab49013" +dependencies = [ + "bitflags 2.9.1", + "cfg-if 1.0.1", + "libc", +] + [[package]] name = "ipnet" version = "2.11.0" @@ -5871,7 +5962,7 @@ version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b" dependencies = [ - "cfg-if", + "cfg-if 1.0.1", "ecdsa 0.16.9 (registry+https://github.com/rust-lang/crates.io-index)", "elliptic-curve", "once_cell", @@ -5885,7 +5976,7 @@ name = "k256" version = "0.13.4" source = "git+https://github.com/sp1-patches/elliptic-curves?tag=patch-k256-13.4-sp1-5.0.0#f7d8998e05d8cbcbd8e543eba1030a7385011fa8" dependencies = [ - "cfg-if", + "cfg-if 1.0.1", "ecdsa 0.16.9 (git+https://github.com/sp1-patches/signatures.git?tag=patch-16.9-sp1-4.1.0)", "elliptic-curve", "hex", @@ -6092,7 +6183,7 @@ version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" dependencies = [ - "cfg-if", + "cfg-if 1.0.1", "windows-targets 0.53.2", ] @@ -6518,13 +6609,19 @@ dependencies = [ "syn 2.0.104", ] +[[package]] +name = "maybe-uninit" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" + [[package]] name = "md-5" version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" dependencies = [ - "cfg-if", + "cfg-if 1.0.1", "digest 0.10.7", ] @@ -6563,6 +6660,15 @@ dependencies = [ "libc", ] +[[package]] +name = "memoffset" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "043175f069eda7b85febe4a74abbaeff828d9f8b448515d3151a14a3542811aa" +dependencies = [ + "autocfg", +] + [[package]] name = "memoffset" version = "0.9.1" @@ -6724,7 +6830,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" dependencies = [ "bitflags 2.9.1", - "cfg-if", + "cfg-if 1.0.1", "cfg_aliases", "libc", ] @@ -7059,7 +7165,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8505734d46c8ab1e19a1dce3aef597ad87dcb4c37e7188231769bd6bd51cebf8" dependencies = [ "bitflags 2.9.1", - "cfg-if", + "cfg-if 1.0.1", "foreign-types 0.3.2", "libc", "once_cell", @@ -7447,7 +7553,7 @@ version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" dependencies = [ - "cfg-if", + "cfg-if 1.0.1", "instant", "libc", "redox_syscall 0.2.16", @@ -7461,7 +7567,7 @@ version = "0.9.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" dependencies = [ - "cfg-if", + "cfg-if 1.0.1", "libc", "redox_syscall 0.5.13", "smallvec", @@ -8031,7 +8137,7 @@ version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d33c28a30771f7f96db69893f78b857f7450d7e0237e9c8fc6427a81bae7ed1" dependencies = [ - "cfg-if", + "cfg-if 1.0.1", "fnv", "lazy_static", "memchr", @@ -8120,7 +8226,7 @@ checksum = "fa9dae7b05c02ec1a6bc9bcf20d8bc64a7dcbf57934107902a872014899b741f" dependencies = [ "anyhow", "byteorder", - "cfg-if", + "cfg-if 1.0.1", "itertools 0.10.5", "once_cell", "parking_lot 0.12.4", @@ -8391,8 +8497,8 @@ version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" dependencies = [ - "crossbeam-deque", - "crossbeam-utils", + "crossbeam-deque 0.8.6", + "crossbeam-utils 0.8.21", ] [[package]] @@ -8658,7 +8764,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a2c336f9921588e50871c00024feb51a521eca50ce6d01494bb9c50f837c8ed" dependencies = [ "auto_impl", - "cfg-if", + "cfg-if 1.0.1", "dyn-clone", "revm-interpreter 5.0.0", "revm-precompile 7.0.0", @@ -8673,7 +8779,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c175ecec83bba464aa8406502fe5bf670491c2ace81a153264891d43bc7fa332" dependencies = [ "auto_impl", - "cfg-if", + "cfg-if 1.0.1", "dyn-clone", "revm-interpreter 15.2.0", "revm-precompile 16.2.0", @@ -8746,7 +8852,7 @@ dependencies = [ "aurora-engine-modexp", "blst", "c-kzg", - "cfg-if", + "cfg-if 1.0.1", "k256 0.13.4 (registry+https://github.com/rust-lang/crates.io-index)", "once_cell", "revm-primitives 15.2.0", @@ -8767,7 +8873,7 @@ dependencies = [ "bitflags 2.9.1", "bitvec", "c-kzg", - "cfg-if", + "cfg-if 1.0.1", "derive_more 0.99.20", "dyn-clone", "enumn", @@ -8790,7 +8896,7 @@ dependencies = [ "bitflags 2.9.1", "bitvec", "c-kzg", - "cfg-if", + "cfg-if 1.0.1", "dyn-clone", "enumn", "hex", @@ -8862,7 +8968,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" dependencies = [ "cc", - "cfg-if", + "cfg-if 1.0.1", "getrandom 0.2.16", "libc", "untrusted 0.9.0", @@ -8950,7 +9056,7 @@ checksum = "8d339c65b0e011677404bd6bdfe1b0f29748187a568fb2f74df7fb650590181a" dependencies = [ "anyhow", "bytemuck", - "cfg-if", + "cfg-if 1.0.1", "keccak", "paste", "rayon", @@ -8988,7 +9094,7 @@ checksum = "8c6501fd3936aea2dd3e55915f34328fe96e6ca25ef00320242f837ae668785b" dependencies = [ "anyhow", "bytemuck", - "cfg-if", + "cfg-if 1.0.1", "cust", "downloader", "hex", @@ -9030,7 +9136,7 @@ dependencies = [ "bit-vec 0.8.0", "bytemuck", "byteorder", - "cfg-if", + "cfg-if 1.0.1", "derive_more 2.0.1", "enum-map", "malachite", @@ -9137,7 +9243,7 @@ dependencies = [ "blake2", "borsh", "bytemuck", - "cfg-if", + "cfg-if 1.0.1", "cust", "digest 0.10.7", "ff 0.13.1", @@ -9213,7 +9319,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2e4de2938eaf24892ef927d9cef6e4acb6a19ce01c017cd498533896f633f332" dependencies = [ "bytemuck", - "cfg-if", + "cfg-if 1.0.1", "getrandom 0.2.16", "getrandom 0.3.3", "libm", @@ -9614,7 +9720,7 @@ version = "2.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "346a3b32eba2640d17a9cb5927056b08f3de90f65b72fe09402c2ad07d684d0b" dependencies = [ - "cfg-if", + "cfg-if 1.0.1", "derive_more 1.0.0", "parity-scale-codec", "scale-info-derive", @@ -9739,7 +9845,7 @@ name = "secp256k1" version = "0.29.1" source = "git+https://github.com/sp1-patches/rust-secp256k1?tag=patch-0.29.1-sp1-5.0.0#14136bdd2fafe651e3d0ce680f930473e848cf56" dependencies = [ - "cfg-if", + "cfg-if 1.0.1", "k256 0.13.4 (git+https://github.com/sp1-patches/elliptic-curves?tag=patch-k256-13.4-sp1-5.0.0)", "rand 0.8.5", "secp256k1-sys", @@ -10013,7 +10119,7 @@ version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ - "cfg-if", + "cfg-if 1.0.1", "cpufeatures", "digest 0.10.7", ] @@ -10024,7 +10130,7 @@ version = "0.10.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ - "cfg-if", + "cfg-if 1.0.1", "cpufeatures", "digest 0.10.7", ] @@ -10046,7 +10152,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c28efc5e327c837aa837c59eae585fc250715ef939ac32881bcc11677cd02d46" dependencies = [ "cc", - "cfg-if", + "cfg-if 1.0.1", ] [[package]] @@ -10307,7 +10413,7 @@ dependencies = [ "bincode", "cbindgen", "cc", - "cfg-if", + "cfg-if 1.0.1", "elliptic-curve", "generic-array 1.1.0", "glob", @@ -10377,7 +10483,7 @@ version = "5.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4d6faecc70f0ca84d0e1259ab2f5eb6d2d351d263c3cd00edf654f8530c0473" dependencies = [ - "cfg-if", + "cfg-if 1.0.1", "dashu", "elliptic-curve", "generic-array 1.1.0", @@ -10423,7 +10529,7 @@ checksum = "699935774a5131c1a8b371108d0666c0c80c43611045fb77fae43f2f242676d5" dependencies = [ "bincode", "blake3", - "cfg-if", + "cfg-if 1.0.1", "hex", "lazy_static", "num-bigint 0.4.6", @@ -10546,7 +10652,7 @@ dependencies = [ "backtrace", "cbindgen", "cc", - "cfg-if", + "cfg-if 1.0.1", "ff 0.13.1", "glob", "hashbrown 0.14.5", @@ -10600,7 +10706,7 @@ dependencies = [ "bincode", "bindgen 0.70.1", "cc", - "cfg-if", + "cfg-if 1.0.1", "hex", "num-bigint 0.4.6", "p3-baby-bear", @@ -10627,7 +10733,7 @@ dependencies = [ "async-trait", "backoff", "bincode", - "cfg-if", + "cfg-if 1.0.1", "dirs 5.0.1", "eventsource-stream", "futures", @@ -10702,7 +10808,7 @@ version = "0.8.0-sp1-5.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac255e1704ebcdeec5e02f6a0ebc4d2e9e6b802161938330b6810c13a610c583" dependencies = [ - "cfg-if", + "cfg-if 1.0.1", "ff 0.13.1", "group 0.13.0", "pairing 0.23.0", @@ -10714,7 +10820,7 @@ dependencies = [ [[package]] name = "spawned-concurrency" version = "0.1.0" -source = "git+https://github.com/lambdaclass/spawned.git?tag=v0.1.0-alpha#abd5476b7cc0feeafd96ca79c6844e87702c7f83" +source = "git+https://github.com/lambdaclass/spawned.git?tag=v0.1.2-alpha#c6f757c0cc07a34f9e56c8c7ea8fde483b50ea20" dependencies = [ "futures", "spawned-rt", @@ -10724,9 +10830,11 @@ dependencies = [ [[package]] name = "spawned-rt" version = "0.1.0" -source = "git+https://github.com/lambdaclass/spawned.git?tag=v0.1.0-alpha#abd5476b7cc0feeafd96ca79c6844e87702c7f83" +source = "git+https://github.com/lambdaclass/spawned.git?tag=v0.1.2-alpha#c6f757c0cc07a34f9e56c8c7ea8fde483b50ea20" dependencies = [ + "crossbeam", "tokio", + "tokio-util", "tracing", "tracing-subscriber 0.3.19", ] @@ -11003,7 +11111,7 @@ version = "0.30.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0a5b4ddaee55fb2bea2bf0e5000747e5f5c0de765e5a5ff87f4cd106439f4bb3" dependencies = [ - "cfg-if", + "cfg-if 1.0.1", "core-foundation-sys", "libc", "ntapi", @@ -11190,7 +11298,7 @@ version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" dependencies = [ - "cfg-if", + "cfg-if 1.0.1", ] [[package]] @@ -11264,7 +11372,7 @@ dependencies = [ "arrayref", "arrayvec", "bytemuck", - "cfg-if", + "cfg-if 1.0.1", "log", "png", "tiny-skia-path", @@ -11324,7 +11432,7 @@ checksum = "a41f915e075a8a98ad64a5f7be6b7cc1710fc835c5f07e4a3efcaeb013291c00" dependencies = [ "aho-corasick 0.7.20", "clap 2.34.0", - "crossbeam-channel", + "crossbeam-channel 0.5.15", "dashmap 4.0.2", "dirs 3.0.2", "encoding_rs_io", @@ -11346,17 +11454,19 @@ dependencies = [ [[package]] name = "tokio" -version = "1.45.1" +version = "1.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75ef51a33ef1da925cea3e4eb122833cb377c61439ca401b770f54902b806779" +checksum = "1140bb80481756a8cbe10541f37433b459c5aa1e727b4c020fbfebdc25bf3ec4" dependencies = [ "backtrace", "bytes", + "io-uring", "libc", "mio", "parking_lot 0.12.4", "pin-project-lite", "signal-hook-registry", + "slab", "socket2", "tokio-macros", "windows-sys 0.52.0", @@ -11736,7 +11846,7 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3566e8ce28cc0a3fe42519fc80e6b4c943cc4c8cef275620eb8dac2d3d4e06cf" dependencies = [ - "crossbeam-channel", + "crossbeam-channel 0.5.15", "thiserror 1.0.69", "time", "tracing-subscriber 0.3.19", @@ -11842,7 +11952,7 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6bca43faba247bc76eb1d6c1b8b561e4a1c5bdd427cc3d7a007faabea75c683a" dependencies = [ - "crossbeam-queue", + "crossbeam-queue 0.3.12", "tokio", ] @@ -11913,7 +12023,7 @@ version = "1.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" dependencies = [ - "cfg-if", + "cfg-if 1.0.1", "static_assertions", ] @@ -12401,7 +12511,7 @@ version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" dependencies = [ - "cfg-if", + "cfg-if 1.0.1", "once_cell", "rustversion", "wasm-bindgen-macro", @@ -12427,7 +12537,7 @@ version = "0.4.50" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" dependencies = [ - "cfg-if", + "cfg-if 1.0.1", "js-sys", "once_cell", "wasm-bindgen", @@ -12933,7 +13043,7 @@ version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" dependencies = [ - "cfg-if", + "cfg-if 1.0.1", "windows-sys 0.48.0", ] @@ -13174,7 +13284,7 @@ dependencies = [ "bzip2", "constant_time_eq 0.1.5", "crc32fast", - "crossbeam-utils", + "crossbeam-utils 0.8.21", "flate2", "hmac", "pbkdf2 0.11.0", @@ -13191,7 +13301,7 @@ checksum = "fabe6324e908f85a1c52063ce7aa26b68dcb7eb6dbc83a2d148403c9bc3eba50" dependencies = [ "arbitrary", "crc32fast", - "crossbeam-utils", + "crossbeam-utils 0.8.21", "displaydoc", "flate2", "indexmap 2.10.0", @@ -13212,7 +13322,7 @@ dependencies = [ "blake2", "bls12_381 0.7.1", "byteorder", - "cfg-if", + "cfg-if 1.0.1", "group 0.12.1", "group 0.13.0", "halo2", diff --git a/Cargo.toml b/Cargo.toml index 089bad06da..1b32ab127f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -74,7 +74,7 @@ crc32fast = "1.4.2" lazy_static = "1.5.0" sha2 = "0.10.8" sha3 = "0.10.8" -tokio-util = { version = "0.7.12", features = ["rt"] } +tokio-util = { version = "0.7.15", features = ["rt"] } jsonwebtoken = "9.3.0" rand = "0.8.5" cfg-if = "1.0.0" @@ -95,6 +95,10 @@ eyre = "0.6.12" kzg-rs = "0.2.6" libsql = "0.9.10" futures = "0.3.31" +# Changing the tag for spawned will break the TDX image build +# When updating it try to build the TDX image and update service.nix with the new hash +spawned-concurrency = {git = "https://github.com/lambdaclass/spawned.git", tag = "v0.1.2-alpha"} +spawned-rt = {git = "https://github.com/lambdaclass/spawned.git", tag = "v0.1.2-alpha"} lambdaworks-crypto = "0.11.0" [patch.crates-io] diff --git a/crates/l2/Cargo.toml b/crates/l2/Cargo.toml index 3c5ab91d42..dda10cde8b 100644 --- a/crates/l2/Cargo.toml +++ b/crates/l2/Cargo.toml @@ -34,13 +34,11 @@ keccak-hash.workspace = true envy = "0.4.2" rand.workspace = true thiserror.workspace = true +spawned-rt.workspace = true +spawned-concurrency.workspace = true directories = "5.0.1" bincode = "1.3.3" serde_with = "3.11.0" -# Changing the tag for spawned will break the TDX image build -# When updating it try to build the TDX image and update service.nix with the new hash -spawned-concurrency = { git = "https://github.com/lambdaclass/spawned.git", tag = "v0.1.0-alpha" } -spawned-rt = { git = "https://github.com/lambdaclass/spawned.git", tag = "v0.1.0-alpha" } lazy_static.workspace = true aligned-sdk = { git = "https://github.com/yetanotherco/aligned_layer", tag = "v0.16.1" } ethers = "2.0" diff --git a/crates/l2/based/block_fetcher.rs b/crates/l2/based/block_fetcher.rs index f9fb6ba483..71448d272b 100644 --- a/crates/l2/based/block_fetcher.rs +++ b/crates/l2/based/block_fetcher.rs @@ -17,7 +17,11 @@ use ethrex_rpc::{EthClient, types::receipt::RpcLog}; use ethrex_storage::Store; use ethrex_storage_rollup::{RollupStoreError, StoreRollup}; use keccak_hash::keccak; -use spawned_concurrency::{CallResponse, CastResponse, GenServer, send_after}; +use spawned_concurrency::{ + error::GenServerError, + messages::Unused, + tasks::{CastResponse, GenServer, GenServerHandle, send_after}, +}; use tracing::{debug, error, info}; use crate::{ @@ -52,12 +56,14 @@ pub enum BlockFetcherError { EvmError(#[from] ethrex_vm::EvmError), #[error("Failed to produce the blob bundle")] BlobBundleError, - #[error("Failed to compute privileged transactions hash: {0}")] + #[error("Failed to compute deposit logs hash: {0}")] PrivilegedTransactionError( #[from] ethrex_l2_common::privileged_transactions::PrivilegedTransactionError, ), + // TODO: Avoid propagating GenServerErrors outside GenServer modules + // See https://github.com/lambdaclass/ethrex/issues/3376 #[error("Spawned GenServer Error")] - GenServerError(spawned_concurrency::GenServerError), + GenServerError(GenServerError), } #[derive(Clone)] @@ -131,7 +137,8 @@ impl BlockFetcher { } impl GenServer for BlockFetcher { - type InMsg = InMessage; + type CallMsg = Unused; + type CastMsg = InMessage; type OutMsg = OutMessage; type State = BlockFetcherState; type Error = BlockFetcherError; @@ -140,32 +147,23 @@ impl GenServer for BlockFetcher { Self {} } - async fn handle_call( - &mut self, - _message: Self::InMsg, - _tx: &spawned_rt::mpsc::Sender>, - _state: &mut Self::State, - ) -> spawned_concurrency::CallResponse { - CallResponse::Reply(OutMessage::Done) - } - async fn handle_cast( &mut self, - _message: Self::InMsg, - _tx: &spawned_rt::mpsc::Sender>, - state: &mut Self::State, - ) -> spawned_concurrency::CastResponse { + _message: Self::CastMsg, + handle: &GenServerHandle, + mut state: Self::State, + ) -> CastResponse { if let SequencerStatus::Following = state.sequencer_state.status().await { - let _ = fetch(state).await.inspect_err(|err| { + let _ = fetch(&mut state).await.inspect_err(|err| { error!("Block Fetcher Error: {err}"); }); } send_after( Duration::from_millis(state.fetch_interval_ms), - _tx.clone(), - Self::InMsg::Fetch, + handle.clone(), + Self::CastMsg::Fetch, ); - CastResponse::NoReply + CastResponse::NoReply(state) } } diff --git a/crates/l2/based/state_updater.rs b/crates/l2/based/state_updater.rs index 7b1e519f59..0522c444b8 100644 --- a/crates/l2/based/state_updater.rs +++ b/crates/l2/based/state_updater.rs @@ -6,7 +6,11 @@ use ethrex_l2_sdk::calldata::encode_calldata; use ethrex_rpc::{EthClient, clients::Overrides}; use ethrex_storage::Store; use ethrex_storage_rollup::{RollupStoreError, StoreRollup}; -use spawned_concurrency::{CallResponse, CastResponse, GenServer, GenServerError, send_after}; +use spawned_concurrency::{ + error::GenServerError, + messages::Unused, + tasks::{CastResponse, GenServer, GenServerHandle, send_after}, +}; use tracing::{debug, error, info, warn}; use crate::{ @@ -32,6 +36,8 @@ pub enum StateUpdaterError { InvalidForkChoice(#[from] ethrex_blockchain::error::InvalidForkChoice), #[error("Internal Error: {0}")] InternalError(String), + // TODO: Avoid propagating GenServerErrors outside GenServer modules + // See https://github.com/lambdaclass/ethrex/issues/3376 #[error("Spawned GenServer Error")] GenServerError(GenServerError), } @@ -99,7 +105,8 @@ impl StateUpdater { } impl GenServer for StateUpdater { - type InMsg = InMessage; + type CallMsg = Unused; + type CastMsg = InMessage; type OutMsg = OutMessage; type State = StateUpdaterState; type Error = StateUpdaterError; @@ -108,30 +115,21 @@ impl GenServer for StateUpdater { Self {} } - async fn handle_call( - &mut self, - _message: Self::InMsg, - _tx: &spawned_rt::mpsc::Sender>, - _state: &mut Self::State, - ) -> spawned_concurrency::CallResponse { - CallResponse::Reply(OutMessage::Done) - } - async fn handle_cast( &mut self, - _message: Self::InMsg, - tx: &spawned_rt::mpsc::Sender>, - state: &mut Self::State, - ) -> spawned_concurrency::CastResponse { - let _ = update_state(state) + _message: Self::CastMsg, + handle: &GenServerHandle, + mut state: Self::State, + ) -> CastResponse { + let _ = update_state(&mut state) .await .inspect_err(|err| error!("State Updater Error: {err}")); send_after( Duration::from_millis(state.check_interval_ms), - tx.clone(), - Self::InMsg::UpdateState, + handle.clone(), + Self::CastMsg::UpdateState, ); - CastResponse::NoReply + CastResponse::NoReply(state) } } diff --git a/crates/l2/sequencer/block_producer.rs b/crates/l2/sequencer/block_producer.rs index b75a4cc60d..e3014d7515 100644 --- a/crates/l2/sequencer/block_producer.rs +++ b/crates/l2/sequencer/block_producer.rs @@ -16,8 +16,10 @@ use ethrex_storage_rollup::StoreRollup; use ethrex_vm::BlockExecutionResult; use keccak_hash::H256; use payload_builder::build_payload; -use spawned_concurrency::{CallResponse, CastResponse, GenServer, GenServerInMsg, send_after}; -use spawned_rt::mpsc::Sender; +use spawned_concurrency::{ + messages::Unused, + tasks::{CastResponse, GenServer, GenServerHandle, send_after}, +}; use tracing::{debug, error, info}; use crate::{ @@ -104,7 +106,8 @@ impl BlockProducer { } impl GenServer for BlockProducer { - type InMsg = InMessage; + type CallMsg = Unused; + type CastMsg = InMessage; type OutMsg = OutMessage; type State = BlockProducerState; @@ -114,33 +117,24 @@ impl GenServer for BlockProducer { Self {} } - async fn handle_call( - &mut self, - _message: Self::InMsg, - _tx: &Sender>, - _state: &mut Self::State, - ) -> CallResponse { - CallResponse::Reply(OutMessage::Done) - } - async fn handle_cast( &mut self, - _message: Self::InMsg, - tx: &Sender>, - state: &mut Self::State, - ) -> CastResponse { + _message: Self::CastMsg, + handle: &GenServerHandle, + state: Self::State, + ) -> CastResponse { // Right now we only have the Produce message, so we ignore the message if let SequencerStatus::Sequencing = state.sequencer_state.status().await { - let _ = produce_block(state) + let _ = produce_block(&state) .await .inspect_err(|e| error!("Block Producer Error: {e}")); } send_after( Duration::from_millis(state.block_time_ms), - tx.clone(), - Self::InMsg::Produce, + handle.clone(), + Self::CastMsg::Produce, ); - CastResponse::NoReply + CastResponse::NoReply(state) } } diff --git a/crates/l2/sequencer/errors.rs b/crates/l2/sequencer/errors.rs index c4f772250d..86cba5ff46 100644 --- a/crates/l2/sequencer/errors.rs +++ b/crates/l2/sequencer/errors.rs @@ -12,7 +12,7 @@ use ethrex_rpc::clients::eth::errors::{CalldataEncodeError, EthClientError}; use ethrex_storage::error::StoreError; use ethrex_storage_rollup::RollupStoreError; use ethrex_vm::{EvmError, ProverDBError}; -use spawned_concurrency::GenServerError; +use spawned_concurrency::error::GenServerError; use tokio::task::JoinError; #[derive(Debug, thiserror::Error)] @@ -61,6 +61,8 @@ pub enum L1WatcherError { FailedAccessingRollUpStore(#[from] RollupStoreError), #[error("{0}")] Custom(String), + // TODO: Avoid propagating GenServerErrors outside GenServer modules + // See https://github.com/lambdaclass/ethrex/issues/3376 #[error("Spawned GenServer Error")] GenServerError(GenServerError), } @@ -123,6 +125,8 @@ pub enum ProofSenderError { InternalError(String), #[error("Failed to parse OnChainProposer response: {0}")] FailedToParseOnChainProposerResponse(String), + // TODO: Avoid propagating GenServerErrors outside GenServer modules + // See https://github.com/lambdaclass/ethrex/issues/3376 #[error("Spawned GenServer Error")] GenServerError(GenServerError), #[error("Proof Sender failed because of a rollup store error: {0}")] @@ -189,6 +193,8 @@ pub enum BlockProducerError { FailedToEncodeAccountStateDiff(#[from] StateDiffError), #[error("Failed to get data from: {0}")] FailedToGetDataFrom(String), + // TODO: Avoid propagating GenServerErrors outside GenServer modules + // See https://github.com/lambdaclass/ethrex/issues/3376 #[error("Spawned GenServer Error")] GenServerError(GenServerError), } @@ -235,6 +241,8 @@ pub enum CommitterError { FailedToGetWithdrawals(#[from] UtilsError), #[error("Privileged Transaction error: {0}")] PrivilegedTransactionError(#[from] PrivilegedTransactionError), + // TODO: Avoid propagating GenServerErrors outside GenServer modules + // See https://github.com/lambdaclass/ethrex/issues/3376 #[error("Spawned GenServer Error")] GenServerError(GenServerError), } @@ -261,6 +269,8 @@ pub enum MetricsGathererError { EthClientError(#[from] EthClientError), #[error("MetricsGatherer: {0}")] TryInto(String), + // TODO: Avoid propagating GenServerErrors outside GenServer modules + // See https://github.com/lambdaclass/ethrex/issues/3376 #[error("Spawned GenServer Error")] GenServerError(GenServerError), } @@ -275,6 +285,8 @@ pub enum ExecutionCacheError { #[derive(Debug, thiserror::Error)] pub enum ConnectionHandlerError { + // TODO: Avoid propagating GenServerErrors outside GenServer modules + // See https://github.com/lambdaclass/ethrex/issues/3376 #[error("Spawned GenServer Error")] GenServerError(GenServerError), } diff --git a/crates/l2/sequencer/l1_committer.rs b/crates/l2/sequencer/l1_committer.rs index 34df169c22..86de954400 100644 --- a/crates/l2/sequencer/l1_committer.rs +++ b/crates/l2/sequencer/l1_committer.rs @@ -37,8 +37,10 @@ use std::{collections::HashMap, sync::Arc}; use tracing::{debug, error, info, warn}; use super::{errors::BlobEstimationError, utils::random_duration}; -use spawned_concurrency::{CallResponse, CastResponse, GenServer, GenServerInMsg, send_after}; -use spawned_rt::mpsc::Sender; +use spawned_concurrency::{ + messages::Unused, + tasks::{CastResponse, GenServer, GenServerHandle, send_after}, +}; const COMMIT_FUNCTION_SIGNATURE_BASED: &str = "commitBatch(uint256,bytes32,bytes32,bytes32,bytes32,bytes[])"; @@ -136,7 +138,8 @@ impl L1Committer { } impl GenServer for L1Committer { - type InMsg = InMessage; + type CallMsg = Unused; + type CastMsg = InMessage; type OutMsg = OutMessage; type State = CommitterState; @@ -146,30 +149,21 @@ impl GenServer for L1Committer { Self {} } - async fn handle_call( - &mut self, - _message: Self::InMsg, - _tx: &Sender>, - _state: &mut Self::State, - ) -> CallResponse { - CallResponse::Reply(OutMessage::Done) - } - async fn handle_cast( &mut self, - _message: Self::InMsg, - tx: &Sender>, - state: &mut Self::State, - ) -> CastResponse { + _message: Self::CastMsg, + handle: &GenServerHandle, + mut state: Self::State, + ) -> CastResponse { // Right now we only have the Commit message, so we ignore the message if let SequencerStatus::Sequencing = state.sequencer_state.status().await { - let _ = commit_next_batch_to_l1(state) + let _ = commit_next_batch_to_l1(&mut state) .await .inspect_err(|err| error!("L1 Committer Error: {err}")); } let check_interval = random_duration(state.commit_time_ms); - send_after(check_interval, tx.clone(), Self::InMsg::Commit); - CastResponse::NoReply + send_after(check_interval, handle.clone(), Self::CastMsg::Commit); + CastResponse::NoReply(state) } } diff --git a/crates/l2/sequencer/l1_proof_sender.rs b/crates/l2/sequencer/l1_proof_sender.rs index 9499bc4ae5..7b7490b401 100644 --- a/crates/l2/sequencer/l1_proof_sender.rs +++ b/crates/l2/sequencer/l1_proof_sender.rs @@ -9,8 +9,10 @@ use ethrex_l2_sdk::calldata::encode_calldata; use ethrex_rpc::EthClient; use ethrex_storage_rollup::StoreRollup; use secp256k1::SecretKey; -use spawned_concurrency::{CallResponse, CastResponse, GenServer, GenServerInMsg, send_after}; -use spawned_rt::mpsc::Sender; +use spawned_concurrency::{ + messages::Unused, + tasks::{CastResponse, GenServer, GenServerHandle, send_after}, +}; use tracing::{debug, error, info}; use super::{ @@ -138,7 +140,8 @@ impl L1ProofSender { } impl GenServer for L1ProofSender { - type InMsg = InMessage; + type CallMsg = Unused; + type CastMsg = InMessage; type OutMsg = OutMessage; type State = L1ProofSenderState; @@ -148,30 +151,21 @@ impl GenServer for L1ProofSender { Self {} } - async fn handle_call( - &mut self, - _message: Self::InMsg, - _tx: &Sender>, - _state: &mut Self::State, - ) -> CallResponse { - CallResponse::Reply(OutMessage::Done) - } - async fn handle_cast( &mut self, - _message: Self::InMsg, - tx: &Sender>, - state: &mut Self::State, - ) -> CastResponse { + _message: Self::CastMsg, + handle: &GenServerHandle, + state: Self::State, + ) -> CastResponse { // Right now we only have the Send message, so we ignore the message if let SequencerStatus::Sequencing = state.sequencer_state.status().await { - let _ = verify_and_send_proof(state) + let _ = verify_and_send_proof(&state) .await .inspect_err(|err| error!("L1 Proof Sender: {err}")); } let check_interval = random_duration(state.proof_send_interval_ms); - send_after(check_interval, tx.clone(), Self::InMsg::Send); - CastResponse::NoReply + send_after(check_interval, handle.clone(), Self::CastMsg::Send); + CastResponse::NoReply(state) } } diff --git a/crates/l2/sequencer/l1_watcher.rs b/crates/l2/sequencer/l1_watcher.rs index d941f56bc8..7dc254bd96 100644 --- a/crates/l2/sequencer/l1_watcher.rs +++ b/crates/l2/sequencer/l1_watcher.rs @@ -15,12 +15,11 @@ use ethrex_rpc::{ }; use ethrex_storage::Store; use keccak_hash::keccak; +use spawned_concurrency::messages::Unused; +use spawned_concurrency::tasks::{CastResponse, GenServer, GenServerHandle, send_after}; use std::{cmp::min, sync::Arc}; use tracing::{debug, error, info, warn}; -use spawned_concurrency::{CallResponse, CastResponse, GenServer, GenServerInMsg, send_after}; -use spawned_rt::mpsc::Sender; - #[derive(Clone)] pub struct L1WatcherState { pub store: Store, @@ -89,17 +88,14 @@ impl L1Watcher { &cfg.l1_watcher, sequencer_state, )?; - let mut l1_watcher = L1Watcher::start(state); - // Perform the check and suscribe a periodic Watch. - l1_watcher - .cast(InMessage::Watch) - .await - .map_err(L1WatcherError::GenServerError) + L1Watcher::start(state); + Ok(()) } } impl GenServer for L1Watcher { - type InMsg = InMessage; + type CallMsg = Unused; + type CastMsg = InMessage; type OutMsg = OutMessage; type State = L1WatcherState; type Error = L1WatcherError; @@ -108,29 +104,34 @@ impl GenServer for L1Watcher { Self {} } - async fn handle_call( + async fn init( &mut self, - _message: Self::InMsg, - _tx: &Sender>, - _state: &mut Self::State, - ) -> CallResponse { - CallResponse::Reply(OutMessage::Done) + handle: &GenServerHandle, + state: Self::State, + ) -> Result { + // Perform the check and suscribe a periodic Watch. + handle + .clone() + .cast(Self::CastMsg::Watch) + .await + .map_err(Self::Error::GenServerError)?; + Ok(state) } async fn handle_cast( &mut self, - message: Self::InMsg, - tx: &Sender>, - state: &mut Self::State, - ) -> CastResponse { + message: Self::CastMsg, + handle: &GenServerHandle, + mut state: Self::State, + ) -> CastResponse { match message { - Self::InMsg::Watch => { + Self::CastMsg::Watch => { if let SequencerStatus::Sequencing = state.sequencer_state.status().await { - watch(state).await; + watch(&mut state).await; } let check_interval = random_duration(state.check_interval); - send_after(check_interval, tx.clone(), Self::InMsg::Watch); - CastResponse::NoReply + send_after(check_interval, handle.clone(), Self::CastMsg::Watch); + CastResponse::NoReply(state) } } } diff --git a/crates/l2/sequencer/metrics.rs b/crates/l2/sequencer/metrics.rs index 25bdd46edd..8b3510234f 100644 --- a/crates/l2/sequencer/metrics.rs +++ b/crates/l2/sequencer/metrics.rs @@ -7,8 +7,9 @@ use ethrex_metrics::{ metrics_transactions::METRICS_TX, }; use ethrex_rpc::clients::eth::EthClient; -use spawned_concurrency::{CallResponse, CastResponse, GenServer, GenServerInMsg, send_after}; -use spawned_rt::mpsc::Sender; +use spawned_concurrency::tasks::{ + CallResponse, CastResponse, GenServer, GenServerHandle, send_after, +}; use std::time::Duration; use tracing::{debug, error}; @@ -40,6 +41,7 @@ impl MetricsGathererState { } } +#[derive(Clone)] pub enum InMessage { Gather, } @@ -69,7 +71,8 @@ impl MetricsGatherer { } impl GenServer for MetricsGatherer { - type InMsg = InMessage; + type CallMsg = (); + type CastMsg = InMessage; type OutMsg = OutMessage; type State = MetricsGathererState; @@ -81,25 +84,25 @@ impl GenServer for MetricsGatherer { async fn handle_call( &mut self, - _message: Self::InMsg, - _tx: &Sender>, - _state: &mut Self::State, - ) -> CallResponse { - CallResponse::Reply(OutMessage::Done) + _message: Self::CallMsg, + _handle: &GenServerHandle, + state: Self::State, + ) -> CallResponse { + CallResponse::Reply(state, OutMessage::Done) } async fn handle_cast( &mut self, - _message: Self::InMsg, - tx: &Sender>, - state: &mut Self::State, - ) -> CastResponse { + _message: Self::CastMsg, + handle: &GenServerHandle, + mut state: Self::State, + ) -> CastResponse { // Right now we only have the Gather message, so we ignore the message - let _ = gather_metrics(state) + let _ = gather_metrics(&mut state) .await .inspect_err(|err| error!("Metrics Gatherer Error: {}", err)); - send_after(state.check_interval, tx.clone(), Self::InMsg::Gather); - CastResponse::NoReply + send_after(state.check_interval, handle.clone(), Self::CastMsg::Gather); + CastResponse::NoReply(state) } } diff --git a/crates/l2/sequencer/proof_coordinator.rs b/crates/l2/sequencer/proof_coordinator.rs index b042eca8dd..0cb5ae2c82 100644 --- a/crates/l2/sequencer/proof_coordinator.rs +++ b/crates/l2/sequencer/proof_coordinator.rs @@ -19,7 +19,8 @@ use ethrex_storage_rollup::StoreRollup; use secp256k1::SecretKey; use serde::{Deserialize, Serialize}; use serde_with::serde_as; -use spawned_concurrency::{CallResponse, CastResponse, GenServer}; +use spawned_concurrency::messages::Unused; +use spawned_concurrency::tasks::{CastResponse, GenServer, GenServerHandle}; use std::net::{IpAddr, SocketAddr}; use std::sync::Arc; use tokio::{ @@ -213,8 +214,9 @@ impl ProofCoordinatorState { } } +#[derive(Clone)] pub enum ProofCordInMessage { - Listen { listener: TcpListener }, + Listen { listener: Arc }, } #[derive(Clone, PartialEq)] @@ -243,7 +245,8 @@ impl ProofCoordinator { needed_proof_types, ) .await?; - let listener = TcpListener::bind(format!("{}:{}", state.listen_ip, state.port)).await?; + let listener = + Arc::new(TcpListener::bind(format!("{}:{}", state.listen_ip, state.port)).await?); let mut proof_coordinator = ProofCoordinator::start(state); let _ = proof_coordinator .cast(ProofCordInMessage::Listen { listener }) @@ -253,7 +256,8 @@ impl ProofCoordinator { } impl GenServer for ProofCoordinator { - type InMsg = ProofCordInMessage; + type CallMsg = Unused; + type CastMsg = ProofCordInMessage; type OutMsg = ProofCordOutMessage; type State = ProofCoordinatorState; type Error = ProofCoordinatorError; @@ -262,32 +266,22 @@ impl GenServer for ProofCoordinator { Self {} } - async fn handle_call( - &mut self, - _message: Self::InMsg, - _tx: &spawned_rt::mpsc::Sender>, - _state: &mut Self::State, - ) -> CallResponse { - CallResponse::Reply(ProofCordOutMessage::Done) - } - async fn handle_cast( &mut self, - message: Self::InMsg, - _tx: &spawned_rt::mpsc::Sender>, - state: &mut Self::State, - ) -> CastResponse { - info!("Receiving message"); + message: Self::CastMsg, + _handle: &GenServerHandle, + state: Self::State, + ) -> CastResponse { match message { ProofCordInMessage::Listen { listener } => { - handle_listens(state, listener).await; + handle_listens(&state, listener).await; } } CastResponse::Stop } } -async fn handle_listens(state: &ProofCoordinatorState, listener: TcpListener) { +async fn handle_listens(state: &ProofCoordinatorState, listener: Arc) { info!("Starting TCP server at {}:{}.", state.listen_ip, state.port); loop { let res = listener.accept().await; @@ -323,14 +317,21 @@ impl ConnectionHandler { ) -> Result<(), ConnectionHandlerError> { let mut connection_handler = ConnectionHandler::start(state); connection_handler - .cast(ConnInMessage::Connection { stream, addr }) + .cast(ConnInMessage::Connection { + stream: Arc::new(stream), + addr, + }) .await .map_err(ConnectionHandlerError::GenServerError) } } +#[derive(Clone)] pub enum ConnInMessage { - Connection { stream: TcpStream, addr: SocketAddr }, + Connection { + stream: Arc, + addr: SocketAddr, + }, } #[derive(Clone, PartialEq)] @@ -339,7 +340,8 @@ pub enum ConnOutMessage { } impl GenServer for ConnectionHandler { - type InMsg = ConnInMessage; + type CallMsg = Unused; + type CastMsg = ConnInMessage; type OutMsg = ConnOutMessage; type State = ProofCoordinatorState; type Error = ProofCoordinatorError; @@ -348,25 +350,15 @@ impl GenServer for ConnectionHandler { Self {} } - async fn handle_call( - &mut self, - _message: Self::InMsg, - _tx: &spawned_rt::mpsc::Sender>, - _state: &mut Self::State, - ) -> CallResponse { - CallResponse::Reply(ConnOutMessage::Done) - } - async fn handle_cast( &mut self, - message: Self::InMsg, - _tx: &spawned_rt::mpsc::Sender>, - state: &mut Self::State, - ) -> CastResponse { - info!("Receiving message"); + message: Self::CastMsg, + _handle: &GenServerHandle, + state: Self::State, + ) -> CastResponse { match message { ConnInMessage::Connection { stream, addr } => { - if let Err(err) = handle_connection(state, stream).await { + if let Err(err) = handle_connection(&state, stream).await { error!("Error handling connection from {addr}: {err}"); } else { debug!("Connection from {addr} handled successfully"); @@ -379,43 +371,48 @@ impl GenServer for ConnectionHandler { async fn handle_connection( state: &ProofCoordinatorState, - mut stream: TcpStream, + stream: Arc, ) -> Result<(), ProofCoordinatorError> { let mut buffer = Vec::new(); - stream.read_to_end(&mut buffer).await?; - - let data: Result = serde_json::from_slice(&buffer); - match data { - Ok(ProofData::BatchRequest { commit_hash }) => { - if let Err(e) = handle_request(state, &mut stream, commit_hash).await { - error!("Failed to handle BatchRequest: {e}"); + // TODO: This should be fixed in https://github.com/lambdaclass/ethrex/issues/3316 + // (stream should not be wrapped in an Arc) + if let Some(mut stream) = Arc::into_inner(stream) { + stream.read_to_end(&mut buffer).await?; + + let data: Result = serde_json::from_slice(&buffer); + match data { + Ok(ProofData::BatchRequest { commit_hash }) => { + if let Err(e) = handle_request(state, &mut stream, commit_hash).await { + error!("Failed to handle BatchRequest: {e}"); + } } - } - Ok(ProofData::ProofSubmit { - batch_number, - batch_proof, - }) => { - if let Err(e) = handle_submit(state, &mut stream, batch_number, batch_proof).await { - error!("Failed to handle ProofSubmit: {e}"); + Ok(ProofData::ProofSubmit { + batch_number, + batch_proof, + }) => { + if let Err(e) = handle_submit(state, &mut stream, batch_number, batch_proof).await { + error!("Failed to handle ProofSubmit: {e}"); + } } - } - Ok(ProofData::ProverSetup { - prover_type, - payload, - }) => { - if let Err(e) = handle_setup(state, &mut stream, prover_type, payload).await { - error!("Failed to handle ProverSetup: {e}"); + Ok(ProofData::ProverSetup { + prover_type, + payload, + }) => { + if let Err(e) = handle_setup(state, &mut stream, prover_type, payload).await { + error!("Failed to handle ProverSetup: {e}"); + } + } + Ok(_) => { + warn!("Invalid request"); + } + Err(e) => { + warn!("Failed to parse request: {e}"); } } - Err(e) => { - warn!("Failed to parse request: {e}"); - } - _ => { - warn!("Invalid request"); - } + debug!("Connection closed"); + } else { + error!("Unable to use stream"); } - - debug!("Connection closed"); Ok(()) } diff --git a/crates/l2/tee/quote-gen/Cargo.lock b/crates/l2/tee/quote-gen/Cargo.lock index 86d531a9a2..948c6af6d5 100644 --- a/crates/l2/tee/quote-gen/Cargo.lock +++ b/crates/l2/tee/quote-gen/Cargo.lock @@ -34,9 +34,9 @@ dependencies = [ [[package]] name = "adler2" -version = "2.0.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" [[package]] name = "aes" @@ -44,7 +44,7 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" dependencies = [ - "cfg-if", + "cfg-if 1.0.1", "cipher", "cpufeatures", ] @@ -70,7 +70,7 @@ dependencies = [ "hex", "lambdaworks-crypto 0.12.0", "log", - "reqwest 0.12.19", + "reqwest 0.12.22", "serde", "serde_json", "serde_repr", @@ -200,12 +200,12 @@ checksum = "8c77490fe91a0ce933a1f219029521f20fc28c2c0ca95d53fa4da9c00b8d9d4e" dependencies = [ "alloy-rlp", "bytes", - "cfg-if", + "cfg-if 1.0.1", "const-hex", "derive_more 2.0.1", "foldhash", - "hashbrown 0.15.3", - "indexmap 2.9.0", + "hashbrown 0.15.4", + "indexmap 2.10.0", "itoa", "k256", "keccak-asm", @@ -238,7 +238,7 @@ checksum = "64b728d511962dda67c1bc7ea7c03736ec275ed2cf4c35d9585298ac9ccf3b73" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -297,7 +297,7 @@ dependencies = [ "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -309,11 +309,11 @@ dependencies = [ "alloy-sol-macro-input", "const-hex", "heck", - "indexmap 2.9.0", + "indexmap 2.10.0", "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", "syn-solidity", "tiny-keccak", ] @@ -330,7 +330,7 @@ dependencies = [ "macro-string", "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", "syn-solidity", ] @@ -600,7 +600,7 @@ checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -638,14 +638,14 @@ checksum = "ffdcb70bdbc4d478427380519163274ac86e52916e10f0a8889adf0f96d3fee7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] name = "autocfg" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "axum" @@ -731,7 +731,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" dependencies = [ "addr2line", - "cfg-if", + "cfg-if 1.0.1", "libc", "miniz_oxide", "object", @@ -765,9 +765,9 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "base64ct" -version = "1.7.3" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89e25b6adfb930f02d1981565a6e5d9c547ac15a96606256d3b59040e5cd4ca3" +checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba" [[package]] name = "bech32" @@ -851,7 +851,7 @@ dependencies = [ "arrayref", "arrayvec", "cc", - "cfg-if", + "cfg-if 1.0.1", "constant_time_eq 0.3.1", ] @@ -901,9 +901,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.18.1" +version = "3.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db76d6187cd04dff33004d8e6c9cc4e05cd330500379d2394209271b4aeee" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" [[package]] name = "byte-slice-cast" @@ -995,9 +995,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.26" +version = "1.2.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "956a5e21988b87f372569b66183b78babf23ebc2e744b733e4350a752c4dafac" +checksum = "d487aa071b5f64da6f19a3e848e3578944b726ee5a4854b82172f02aa876bfdc" dependencies = [ "jobserver", "libc", @@ -1006,9 +1006,15 @@ dependencies = [ [[package]] name = "cfg-if" -version = "1.0.0" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "cfg-if" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" [[package]] name = "chrono" @@ -1062,9 +1068,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.39" +version = "4.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd60e63e9be68e5fb56422e397cf9baddded06dae1d2e523401542383bc72a9f" +checksum = "40b6887a1d8685cebccf115538db5c0efe625ccac9696ad45c409d96566e910f" dependencies = [ "clap_builder", "clap_derive", @@ -1072,9 +1078,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.39" +version = "4.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89cc6392a1f72bbeb820d71f32108f61fdaf18bc526e1d23954168a67759ef51" +checksum = "e0c66c08ce9f0c698cbce5c0279d0bb6ac936d8674174fe48f736533b964f59e" dependencies = [ "anstream", "anstyle", @@ -1084,21 +1090,21 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.32" +version = "4.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7" +checksum = "d2c7947ae4cc3d851207c1adb5b5e260ff0cca11446b1d6d1423788e442257ce" dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] name = "clap_lex" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" +checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" [[package]] name = "coins-bip32" @@ -1192,7 +1198,7 @@ version = "1.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "83e22e0ed40b96a48d3db274f72fd365bd78f67af39b6bbd47e8a15e1c6207ff" dependencies = [ - "cfg-if", + "cfg-if 1.0.1", "cpufeatures", "hex", "proptest", @@ -1292,7 +1298,42 @@ version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" dependencies = [ - "cfg-if", + "cfg-if 1.0.1", +] + +[[package]] +name = "crossbeam" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69323bff1fb41c635347b8ead484a5ca6c3f11914d784170b158d8449ab07f8e" +dependencies = [ + "cfg-if 0.1.10", + "crossbeam-channel", + "crossbeam-deque 0.7.4", + "crossbeam-epoch 0.8.2", + "crossbeam-queue", + "crossbeam-utils 0.7.2", +] + +[[package]] +name = "crossbeam-channel" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b153fe7cbef478c567df0f972e02e6d736db11affe43dfc9c56a9374d1adfb87" +dependencies = [ + "crossbeam-utils 0.7.2", + "maybe-uninit", +] + +[[package]] +name = "crossbeam-deque" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20ff29ded3204c5106278a81a38f4b482636ed4fa1e6cfbeef193291beb29ed" +dependencies = [ + "crossbeam-epoch 0.8.2", + "crossbeam-utils 0.7.2", + "maybe-uninit", ] [[package]] @@ -1301,8 +1342,23 @@ version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" dependencies = [ - "crossbeam-epoch", - "crossbeam-utils", + "crossbeam-epoch 0.9.18", + "crossbeam-utils 0.8.21", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace" +dependencies = [ + "autocfg", + "cfg-if 0.1.10", + "crossbeam-utils 0.7.2", + "lazy_static", + "maybe-uninit", + "memoffset", + "scopeguard", ] [[package]] @@ -1311,7 +1367,29 @@ version = "0.9.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" dependencies = [ - "crossbeam-utils", + "crossbeam-utils 0.8.21", +] + +[[package]] +name = "crossbeam-queue" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "774ba60a54c213d409d5353bda12d49cd68d14e45036a285234c8d6f91f92570" +dependencies = [ + "cfg-if 0.1.10", + "crossbeam-utils 0.7.2", + "maybe-uninit", +] + +[[package]] +name = "crossbeam-utils" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" +dependencies = [ + "autocfg", + "cfg-if 0.1.10", + "lazy_static", ] [[package]] @@ -1322,9 +1400,9 @@ checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "crunchy" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" [[package]] name = "crypto-bigint" @@ -1378,7 +1456,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -1389,7 +1467,7 @@ checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" dependencies = [ "darling_core", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -1460,7 +1538,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -1470,7 +1548,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" dependencies = [ "derive_builder_core", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -1500,7 +1578,7 @@ dependencies = [ "convert_case", "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", "unicode-xid", ] @@ -1512,7 +1590,7 @@ checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", "unicode-xid", ] @@ -1574,7 +1652,7 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" dependencies = [ - "cfg-if", + "cfg-if 1.0.1", "dirs-sys-next", ] @@ -1609,7 +1687,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -1686,7 +1764,7 @@ version = "0.8.35" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" dependencies = [ - "cfg-if", + "cfg-if 1.0.1", ] [[package]] @@ -1715,7 +1793,7 @@ checksum = "2f9ed6b3789237c8a0c1c505af1c7eb2c560df6186f01b098c3a1064ea532f38" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -1735,12 +1813,12 @@ checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "errno" -version = "0.3.12" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cea14ef9355e3beab063703aa9dab15afd25f0667c341310c1e5274bb1d0da18" +checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] @@ -1912,7 +1990,7 @@ dependencies = [ "reqwest 0.11.27", "serde", "serde_json", - "syn 2.0.101", + "syn 2.0.104", "toml", "walkdir", ] @@ -1930,7 +2008,7 @@ dependencies = [ "proc-macro2", "quote", "serde_json", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -1956,7 +2034,7 @@ dependencies = [ "serde", "serde_json", "strum", - "syn 2.0.101", + "syn 2.0.104", "tempfile", "thiserror 1.0.69", "tiny-keccak", @@ -2069,7 +2147,7 @@ version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "66244a771d9163282646dbeffe0e6eca4dda4146b6498644e678ac6089b11edd" dependencies = [ - "cfg-if", + "cfg-if 1.0.1", "const-hex", "dirs", "dunce", @@ -2100,7 +2178,7 @@ name = "ethrex-blockchain" version = "0.1.0" dependencies = [ "bytes", - "cfg-if", + "cfg-if 1.0.1", "ethrex-common", "ethrex-metrics", "ethrex-rlp", @@ -2151,7 +2229,7 @@ dependencies = [ "hex", "jsonwebtoken 9.3.1", "keccak-hash", - "reqwest 0.12.19", + "reqwest 0.12.22", "serde", "serde_json", "sha2", @@ -2167,7 +2245,7 @@ dependencies = [ "aligned-sdk", "bincode", "bytes", - "cfg-if", + "cfg-if 1.0.1", "directories", "envy", "ethereum-types 0.15.1", @@ -2190,7 +2268,7 @@ dependencies = [ "keccak-hash", "lazy_static", "rand 0.8.5", - "reqwest 0.12.19", + "reqwest 0.12.22", "secp256k1", "serde", "serde_json", @@ -2285,6 +2363,8 @@ dependencies = [ "serde_json", "sha3", "snap", + "spawned-concurrency", + "spawned-rt", "thiserror 2.0.12", "tokio", "tokio-stream", @@ -2312,7 +2392,7 @@ dependencies = [ "axum", "axum-extra", "bytes", - "cfg-if", + "cfg-if 1.0.1", "envy", "ethereum-types 0.15.1", "ethrex-blockchain", @@ -2326,7 +2406,7 @@ dependencies = [ "k256", "keccak-hash", "rand 0.8.5", - "reqwest 0.12.19", + "reqwest 0.12.22", "secp256k1", "serde", "serde_json", @@ -2355,7 +2435,7 @@ dependencies = [ "itertools 0.13.0", "keccak-hash", "lazy_static", - "reqwest 0.12.19", + "reqwest 0.12.22", "secp256k1", "serde", "serde_json", @@ -2427,7 +2507,7 @@ version = "0.1.0" dependencies = [ "bincode", "bytes", - "cfg-if", + "cfg-if 1.0.1", "derive_more 1.0.0", "dyn-clone", "ethereum-types 0.15.1", @@ -2543,9 +2623,9 @@ checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" [[package]] name = "flate2" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ced92e76e966ca2fd84c8f7aa01a4aea65b0eb6648d72f7c8f3e2764a67fece" +checksum = "4a3d7db9596fecd151c5f638c0ee5d5bd487b6e0ea232e5dc96d5250f6f94b1d" dependencies = [ "crc32fast", "miniz_oxide", @@ -2669,7 +2749,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -2744,10 +2824,10 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" dependencies = [ - "cfg-if", + "cfg-if 1.0.1", "js-sys", "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi 0.11.1+wasi-snapshot-preview1", "wasm-bindgen", ] @@ -2757,7 +2837,7 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" dependencies = [ - "cfg-if", + "cfg-if 1.0.1", "libc", "r-efi", "wasi 0.14.2+wasi-0.2.4", @@ -2823,7 +2903,7 @@ dependencies = [ "futures-sink", "futures-util", "http 0.2.12", - "indexmap 2.9.0", + "indexmap 2.10.0", "slab", "tokio", "tokio-util", @@ -2832,9 +2912,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.10" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9421a676d1b147b16b82c9225157dc629087ef8ec4d5e2960f9437a90dac0a5" +checksum = "17da50a276f1e01e0ba6c029e47b7100754904ee8a278f886546e98575380785" dependencies = [ "atomic-waker", "bytes", @@ -2842,7 +2922,7 @@ dependencies = [ "futures-core", "futures-sink", "http 1.3.1", - "indexmap 2.9.0", + "indexmap 2.10.0", "slab", "tokio", "tokio-util", @@ -2855,7 +2935,7 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "459196ed295495a68f7d7fe1d84f6c4b7ff0e21fe3017b2f283c6fac3ad803c9" dependencies = [ - "cfg-if", + "cfg-if 1.0.1", "crunchy", ] @@ -2867,9 +2947,9 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "hashbrown" -version = "0.15.3" +version = "0.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84b26c544d002229e640969970a2e74021aadf6e2f96372b9c58eff97de08eb3" +checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5" dependencies = [ "foldhash", "serde", @@ -2916,9 +2996,9 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hermit-abi" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f154ce46856750ed433c8649605bf7ed2de3bc35fd9d2a9f30cddd873c80cb08" +checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" [[package]] name = "hex" @@ -3057,7 +3137,7 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "h2 0.4.10", + "h2 0.4.11", "http 1.3.1", "http-body 1.0.1", "httparse", @@ -3092,7 +3172,7 @@ dependencies = [ "http 1.3.1", "hyper 1.6.0", "hyper-util", - "rustls 0.23.27", + "rustls 0.23.28", "rustls-pki-types", "tokio", "tokio-rustls 0.26.2", @@ -3340,7 +3420,7 @@ checksum = "a0eb5a3343abf848c0984fe4604b2b105da9539376e24fc0a3b0007411ae4fd9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -3362,12 +3442,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.9.0" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" +checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661" dependencies = [ "equivalent", - "hashbrown 0.15.3", + "hashbrown 0.15.4", "serde", ] @@ -3386,7 +3466,7 @@ version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" dependencies = [ - "cfg-if", + "cfg-if 1.0.1", ] [[package]] @@ -3517,7 +3597,7 @@ version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b" dependencies = [ - "cfg-if", + "cfg-if 1.0.1", "ecdsa", "elliptic-curve", "once_cell", @@ -3656,9 +3736,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.172" +version = "0.2.174" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" +checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" [[package]] name = "libgit2-sys" @@ -3680,9 +3760,9 @@ checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" [[package]] name = "libredox" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +checksum = "1580801010e535496706ba011c15f8532df6b42297d2e471fec38ceadd8c0638" dependencies = [ "bitflags 2.9.1", "libc", @@ -3748,7 +3828,7 @@ checksum = "1b27834086c65ec3f9387b096d66e99f221cf081c2b738042aa252bcd41204e3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -3766,21 +3846,36 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3" +[[package]] +name = "maybe-uninit" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" + [[package]] name = "md-5" version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" dependencies = [ - "cfg-if", + "cfg-if 1.0.1", "digest 0.10.7", ] [[package]] name = "memchr" -version = "2.7.4" +version = "2.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" + +[[package]] +name = "memoffset" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "043175f069eda7b85febe4a74abbaeff828d9f8b448515d3151a14a3542811aa" +dependencies = [ + "autocfg", +] [[package]] name = "mime" @@ -3790,9 +3885,9 @@ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "miniz_oxide" -version = "0.8.8" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" dependencies = [ "adler2", ] @@ -3804,7 +3899,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" dependencies = [ "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi 0.11.1+wasi-snapshot-preview1", "windows-sys 0.59.0", ] @@ -3944,23 +4039,24 @@ dependencies = [ [[package]] name = "num_enum" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e613fc340b2220f734a8595782c551f1250e969d87d3be1ae0579e8d4065179" +checksum = "a973b4e44ce6cad84ce69d797acf9a044532e4184c4f267913d1b546a0727b7a" dependencies = [ "num_enum_derive", + "rustversion", ] [[package]] name = "num_enum_derive" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" +checksum = "77e878c846a8abae00dd069496dbe8751b16ac1c3d6bd2a7283a938e8228f90d" dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -4036,7 +4132,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8505734d46c8ab1e19a1dce3aef597ad87dcb4c37e7188231769bd6bd51cebf8" dependencies = [ "bitflags 2.9.1", - "cfg-if", + "cfg-if 1.0.1", "foreign-types", "libc", "once_cell", @@ -4052,7 +4148,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -4243,7 +4339,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -4262,7 +4358,7 @@ version = "0.9.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" dependencies = [ - "cfg-if", + "cfg-if 1.0.1", "libc", "redox_syscall", "smallvec", @@ -4350,9 +4446,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.8.0" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "198db74531d58c70a361c42201efde7e2591e976d518caf7662a47dc5720e7b6" +checksum = "1db05f56d34358a8b1066f67cbb203ee3e7ed2ba674a6263a1d5ec6db2204323" dependencies = [ "memchr", "thiserror 2.0.12", @@ -4366,7 +4462,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset", - "indexmap 2.9.0", + "indexmap 2.10.0", ] [[package]] @@ -4409,7 +4505,7 @@ dependencies = [ "phf_shared", "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -4438,7 +4534,7 @@ checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -4501,12 +4597,12 @@ checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" [[package]] name = "prettyplease" -version = "0.2.33" +version = "0.2.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dee91521343f4c5c6a63edd65e54f31f5c92fe8978c40a4282f8372194c6a7d" +checksum = "061c1221631e079b26479d25bbf2275bfe5917ae8419cd7e34f13bfc2aa7539a" dependencies = [ "proc-macro2", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -4573,7 +4669,7 @@ dependencies = [ "proc-macro-error-attr2", "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -4587,17 +4683,17 @@ dependencies = [ [[package]] name = "proptest" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14cae93065090804185d3b75f0bf93b8eeda30c7a9b4a33d3bdb3988d6229e50" +checksum = "6fcdab19deb5195a31cf7726a210015ff1496ba1464fd42cb4f537b8b01b471f" dependencies = [ "bit-set 0.8.0", "bit-vec 0.8.0", "bitflags 2.9.1", "lazy_static", "num-traits", - "rand 0.8.5", - "rand_chacha 0.3.1", + "rand 0.9.1", + "rand_chacha 0.9.0", "rand_xorshift", "regex-syntax 0.8.5", "rusty-fork", @@ -4648,9 +4744,9 @@ dependencies = [ [[package]] name = "r-efi" -version = "5.2.0" +version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" [[package]] name = "radium" @@ -4720,11 +4816,11 @@ dependencies = [ [[package]] name = "rand_xorshift" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f" +checksum = "513962919efc330f829edb2535844d1b912b0fbe2ca165d613e4e8788bb05a5a" dependencies = [ - "rand_core 0.6.4", + "rand_core 0.9.3", ] [[package]] @@ -4743,15 +4839,15 @@ version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" dependencies = [ - "crossbeam-deque", - "crossbeam-utils", + "crossbeam-deque 0.8.6", + "crossbeam-utils 0.8.21", ] [[package]] name = "redox_syscall" -version = "0.5.12" +version = "0.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "928fca9cf2aa042393a8325b9ead81d2f0df4cb12e1e24cef072922ccd99c5af" +checksum = "0d04b7d0ee6b4a0207a0a7adb104d23ecb0b47d6beae7152d0fa34b692b29fd6" dependencies = [ "bitflags 2.9.1", ] @@ -4767,6 +4863,26 @@ dependencies = [ "thiserror 1.0.69", ] +[[package]] +name = "ref-cast" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a0ae411dbe946a674d89546582cea4ba2bb8defac896622d6496f14c23ba5cf" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1165225c21bff1f3bbce98f5a1f889949bc902d3575308cc7b0de30b4f6d27c7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + [[package]] name = "regex" version = "1.11.1" @@ -4854,15 +4970,15 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.12.19" +version = "0.12.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2f8e5513d63f2e5b386eb5106dc67eaf3f84e95258e210489136b8b92ad6119" +checksum = "cbc931937e6ca3a06e3b6c0aa7841849b160a90351d6ab467a8b9b9959767531" dependencies = [ "base64 0.22.1", "bytes", "encoding_rs", "futures-core", - "h2 0.4.10", + "h2 0.4.11", "http 1.3.1", "http-body 1.0.1", "http-body-util", @@ -4870,12 +4986,10 @@ dependencies = [ "hyper-rustls 0.27.7", "hyper-tls", "hyper-util", - "ipnet", "js-sys", "log", "mime", "native-tls", - "once_cell", "percent-encoding", "pin-project-lite", "rustls-pki-types", @@ -4901,7 +5015,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c175ecec83bba464aa8406502fe5bf670491c2ace81a153264891d43bc7fa332" dependencies = [ "auto_impl", - "cfg-if", + "cfg-if 1.0.1", "dyn-clone", "revm-interpreter", "revm-precompile", @@ -4945,7 +5059,7 @@ checksum = "99743c3a2cac341084cc15ac74286c4bf34a0941ebf60aa420cfdb9f81f72f9f" dependencies = [ "aurora-engine-modexp", "c-kzg", - "cfg-if", + "cfg-if 1.0.1", "k256", "once_cell", "revm-primitives", @@ -4968,7 +5082,7 @@ dependencies = [ "bitflags 2.9.1", "bitvec", "c-kzg", - "cfg-if", + "cfg-if 1.0.1", "dyn-clone", "enumn", "hex", @@ -5007,7 +5121,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" dependencies = [ "cc", - "cfg-if", + "cfg-if 1.0.1", "getrandom 0.2.16", "libc", "untrusted 0.9.0", @@ -5090,9 +5204,9 @@ checksum = "48fd7bd8a6377e15ad9d42a8ec25371b94ddc67abe7c8b9127bec79bebaaae18" [[package]] name = "rustc-demangle" -version = "0.1.24" +version = "0.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" +checksum = "989e6739f80c4ad5b13e0fd7fe89531180375b18520cc8c82080e4dc4035b84f" [[package]] name = "rustc-hash" @@ -5151,9 +5265,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.27" +version = "0.23.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "730944ca083c1c233a75c09f199e973ca499344a2b7ba9e755c457e86fb4a321" +checksum = "7160e3e10bf4535308537f3c4e1641468cd0e485175d6163087c0393c7d46643" dependencies = [ "once_cell", "rustls-pki-types", @@ -5249,7 +5363,7 @@ version = "2.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "346a3b32eba2640d17a9cb5927056b08f3de90f65b72fe09402c2ad07d684d0b" dependencies = [ - "cfg-if", + "cfg-if 1.0.1", "derive_more 1.0.0", "parity-scale-codec", "scale-info-derive", @@ -5264,7 +5378,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -5276,6 +5390,30 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "schemars" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd191f9397d57d581cddd31014772520aa448f65ef991055d7f61582c65165f" +dependencies = [ + "dyn-clone", + "ref-cast", + "serde", + "serde_json", +] + +[[package]] +name = "schemars" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1375ba8ef45a6f15d83fa8748f1079428295d403d6ea991d09ab100155fbc06d" +dependencies = [ + "dyn-clone", + "ref-cast", + "serde", + "serde_json", +] + [[package]] name = "scopeguard" version = "1.2.0" @@ -5425,7 +5563,7 @@ checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -5434,7 +5572,7 @@ version = "1.0.140" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" dependencies = [ - "indexmap 2.9.0", + "indexmap 2.10.0", "itoa", "memchr", "ryu", @@ -5459,7 +5597,7 @@ checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -5485,15 +5623,17 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.12.0" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6b6f7f2fcb69f747921f79f3926bd1e203fce4fef62c268dd3abfb6d86029aa" +checksum = "f2c45cd61fefa9db6f254525d46e392b852e0e61d9a1fd36e5bd183450a556d5" dependencies = [ "base64 0.22.1", "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.9.0", + "indexmap 2.10.0", + "schemars 0.9.0", + "schemars 1.0.3", "serde", "serde_derive", "serde_json", @@ -5503,14 +5643,14 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.12.0" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d00caa5193a3c8362ac2b73be6b9e768aa5a4b2f721d8f4b339600c3cb51f8e" +checksum = "de90945e6565ce0d9a25098082ed4ee4002e047cb59892c318d66821e14bb30f" dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -5519,7 +5659,7 @@ version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ - "cfg-if", + "cfg-if 1.0.1", "cpufeatures", "digest 0.10.7", ] @@ -5530,7 +5670,7 @@ version = "0.10.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ - "cfg-if", + "cfg-if 1.0.1", "cpufeatures", "digest 0.10.7", ] @@ -5552,7 +5692,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c28efc5e327c837aa837c59eae585fc250715ef939ac32881bcc11677cd02d46" dependencies = [ "cc", - "cfg-if", + "cfg-if 1.0.1", ] [[package]] @@ -5615,12 +5755,9 @@ checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" [[package]] name = "slab" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" -dependencies = [ - "autocfg", -] +checksum = "04dc19736151f35336d325007ac991178d504a119863a2fcb3758cdb5e52c50d" [[package]] name = "smallvec" @@ -5663,9 +5800,9 @@ dependencies = [ [[package]] name = "sp1-lib" -version = "5.0.0" +version = "5.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03046db52868c1b60e8acffa0777ef6dc11ec1bbbb10b9eb612a871f69c8d3f6" +checksum = "d0fd8bc101e5603ccf2dc1836ea06410f25ce2298755b2dac626add9be2424b4" dependencies = [ "bincode", "serde", @@ -5674,13 +5811,13 @@ dependencies = [ [[package]] name = "sp1-primitives" -version = "5.0.0" +version = "5.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6939d6b2f63e54e5fbd208a0293027608f22511741b62fe32b6f67f6c144e0c0" +checksum = "699935774a5131c1a8b371108d0666c0c80c43611045fb77fae43f2f242676d5" dependencies = [ "bincode", "blake3", - "cfg-if", + "cfg-if 1.0.1", "hex", "lazy_static", "num-bigint 0.4.6", @@ -5698,7 +5835,7 @@ version = "0.8.0-sp1-5.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac255e1704ebcdeec5e02f6a0ebc4d2e9e6b802161938330b6810c13a610c583" dependencies = [ - "cfg-if", + "cfg-if 1.0.1", "ff", "group", "pairing", @@ -5710,7 +5847,7 @@ dependencies = [ [[package]] name = "spawned-concurrency" version = "0.1.0" -source = "git+https://github.com/lambdaclass/spawned.git?tag=v0.1.0-alpha#abd5476b7cc0feeafd96ca79c6844e87702c7f83" +source = "git+https://github.com/lambdaclass/spawned.git?tag=v0.1.2-alpha#c6f757c0cc07a34f9e56c8c7ea8fde483b50ea20" dependencies = [ "futures", "spawned-rt", @@ -5720,9 +5857,11 @@ dependencies = [ [[package]] name = "spawned-rt" version = "0.1.0" -source = "git+https://github.com/lambdaclass/spawned.git?tag=v0.1.0-alpha#abd5476b7cc0feeafd96ca79c6844e87702c7f83" +source = "git+https://github.com/lambdaclass/spawned.git?tag=v0.1.2-alpha#c6f757c0cc07a34f9e56c8c7ea8fde483b50ea20" dependencies = [ + "crossbeam", "tokio", + "tokio-util", "tracing", "tracing-subscriber", ] @@ -5798,7 +5937,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -5853,9 +5992,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.101" +version = "2.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf" +checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" dependencies = [ "proc-macro2", "quote", @@ -5871,7 +6010,7 @@ dependencies = [ "paste", "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -5897,7 +6036,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -5998,7 +6137,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -6009,17 +6148,16 @@ checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] name = "thread_local" -version = "1.1.8" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" dependencies = [ - "cfg-if", - "once_cell", + "cfg-if 1.0.1", ] [[package]] @@ -6124,7 +6262,7 @@ checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -6153,7 +6291,7 @@ version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" dependencies = [ - "rustls 0.23.27", + "rustls 0.23.28", "tokio", ] @@ -6207,7 +6345,7 @@ dependencies = [ "futures-core", "futures-sink", "futures-util", - "hashbrown 0.15.3", + "hashbrown 0.15.4", "pin-project-lite", "tokio", ] @@ -6239,7 +6377,7 @@ version = "0.22.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" dependencies = [ - "indexmap 2.9.0", + "indexmap 2.10.0", "serde", "serde_spanned", "toml_datetime", @@ -6313,13 +6451,13 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.29" +version = "0.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b1ffbcf9c6f6b99d386e7444eb608ba646ae452a36b39737deb9663b610f662" +checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -6472,9 +6610,9 @@ checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" [[package]] name = "unicode-width" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" +checksum = "4a1a07cc7db3810833284e8d372ccdc6da29741639ecc70c9ec107df0fa6154c" [[package]] name = "unicode-xid" @@ -6619,9 +6757,9 @@ dependencies = [ [[package]] name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" +version = "0.11.1+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasi" @@ -6638,7 +6776,7 @@ version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" dependencies = [ - "cfg-if", + "cfg-if 1.0.1", "once_cell", "rustversion", "wasm-bindgen-macro", @@ -6654,7 +6792,7 @@ dependencies = [ "log", "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", "wasm-bindgen-shared", ] @@ -6664,7 +6802,7 @@ version = "0.4.50" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" dependencies = [ - "cfg-if", + "cfg-if 1.0.1", "js-sys", "once_cell", "wasm-bindgen", @@ -6689,7 +6827,7 @@ checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -6771,7 +6909,7 @@ checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -6782,20 +6920,20 @@ checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] name = "windows-link" -version = "0.1.1" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" [[package]] name = "windows-registry" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3bab093bdd303a1240bb99b8aba8ea8a69ee19d34c9e2ef9594e708a4878820" +checksum = "5b8a9ed28765efc97bbc954883f4e6796c33a06546ebafacbabee9696967499e" dependencies = [ "windows-link", "windows-result", @@ -6847,6 +6985,15 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.2", +] + [[package]] name = "windows-targets" version = "0.48.5" @@ -6871,13 +7018,29 @@ dependencies = [ "windows_aarch64_gnullvm 0.52.6", "windows_aarch64_msvc 0.52.6", "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm", + "windows_i686_gnullvm 0.52.6", "windows_i686_msvc 0.52.6", "windows_x86_64_gnu 0.52.6", "windows_x86_64_gnullvm 0.52.6", "windows_x86_64_msvc 0.52.6", ] +[[package]] +name = "windows-targets" +version = "0.53.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c66f69fcc9ce11da9966ddb31a40968cad001c5bedeb5c2b82ede4253ab48aef" +dependencies = [ + "windows_aarch64_gnullvm 0.53.0", + "windows_aarch64_msvc 0.53.0", + "windows_i686_gnu 0.53.0", + "windows_i686_gnullvm 0.53.0", + "windows_i686_msvc 0.53.0", + "windows_x86_64_gnu 0.53.0", + "windows_x86_64_gnullvm 0.53.0", + "windows_x86_64_msvc 0.53.0", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.48.5" @@ -6890,6 +7053,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" + [[package]] name = "windows_aarch64_msvc" version = "0.48.5" @@ -6902,6 +7071,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" + [[package]] name = "windows_i686_gnu" version = "0.48.5" @@ -6914,12 +7089,24 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" +[[package]] +name = "windows_i686_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" + [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" + [[package]] name = "windows_i686_msvc" version = "0.48.5" @@ -6932,6 +7119,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" +[[package]] +name = "windows_i686_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" + [[package]] name = "windows_x86_64_gnu" version = "0.48.5" @@ -6944,6 +7137,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" @@ -6956,6 +7155,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" + [[package]] name = "windows_x86_64_msvc" version = "0.48.5" @@ -6968,11 +7173,17 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" + [[package]] name = "winnow" -version = "0.7.10" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06928c8748d81b05c9be96aad92e1b6ff01833332f281e8cfca3be4b35fc9ec" +checksum = "74c7b26e3480b707944fc872477815d29a8e429d2f93a1ce000f5fa84a15cbcd" dependencies = [ "memchr", ] @@ -6983,7 +7194,7 @@ version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" dependencies = [ - "cfg-if", + "cfg-if 1.0.1", "windows-sys 0.48.0", ] @@ -7004,9 +7215,9 @@ checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" [[package]] name = "ws_stream_wasm" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7999f5f4217fe3818726b66257a4475f71e74ffd190776ad053fa159e50737f5" +checksum = "6c173014acad22e83f16403ee360115b38846fe754e735c5d9d3803fe70c6abc" dependencies = [ "async_io_stream", "futures", @@ -7015,7 +7226,7 @@ dependencies = [ "pharos", "rustc_version 0.4.1", "send_wrapper 0.6.0", - "thiserror 1.0.69", + "thiserror 2.0.12", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", @@ -7056,28 +7267,28 @@ checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", "synstructure", ] [[package]] name = "zerocopy" -version = "0.8.25" +version = "0.8.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1702d9583232ddb9174e01bb7c15a2ab8fb1bc6f227aa1233858c351a3ba0cb" +checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.25" +version = "0.8.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28a6e20d751156648aa063f3800b706ee209a32c0b4d9f24be3d980b01be55ef" +checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -7097,7 +7308,7 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", "synstructure", ] @@ -7118,7 +7329,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -7151,7 +7362,7 @@ checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.104", ] [[package]] @@ -7165,7 +7376,7 @@ dependencies = [ "bzip2", "constant_time_eq 0.1.5", "crc32fast", - "crossbeam-utils", + "crossbeam-utils 0.8.21", "flate2", "hmac", "pbkdf2 0.11.0", diff --git a/crates/l2/tee/quote-gen/service.nix b/crates/l2/tee/quote-gen/service.nix index ccae0408ea..1d1479539c 100644 --- a/crates/l2/tee/quote-gen/service.nix +++ b/crates/l2/tee/quote-gen/service.nix @@ -20,7 +20,7 @@ let lockFile = ./Cargo.lock; outputHashes = { "bls12_381-0.8.0" = "sha256-8/pXRA7hVAPeMKCZ+PRPfQfxqstw5Ob4MJNp85pv5WQ="; - "spawned-concurrency-0.1.0" = "sha256-/RO23J4c1fNVpF6ZgHdVPp3C2mgpg+dCwLjg0JcZ0YI="; + "spawned-concurrency-0.1.0" = "sha256-63xBuGAlrHvIf8hboScUY4LZronPZJZzmfJBdAbUKTU="; "aligned-sdk-0.1.0" = "sha256-Az97VtggdN4gsYds3myezNJ+mNeSaIDbF0Pq5kq2M3M="; "lambdaworks-crypto-0.12.0" = "sha256-4vgW/O85zVLhhFrcZUwcPjavy/rRWB8LGTabAkPNrDw="; }; diff --git a/crates/networking/p2p/Cargo.toml b/crates/networking/p2p/Cargo.toml index 2c798e0cf4..a796ab5f46 100644 --- a/crates/networking/p2p/Cargo.toml +++ b/crates/networking/p2p/Cargo.toml @@ -21,6 +21,8 @@ thiserror.workspace = true lazy_static.workspace = true snap.workspace = true serde.workspace = true +spawned-rt.workspace = true +spawned-concurrency.workspace = true tokio-stream = "0.1.17" futures = "0.3.31" diff --git a/crates/networking/p2p/discv4/server.rs b/crates/networking/p2p/discv4/server.rs index 3d2676d7ce..44d224c99a 100644 --- a/crates/networking/p2p/discv4/server.rs +++ b/crates/networking/p2p/discv4/server.rs @@ -10,8 +10,8 @@ use super::{ }; use crate::{ kademlia::{KademliaTable, MAX_NODES_PER_BUCKET}, - network::{P2PContext, handle_peer_as_initiator}, - rlpx::{connection::MAX_PEERS_TCP_CONNECTIONS, utils::node_id}, + network::P2PContext, + rlpx::{connection::server::RLPxConnection, utils::node_id}, types::{Endpoint, Node}, }; use ethrex_common::H256; @@ -27,6 +27,7 @@ use tracing::{debug, error}; const MAX_DISC_PACKET_SIZE: usize = 1280; const PROOF_EXPIRATION_IN_HS: u64 = 12; +pub const MAX_PEERS_TCP_CONNECTIONS: usize = 100; // These interval times are arbitrary numbers, maybe we should read them from a cfg or a cli param const REVALIDATION_INTERVAL_IN_SECONDS: u64 = 30; @@ -224,10 +225,8 @@ impl Discv4Server { return Ok(()); } - let ctx = self.ctx.clone(); - self.ctx - .tracker - .spawn(async move { handle_peer_as_initiator(ctx, peer.node).await }); + RLPxConnection::spawn_as_initiator(self.ctx.clone(), &peer.node).await; + Ok(()) } Message::FindNode(msg) => { @@ -518,11 +517,8 @@ impl Discv4Server { if active_connections >= MAX_PEERS_TCP_CONNECTIONS { return Ok(()); } - let ctx = self.ctx.clone(); - self.ctx - .tracker - .spawn(async move { handle_peer_as_initiator(ctx, peer.node).await }); + RLPxConnection::spawn_as_initiator(self.ctx.clone(), &peer.node).await; Ok(()) } diff --git a/crates/networking/p2p/kademlia.rs b/crates/networking/p2p/kademlia.rs index 4650f85170..4bf794cc89 100644 --- a/crates/networking/p2p/kademlia.rs +++ b/crates/networking/p2p/kademlia.rs @@ -1,10 +1,11 @@ use crate::{ discv4::messages::FindNodeRequest, - rlpx::{message::Message as RLPxMessage, p2p::Capability}, + rlpx::{connection::server::RLPxConnection, message::Message as RLPxMessage, p2p::Capability}, types::{Node, NodeRecord}, }; use ethrex_common::{H256, U256}; use rand::random; +use spawned_concurrency::tasks::GenServerHandle; use std::sync::Arc; use tokio::sync::mpsc::UnboundedSender; use tokio::sync::{Mutex, mpsc}; @@ -487,25 +488,24 @@ pub const MAX_MESSAGES_IN_PEER_CHANNEL: usize = 25; #[derive(Debug, Clone)] /// Holds the respective sender and receiver ends of the communication channels bewteen the peer data and its active connection pub struct PeerChannels { - pub(crate) sender: mpsc::Sender, + pub(crate) connection: GenServerHandle, pub(crate) receiver: Arc>>, } impl PeerChannels { /// Sets up the communication channels for the peer /// Returns the channel endpoints to send to the active connection's listen loop - pub(crate) fn create() -> (Self, mpsc::Sender, mpsc::Receiver) { - let (sender, connection_receiver) = - mpsc::channel::(MAX_MESSAGES_IN_PEER_CHANNEL); + pub(crate) fn create( + connection: GenServerHandle, + ) -> (Self, mpsc::Sender) { let (connection_sender, receiver) = mpsc::channel::(MAX_MESSAGES_IN_PEER_CHANNEL); ( Self { - sender, + connection, receiver: Arc::new(Mutex::new(receiver)), }, connection_sender, - connection_receiver, ) } } diff --git a/crates/networking/p2p/network.rs b/crates/networking/p2p/network.rs index 2b028f31b2..4b90710778 100644 --- a/crates/networking/p2p/network.rs +++ b/crates/networking/p2p/network.rs @@ -1,13 +1,9 @@ +use crate::discv4::server::{DiscoveryError, Discv4Server}; use crate::kademlia::{self, KademliaTable}; +use crate::rlpx::connection::server::{RLPxConnBroadcastSender, RLPxConnection}; +use crate::rlpx::message::Message as RLPxMessage; use crate::rlpx::p2p::SUPPORTED_SNAP_CAPABILITIES; -use crate::rlpx::{ - connection::RLPxConnBroadcastSender, handshake, message::Message as RLPxMessage, -}; use crate::types::{Node, NodeRecord}; -use crate::{ - discv4::server::{DiscoveryError, Discv4Server}, - rlpx::utils::log_peer_debug, -}; use ethrex_blockchain::Blockchain; use ethrex_common::{H256, H512}; use ethrex_storage::Store; @@ -17,11 +13,11 @@ use k256::{ }; use std::{io, net::SocketAddr, sync::Arc}; use tokio::{ - net::{TcpListener, TcpSocket, TcpStream}, + net::{TcpListener, TcpSocket}, sync::Mutex, }; use tokio_util::task::TaskTracker; -use tracing::{debug, error, info}; +use tracing::{error, info}; // Totally arbitrary limit on how // many messages the connections can queue, @@ -133,9 +129,7 @@ pub(crate) async fn serve_p2p_requests(context: P2PContext) { } }; - context - .tracker - .spawn(handle_peer_as_receiver(context.clone(), peer_addr, stream)); + let _ = RLPxConnection::spawn_as_receiver(context.clone(), peer_addr, stream).await; } } @@ -145,40 +139,6 @@ fn listener(tcp_addr: SocketAddr) -> Result { tcp_socket.listen(50) } -async fn handle_peer_as_receiver(context: P2PContext, peer_addr: SocketAddr, stream: TcpStream) { - let table = context.table.clone(); - match handshake::as_receiver(context, peer_addr, stream).await { - Ok(mut conn) => conn.start(table, true).await, - Err(e) => { - debug!("Error creating tcp connection with peer at {peer_addr}: {e}") - } - } -} - -pub async fn handle_peer_as_initiator(context: P2PContext, node: Node) { - let addr = SocketAddr::new(node.ip, node.tcp_port); - let stream = match tcp_stream(addr).await { - Ok(result) => result, - Err(e) => { - log_peer_debug(&node, &format!("Error creating tcp connection {e}")); - context.table.lock().await.replace_peer(node.node_id()); - return; - } - }; - let table = context.table.clone(); - match handshake::as_initiator(context, node.clone(), stream).await { - Ok(mut conn) => conn.start(table, false).await, - Err(e) => { - log_peer_debug(&node, &format!("Error creating tcp connection {e}")); - table.lock().await.replace_peer(node.node_id()); - } - }; -} - -async fn tcp_stream(addr: SocketAddr) -> Result { - TcpSocket::new_v4()?.connect(addr).await -} - pub fn public_key_from_signing_key(signer: &SigningKey) -> H512 { let public_key = PublicKey::from(signer.verifying_key()); let encoded = public_key.to_encoded_point(false); diff --git a/crates/networking/p2p/peer_handler.rs b/crates/networking/p2p/peer_handler.rs index 8fa81e4bcd..be73be6f2f 100644 --- a/crates/networking/p2p/peer_handler.rs +++ b/crates/networking/p2p/peer_handler.rs @@ -13,6 +13,7 @@ use tokio::sync::Mutex; use crate::{ kademlia::{KademliaTable, PeerChannels, PeerData}, rlpx::{ + connection::server::CastMessage, eth::{ blocks::{ BLOCK_HEADER_LIMIT, BlockBodies, BlockHeaders, GetBlockBodies, GetBlockHeaders, @@ -127,13 +128,17 @@ impl PeerHandler { skip: 0, reverse: matches!(order, BlockRequestOrder::NewToOld), }); - let (peer_id, peer_channel) = self + let (peer_id, mut peer_channel) = self .get_peer_channel_with_retry(&SUPPORTED_ETH_CAPABILITIES) .await?; let mut receiver = peer_channel.receiver.lock().await; - if let Err(err) = peer_channel.sender.send(request).await { - debug!("Failed to send message to peer: {err}"); + if let Err(err) = peer_channel + .connection + .cast(CastMessage::BackendMessage(request)) + .await + { self.record_peer_failure(peer_id).await; + debug!("Failed to send message to peer: {err:?}"); continue; } if let Some(block_headers) = tokio::time::timeout(PEER_REPLY_TIMEOUT, async move { @@ -185,13 +190,17 @@ impl PeerHandler { id: request_id, block_hashes: block_hashes.clone(), }); - let (peer_id, peer_channel) = self + let (peer_id, mut peer_channel) = self .get_peer_channel_with_retry(&SUPPORTED_ETH_CAPABILITIES) .await?; let mut receiver = peer_channel.receiver.lock().await; - if let Err(err) = peer_channel.sender.send(request).await { - debug!("Failed to send message to peer: {err}"); + if let Err(err) = peer_channel + .connection + .cast(CastMessage::BackendMessage(request)) + .await + { self.record_peer_failure(peer_id).await; + debug!("Failed to send message to peer: {err:?}"); return None; } if let Some(block_bodies) = tokio::time::timeout(PEER_REPLY_TIMEOUT, async move { @@ -305,12 +314,16 @@ impl PeerHandler { id: request_id, block_hashes: block_hashes.clone(), }); - let (_, peer_channel) = self + let (_, mut peer_channel) = self .get_peer_channel_with_retry(&SUPPORTED_ETH_CAPABILITIES) .await?; let mut receiver = peer_channel.receiver.lock().await; - if let Err(err) = peer_channel.sender.send(request).await { - debug!("Failed to send message to peer: {err}"); + if let Err(err) = peer_channel + .connection + .cast(CastMessage::BackendMessage(request)) + .await + { + debug!("Failed to send message to peer: {err:?}"); continue; } if let Some(receipts) = tokio::time::timeout(PEER_REPLY_TIMEOUT, async move { @@ -362,12 +375,16 @@ impl PeerHandler { limit_hash: limit, response_bytes: MAX_RESPONSE_BYTES, }); - let (_, peer_channel) = self + let (_, mut peer_channel) = self .get_peer_channel_with_retry(&SUPPORTED_SNAP_CAPABILITIES) .await?; let mut receiver = peer_channel.receiver.lock().await; - if let Err(err) = peer_channel.sender.send(request).await { - debug!("Failed to send message to peer: {err}"); + if let Err(err) = peer_channel + .connection + .cast(CastMessage::BackendMessage(request)) + .await + { + debug!("Failed to send message to peer: {err:?}"); continue; } if let Some((accounts, proof)) = tokio::time::timeout(PEER_REPLY_TIMEOUT, async move { @@ -425,12 +442,16 @@ impl PeerHandler { hashes: hashes.clone(), bytes: MAX_RESPONSE_BYTES, }); - let (_, peer_channel) = self + let (_, mut peer_channel) = self .get_peer_channel_with_retry(&SUPPORTED_SNAP_CAPABILITIES) .await?; let mut receiver = peer_channel.receiver.lock().await; - if let Err(err) = peer_channel.sender.send(request).await { - debug!("Failed to send message to peer: {err}"); + if let Err(err) = peer_channel + .connection + .cast(CastMessage::BackendMessage(request)) + .await + { + debug!("Failed to send message to peer: {err:?}"); continue; } if let Some(codes) = tokio::time::timeout(PEER_REPLY_TIMEOUT, async move { @@ -482,12 +503,16 @@ impl PeerHandler { limit_hash: HASH_MAX, response_bytes: MAX_RESPONSE_BYTES, }); - let (_, peer_channel) = self + let (_, mut peer_channel) = self .get_peer_channel_with_retry(&SUPPORTED_SNAP_CAPABILITIES) .await?; let mut receiver = peer_channel.receiver.lock().await; - if let Err(err) = peer_channel.sender.send(request).await { - debug!("Failed to send message to peer: {err}"); + if let Err(err) = peer_channel + .connection + .cast(CastMessage::BackendMessage(request)) + .await + { + debug!("Failed to send message to peer: {err:?}"); continue; } if let Some((mut slots, proof)) = tokio::time::timeout(PEER_REPLY_TIMEOUT, async move { @@ -583,12 +608,16 @@ impl PeerHandler { .collect(), bytes: MAX_RESPONSE_BYTES, }); - let (_, peer_channel) = self + let (_, mut peer_channel) = self .get_peer_channel_with_retry(&SUPPORTED_SNAP_CAPABILITIES) .await?; let mut receiver = peer_channel.receiver.lock().await; - if let Err(err) = peer_channel.sender.send(request).await { - debug!("Failed to send message to peer: {err}"); + if let Err(err) = peer_channel + .connection + .cast(CastMessage::BackendMessage(request)) + .await + { + debug!("Failed to send message to peer: {err:?}"); continue; } if let Some(nodes) = tokio::time::timeout(PEER_REPLY_TIMEOUT, async move { @@ -657,12 +686,16 @@ impl PeerHandler { .collect(), bytes: MAX_RESPONSE_BYTES, }); - let (_, peer_channel) = self + let (_, mut peer_channel) = self .get_peer_channel_with_retry(&SUPPORTED_SNAP_CAPABILITIES) .await?; let mut receiver = peer_channel.receiver.lock().await; - if let Err(err) = peer_channel.sender.send(request).await { - debug!("Failed to send message to peer: {err}"); + if let Err(err) = peer_channel + .connection + .cast(CastMessage::BackendMessage(request)) + .await + { + debug!("Failed to send message to peer: {err:?}"); continue; } if let Some(nodes) = tokio::time::timeout(PEER_REPLY_TIMEOUT, async move { @@ -724,12 +757,16 @@ impl PeerHandler { limit_hash: HASH_MAX, response_bytes: MAX_RESPONSE_BYTES, }); - let (_, peer_channel) = self + let (_, mut peer_channel) = self .get_peer_channel_with_retry(&SUPPORTED_SNAP_CAPABILITIES) .await?; let mut receiver = peer_channel.receiver.lock().await; - if let Err(err) = peer_channel.sender.send(request).await { - debug!("Failed to send message to peer: {err}"); + if let Err(err) = peer_channel + .connection + .cast(CastMessage::BackendMessage(request)) + .await + { + debug!("Failed to send message to peer: {err:?}"); continue; } if let Some((mut slots, proof)) = tokio::time::timeout(PEER_REPLY_TIMEOUT, async move { diff --git a/crates/networking/p2p/rlpx.rs b/crates/networking/p2p/rlpx.rs index 12082b65c7..1880b39487 100644 --- a/crates/networking/p2p/rlpx.rs +++ b/crates/networking/p2p/rlpx.rs @@ -1,8 +1,6 @@ pub mod connection; pub mod error; pub mod eth; -pub mod frame; -pub mod handshake; pub mod message; pub mod p2p; pub mod snap; diff --git a/crates/networking/p2p/rlpx/connection.rs b/crates/networking/p2p/rlpx/connection.rs deleted file mode 100644 index c8c2b2c04e..0000000000 --- a/crates/networking/p2p/rlpx/connection.rs +++ /dev/null @@ -1,729 +0,0 @@ -use super::{ - eth::{transactions::NewPooledTransactionHashes, update::BlockRangeUpdate}, - p2p::DisconnectReason, - utils::log_peer_warn, -}; -use crate::{ - kademlia::PeerChannels, - rlpx::{ - error::RLPxError, - eth::{ - backend, - blocks::{BlockBodies, BlockHeaders}, - receipts::{GetReceipts, Receipts}, - status::StatusMessage, - transactions::{GetPooledTransactions, Transactions}, - }, - frame::RLPxCodec, - message::Message, - p2p::{ - self, Capability, DisconnectMessage, PingMessage, PongMessage, - SUPPORTED_ETH_CAPABILITIES, SUPPORTED_P2P_CAPABILITIES, SUPPORTED_SNAP_CAPABILITIES, - }, - utils::{log_peer_debug, log_peer_error}, - }, - snap::{ - process_account_range_request, process_byte_codes_request, process_storage_ranges_request, - process_trie_nodes_request, - }, - types::Node, -}; -use ethrex_blockchain::Blockchain; -use ethrex_common::{ - H256, H512, - types::{MempoolTransaction, Transaction}, -}; -use ethrex_storage::Store; -use futures::SinkExt; -use k256::{PublicKey, SecretKey, ecdsa::SigningKey}; -use rand::random; -use std::{ - collections::{HashMap, HashSet}, - sync::Arc, -}; -use tokio::{ - io::{AsyncRead, AsyncWrite}, - sync::{ - Mutex, - broadcast::{self, error::RecvError}, - mpsc, - }, - task, - time::{Instant, sleep}, -}; -use tokio_stream::StreamExt; -use tokio_util::codec::Framed; -use tracing::debug; - -const PERIODIC_PING_INTERVAL: std::time::Duration = std::time::Duration::from_secs(10); -const PERIODIC_TX_BROADCAST_INTERVAL: std::time::Duration = std::time::Duration::from_millis(500); -const PERIODIC_TASKS_CHECK_INTERVAL: std::time::Duration = std::time::Duration::from_millis(500); -const PERIODIC_BLOCK_RANGE_UPDATE_INTERVAL: std::time::Duration = - std::time::Duration::from_secs(60); -pub const MAX_PEERS_TCP_CONNECTIONS: usize = 100; - -pub(crate) type Aes256Ctr64BE = ctr::Ctr64BE; - -pub(crate) type RLPxConnBroadcastSender = broadcast::Sender<(tokio::task::Id, Arc)>; - -pub(crate) struct RemoteState { - pub(crate) public_key: H512, - pub(crate) nonce: H256, - pub(crate) ephemeral_key: PublicKey, - pub(crate) init_message: Vec, -} - -pub(crate) struct LocalState { - pub(crate) nonce: H256, - pub(crate) ephemeral_key: SecretKey, - pub(crate) init_message: Vec, -} - -/// Fully working RLPx connection. -pub(crate) struct RLPxConnection { - signer: SigningKey, - node: Node, - framed: Framed, - storage: Store, - blockchain: Arc, - capabilities: Vec, - negotiated_eth_capability: Option, - negotiated_snap_capability: Option, - next_periodic_ping: Instant, - next_tx_broadcast: Instant, - next_block_range_update: Instant, - last_block_range_update_block: u64, - broadcasted_txs: HashSet, - requested_pooled_txs: HashMap, - client_version: String, - /// Send end of the channel used to broadcast messages - /// to other connected peers, is ok to have it here, - /// since internally it's an Arc. - /// The ID is to ignore the message sent from the same task. - /// This is used both to send messages and to received broadcasted - /// messages from other connections (sent from other peers). - /// The receive end is instantiated after the handshake is completed - /// under `handle_peer`. - connection_broadcast_send: RLPxConnBroadcastSender, -} - -impl RLPxConnection { - #[allow(clippy::too_many_arguments)] - pub fn new( - signer: SigningKey, - node: Node, - stream: S, - codec: RLPxCodec, - storage: Store, - blockchain: Arc, - client_version: String, - connection_broadcast: RLPxConnBroadcastSender, - ) -> Self { - Self { - signer, - node, - framed: Framed::new(stream, codec), - storage, - blockchain, - capabilities: vec![], - negotiated_eth_capability: None, - negotiated_snap_capability: None, - next_periodic_ping: Instant::now() + PERIODIC_TASKS_CHECK_INTERVAL, - next_tx_broadcast: Instant::now() + PERIODIC_TX_BROADCAST_INTERVAL, - next_block_range_update: Instant::now() + PERIODIC_BLOCK_RANGE_UPDATE_INTERVAL, - last_block_range_update_block: 0, - broadcasted_txs: HashSet::new(), - requested_pooled_txs: HashMap::new(), - client_version, - connection_broadcast_send: connection_broadcast, - } - } - - async fn post_handshake_checks( - &self, - table: Arc>, - ) -> Result<(), DisconnectReason> { - // Check if connected peers exceed the limit - let peer_count = { - let table_lock = table.lock().await; - table_lock.count_connected_peers() - }; - - if peer_count >= MAX_PEERS_TCP_CONNECTIONS { - return Err(DisconnectReason::TooManyPeers); - } - - Ok(()) - } - - /// Handshake already performed, now it starts a peer connection. - /// It runs in it's own task and blocks until the connection is dropped - pub async fn start( - &mut self, - table: Arc>, - inbound: bool, - ) { - log_peer_debug(&self.node, "Starting RLPx connection"); - - if let Err(reason) = self.post_handshake_checks(table.clone()).await { - self.connection_failed( - "Post handshake validations failed", - RLPxError::DisconnectSent(reason), - table, - ) - .await; - return; - } - - if let Err(e) = self.exchange_hello_messages().await { - self.connection_failed("Hello messages exchange failed", e, table) - .await; - } else { - // Handshake OK: handle connection - // Create channels to communicate directly to the peer - let (peer_channels, sender, receiver) = PeerChannels::create(); - - // NOTE: if the peer came from the discovery server it will already be inserted in the table - // but that might not always be the case, so we try to add it to the table - // Note: we don't ping the node we let the validation service do its job - { - let mut table_lock = table.lock().await; - table_lock.insert_node_forced(self.node.clone()); - table_lock.init_backend_communication( - self.node.node_id(), - peer_channels, - self.capabilities.clone(), - inbound, - ); - } - if let Err(e) = self.connection_loop(sender, receiver).await { - self.connection_failed("Error during RLPx connection", e, table) - .await; - } - } - } - - async fn send_disconnect_message(&mut self, reason: Option) { - self.send(Message::Disconnect(DisconnectMessage { reason })) - .await - .unwrap_or_else(|_| { - log_peer_debug( - &self.node, - &format!("Could not send Disconnect message: ({reason:?})."), - ); - }); - } - - async fn connection_failed( - &mut self, - error_text: &str, - error: RLPxError, - table: Arc>, - ) { - log_peer_debug(&self.node, &format!("{error_text}: ({error})")); - - // Send disconnect message only if error is different than RLPxError::DisconnectRequested - // because if it is a DisconnectRequested error it means that the peer requested the disconnection, not us. - if !matches!(error, RLPxError::DisconnectReceived(_)) { - self.send_disconnect_message(self.match_disconnect_reason(&error)) - .await; - } - - // Discard peer from kademlia table in some cases - match error { - // already connected, don't discard it - RLPxError::DisconnectReceived(DisconnectReason::AlreadyConnected) - | RLPxError::DisconnectSent(DisconnectReason::AlreadyConnected) => { - log_peer_debug(&self.node, "Peer already connected, don't replace it"); - } - _ => { - let remote_public_key = self.node.public_key; - log_peer_debug( - &self.node, - &format!("{error_text}: ({error}), discarding peer {remote_public_key}"), - ); - table.lock().await.replace_peer(self.node.node_id()); - } - } - - let _ = self.framed.close().await; - } - - fn match_disconnect_reason(&self, error: &RLPxError) -> Option { - match error { - RLPxError::DisconnectSent(reason) => Some(*reason), - RLPxError::DisconnectReceived(reason) => Some(*reason), - RLPxError::RLPDecodeError(_) => Some(DisconnectReason::NetworkError), - // TODO build a proper matching between error types and disconnection reasons - _ => None, - } - } - - async fn exchange_hello_messages(&mut self) -> Result<(), RLPxError> { - let supported_capabilities: Vec = [ - &SUPPORTED_ETH_CAPABILITIES[..], - &SUPPORTED_SNAP_CAPABILITIES[..], - &SUPPORTED_P2P_CAPABILITIES[..], - ] - .concat(); - let hello_msg = Message::Hello(p2p::HelloMessage::new( - supported_capabilities, - PublicKey::from(self.signer.verifying_key()), - self.client_version.clone(), - )); - - self.send(hello_msg).await?; - - // Receive Hello message - let msg = match self.receive().await { - Some(msg) => msg?, - None => return Err(RLPxError::Disconnected()), - }; - - match msg { - Message::Hello(hello_message) => { - let mut negotiated_eth_version = 0; - let mut negotiated_snap_version = 0; - - log_peer_debug( - &self.node, - &format!( - "Hello message capabilities {:?}", - hello_message.capabilities - ), - ); - - // Check if we have any capability in common and store the highest version - for cap in &hello_message.capabilities { - match cap.protocol { - "eth" => { - if SUPPORTED_ETH_CAPABILITIES.contains(cap) - && cap.version > negotiated_eth_version - { - negotiated_eth_version = cap.version; - } - } - "snap" => { - if SUPPORTED_SNAP_CAPABILITIES.contains(cap) - && cap.version > negotiated_snap_version - { - negotiated_snap_version = cap.version; - } - } - _ => {} - } - } - - self.capabilities = hello_message.capabilities; - - if negotiated_eth_version == 0 { - return Err(RLPxError::NoMatchingCapabilities()); - } - debug!("Negotatied eth version: eth/{}", negotiated_eth_version); - self.negotiated_eth_capability = Some(Capability::eth(negotiated_eth_version)); - - if negotiated_snap_version != 0 { - debug!("Negotatied snap version: snap/{}", negotiated_snap_version); - self.negotiated_snap_capability = - Some(Capability::snap(negotiated_snap_version)); - } - - self.node.version = Some(hello_message.client_id); - - Ok(()) - } - Message::Disconnect(disconnect) => { - Err(RLPxError::DisconnectReceived(disconnect.reason())) - } - _ => { - // Fail if it is not a hello message - Err(RLPxError::BadRequest("Expected Hello message".to_string())) - } - } - } - - async fn connection_loop( - &mut self, - sender: mpsc::Sender, - mut receiver: mpsc::Receiver, - ) -> Result<(), RLPxError> { - self.init_peer_conn().await?; - log_peer_debug(&self.node, "Started peer main loop"); - - // Subscribe this connection to the broadcasting channel. - let mut broadcaster_receive = if self.negotiated_eth_capability.is_some() { - Some(self.connection_broadcast_send.subscribe()) - } else { - None - }; - - // Send transactions transaction hashes from mempool at connection start - self.send_new_pooled_tx_hashes().await?; - // Start listening for messages, - loop { - tokio::select! { - // Expect a message from the remote peer - Some(message) = self.receive() => { - match message { - Ok(message) => { - log_peer_debug(&self.node, &format!("Received message {message}")); - self.handle_message(message, sender.clone()).await?; - }, - Err(e) => { - log_peer_debug(&self.node, &format!("Received RLPX Error in msg {e}")); - return Err(e); - } - } - } - // Expect a message from the backend - Some(message) = receiver.recv() => { - log_peer_debug(&self.node, &format!("Sending message {message}")); - self.send(message).await?; - } - // This is not ideal, but using the receiver without - // this function call, causes the loop to take ownwership - // of the variable and the compiler will complain about it, - // with this function, we avoid that. - // If the broadcaster is Some (i.e. we're connected to a peer that supports an eth protocol), - // we'll receive broadcasted messages from another connections through a channel, otherwise - // the function below will yield immediately but the select will not match and - // ignore the returned value. - Some(broadcasted_msg) = Self::maybe_wait_for_broadcaster(&mut broadcaster_receive) => { - self.handle_broadcast(broadcasted_msg?).await? - } - // Allow an interruption to check periodic tasks - _ = sleep(PERIODIC_TASKS_CHECK_INTERVAL) => (), // noop - } - self.check_periodic_tasks().await?; - } - } - - async fn maybe_wait_for_broadcaster( - receiver: &mut Option)>>, - ) -> Option), RecvError>> { - match receiver { - None => None, - Some(rec) => Some(rec.recv().await), - } - } - - async fn check_periodic_tasks(&mut self) -> Result<(), RLPxError> { - if Instant::now() >= self.next_periodic_ping { - self.send(Message::Ping(PingMessage {})).await?; - log_peer_debug(&self.node, "Ping sent"); - self.next_periodic_ping = Instant::now() + PERIODIC_PING_INTERVAL; - }; - if Instant::now() >= self.next_tx_broadcast { - self.send_new_pooled_tx_hashes().await?; - self.next_tx_broadcast = Instant::now() + PERIODIC_TX_BROADCAST_INTERVAL; - }; - if Instant::now() >= self.next_block_range_update { - self.next_block_range_update = Instant::now() + PERIODIC_BLOCK_RANGE_UPDATE_INTERVAL; - if self.should_send_block_range_update().await? { - self.send_block_range_update().await?; - } - }; - Ok(()) - } - - async fn send_new_pooled_tx_hashes(&mut self) -> Result<(), RLPxError> { - if SUPPORTED_ETH_CAPABILITIES - .iter() - .any(|cap| self.capabilities.contains(cap)) - { - let filter = - |tx: &Transaction| -> bool { !self.broadcasted_txs.contains(&tx.compute_hash()) }; - let txs: Vec = self - .blockchain - .mempool - .filter_transactions_with_filter_fn(&filter)? - .into_values() - .flatten() - .collect(); - if !txs.is_empty() { - let tx_count = txs.len(); - for tx in txs { - self.send(Message::NewPooledTransactionHashes( - NewPooledTransactionHashes::new(vec![(*tx).clone()], &self.blockchain)?, - )) - .await?; - // Possible improvement: the mempool already knows the hash but the filter function does not return it - self.broadcasted_txs.insert((*tx).compute_hash()); - } - log_peer_debug(&self.node, &format!("Sent {tx_count} transactions to peer")); - } - } - Ok(()) - } - - async fn send_block_range_update(&mut self) -> Result<(), RLPxError> { - // BlockRangeUpdate was introduced in eth/69 - if let Some(eth) = &self.negotiated_eth_capability { - if eth.version >= 69 { - log_peer_debug(&self.node, "Sending BlockRangeUpdate"); - let update = BlockRangeUpdate::new(&self.storage).await?; - let lastet_block = update.lastest_block; - self.send(Message::BlockRangeUpdate(update)).await?; - self.last_block_range_update_block = lastet_block - (lastet_block % 32); - } - } - Ok(()) - } - - async fn should_send_block_range_update(&mut self) -> Result { - let latest_block = self.storage.get_latest_block_number().await?; - if latest_block < self.last_block_range_update_block - || latest_block - self.last_block_range_update_block >= 32 - { - return Ok(true); - } - Ok(false) - } - - async fn handle_message( - &mut self, - message: Message, - sender: mpsc::Sender, - ) -> Result<(), RLPxError> { - let peer_supports_eth = self.negotiated_eth_capability.is_some(); - match message { - Message::Disconnect(msg_data) => { - log_peer_debug( - &self.node, - &format!("Received Disconnect: {}", msg_data.reason()), - ); - // TODO handle the disconnection request - return Err(RLPxError::DisconnectReceived(msg_data.reason())); - } - Message::Ping(_) => { - log_peer_debug(&self.node, "Sending pong message"); - self.send(Message::Pong(PongMessage {})).await?; - } - Message::Pong(_) => { - // We ignore received Pong messages - } - Message::Status(msg_data) => { - if let Some(eth) = &self.negotiated_eth_capability { - backend::validate_status(msg_data, &self.storage, eth).await? - }; - } - Message::GetAccountRange(req) => { - let response = process_account_range_request(req, self.storage.clone())?; - self.send(Message::AccountRange(response)).await? - } - Message::Transactions(txs) if peer_supports_eth => { - if self.blockchain.is_synced() { - let mut valid_txs = vec![]; - for tx in &txs.transactions { - if let Err(e) = self.blockchain.add_transaction_to_pool(tx.clone()).await { - log_peer_warn(&self.node, &format!("Error adding transaction: {e}")); - continue; - } - valid_txs.push(tx.clone()); - } - if !valid_txs.is_empty() { - self.broadcast_message(Message::Transactions(Transactions::new( - valid_txs, - )))?; - } - } - } - Message::GetBlockHeaders(msg_data) if peer_supports_eth => { - let response = BlockHeaders { - id: msg_data.id, - block_headers: msg_data.fetch_headers(&self.storage).await, - }; - self.send(Message::BlockHeaders(response)).await?; - } - Message::GetBlockBodies(msg_data) if peer_supports_eth => { - let response = BlockBodies { - id: msg_data.id, - block_bodies: msg_data.fetch_blocks(&self.storage).await, - }; - self.send(Message::BlockBodies(response)).await?; - } - Message::GetReceipts(GetReceipts { id, block_hashes }) if peer_supports_eth => { - if let Some(eth) = &self.negotiated_eth_capability { - let mut receipts = Vec::new(); - for hash in block_hashes.iter() { - receipts.push(self.storage.get_receipts_for_block(hash)?); - } - let response = Receipts::new(id, receipts, eth)?; - self.send(Message::Receipts(response)).await?; - } - } - Message::BlockRangeUpdate(update) => { - if update.earliest_block > update.lastest_block { - return Err(RLPxError::InvalidBlockRange); - } - - //TODO implement the logic - log_peer_debug( - &self.node, - &format!( - "Range block update: {} to {}", - update.earliest_block, update.lastest_block - ), - ); - } - Message::NewPooledTransactionHashes(new_pooled_transaction_hashes) - if peer_supports_eth => - { - let hashes = - new_pooled_transaction_hashes.get_transactions_to_request(&self.blockchain)?; - - let request_id = random(); - self.requested_pooled_txs - .insert(request_id, new_pooled_transaction_hashes); - - let request = GetPooledTransactions::new(request_id, hashes); - self.send(Message::GetPooledTransactions(request)).await?; - } - Message::GetPooledTransactions(msg) => { - let response = msg.handle(&self.blockchain)?; - self.send(Message::PooledTransactions(response)).await?; - } - Message::PooledTransactions(msg) if peer_supports_eth => { - if self.blockchain.is_synced() { - if let Some(requested) = self.requested_pooled_txs.get(&msg.id) { - if let Err(error) = msg.validate_requested(requested).await { - log_peer_warn( - &self.node, - &format!("disconnected from peer. Reason: {error}"), - ); - self.send_disconnect_message(Some(DisconnectReason::SubprotocolError)) - .await; - return Err(RLPxError::DisconnectSent( - DisconnectReason::SubprotocolError, - )); - } else { - self.requested_pooled_txs.remove(&msg.id); - } - } - msg.handle(&self.node, &self.blockchain).await?; - } - } - Message::GetStorageRanges(req) => { - let response = process_storage_ranges_request(req, self.storage.clone())?; - self.send(Message::StorageRanges(response)).await? - } - Message::GetByteCodes(req) => { - let response = process_byte_codes_request(req, self.storage.clone())?; - self.send(Message::ByteCodes(response)).await? - } - Message::GetTrieNodes(req) => { - let response = process_trie_nodes_request(req, self.storage.clone())?; - self.send(Message::TrieNodes(response)).await? - } - // Send response messages to the backend - message @ Message::AccountRange(_) - | message @ Message::StorageRanges(_) - | message @ Message::ByteCodes(_) - | message @ Message::TrieNodes(_) - | message @ Message::BlockBodies(_) - | message @ Message::BlockHeaders(_) - | message @ Message::Receipts(_) => sender.send(message).await?, - // TODO: Add new message types and handlers as they are implemented - message => return Err(RLPxError::MessageNotHandled(format!("{message}"))), - }; - Ok(()) - } - - async fn handle_broadcast( - &mut self, - (id, broadcasted_msg): (task::Id, Arc), - ) -> Result<(), RLPxError> { - if id != tokio::task::id() { - match broadcasted_msg.as_ref() { - Message::Transactions(txs) => { - // TODO(#1131): Avoid cloning this vector. - let cloned = txs.transactions.clone(); - let new_msg = Message::Transactions(Transactions { - transactions: cloned, - }); - self.send(new_msg).await?; - } - msg => { - let error_message = format!("Non-supported message broadcasted: {msg}"); - log_peer_error(&self.node, &error_message); - return Err(RLPxError::BroadcastError(error_message)); - } - } - } - Ok(()) - } - - async fn init_peer_conn(&mut self) -> Result<(), RLPxError> { - // Sending eth Status if peer supports it - if let Some(eth) = self.negotiated_eth_capability.clone() { - let status = StatusMessage::new(&self.storage, ð).await?; - log_peer_debug(&self.node, "Sending status"); - self.send(Message::Status(status)).await?; - // The next immediate message in the ETH protocol is the - // status, reference here: - // https://github.com/ethereum/devp2p/blob/master/caps/eth.md#status-0x00 - let msg = match self.receive().await { - Some(msg) => msg?, - None => return Err(RLPxError::Disconnected()), - }; - match msg { - Message::Status(msg_data) => { - log_peer_debug(&self.node, "Received Status"); - backend::validate_status(msg_data, &self.storage, ð).await? - } - Message::Disconnect(disconnect) => { - return Err(RLPxError::HandshakeError(format!( - "Peer disconnected due to: {}", - disconnect.reason() - ))); - } - _ => { - return Err(RLPxError::HandshakeError( - "Expected a Status message".to_string(), - )); - } - } - } - - Ok(()) - } - - async fn send(&mut self, message: Message) -> Result<(), RLPxError> { - self.framed.send(message).await - } - - /// Reads from the frame until a frame is available. - /// - /// Returns `None` when the stream buffer is 0. This could indicate that the client has disconnected, - /// but we cannot safely assume an EOF, as per the Tokio documentation. - /// - /// If the handshake has not been established, it is reasonable to terminate the connection. - /// - /// For an established connection, [`check_periodic_task`] will detect actual disconnections - /// while sending pings and you should not assume a disconnection. - /// - /// See [`Framed::new`] for more details. - async fn receive(&mut self) -> Option> { - self.framed.next().await - } - - fn broadcast_message(&self, msg: Message) -> Result<(), RLPxError> { - match msg { - txs_msg @ Message::Transactions(_) => { - let txs = Arc::new(txs_msg); - let task_id = tokio::task::id(); - let Ok(_) = self.connection_broadcast_send.send((task_id, txs)) else { - let error_message = "Could not broadcast received transactions"; - log_peer_error(&self.node, error_message); - return Err(RLPxError::BroadcastError(error_message.to_owned())); - }; - Ok(()) - } - msg => { - let error_message = format!("Broadcasting for msg: {msg} is not supported"); - log_peer_error(&self.node, &error_message); - Err(RLPxError::BroadcastError(error_message)) - } - } - } -} diff --git a/crates/networking/p2p/rlpx/frame.rs b/crates/networking/p2p/rlpx/connection/codec.rs similarity index 98% rename from crates/networking/p2p/rlpx/frame.rs rename to crates/networking/p2p/rlpx/connection/codec.rs index c657e838dd..24525ba42c 100644 --- a/crates/networking/p2p/rlpx/frame.rs +++ b/crates/networking/p2p/rlpx/connection/codec.rs @@ -1,9 +1,6 @@ -use super::{ - connection::{Aes256Ctr64BE, LocalState, RemoteState}, - error::RLPxError, - message as rlpx, - utils::ecdh_xchng, -}; +use crate::rlpx::{error::RLPxError, message as rlpx, utils::ecdh_xchng}; + +use super::handshake::{LocalState, RemoteState}; use aes::{ Aes256Enc, cipher::{BlockEncrypt as _, KeyInit as _, KeyIvInit, StreamCipher as _}, @@ -19,6 +16,8 @@ use tokio_util::codec::{Decoder, Encoder, Framed}; // Taken from https://github.com/ethereum/go-ethereum/blob/82e963e5c981e36dc4b607dd0685c64cf4aabea8/p2p/rlpx/rlpx.go#L152 const MAX_MESSAGE_SIZE: usize = 0xFFFFFF; +type Aes256Ctr64BE = ctr::Ctr64BE; + pub(crate) struct RLPxCodec { pub(crate) mac_key: H256, pub(crate) ingress_mac: Keccak256, diff --git a/crates/networking/p2p/rlpx/handshake.rs b/crates/networking/p2p/rlpx/connection/handshake.rs similarity index 80% rename from crates/networking/p2p/rlpx/handshake.rs rename to crates/networking/p2p/rlpx/connection/handshake.rs index 745f26dde0..7764e0cdff 100644 --- a/crates/networking/p2p/rlpx/handshake.rs +++ b/crates/networking/p2p/rlpx/connection/handshake.rs @@ -1,11 +1,13 @@ -use std::net::SocketAddr; +use std::{ + collections::{HashMap, HashSet}, + net::SocketAddr, + sync::Arc, +}; use crate::{ - network::P2PContext, rlpx::{ - connection::{LocalState, RLPxConnection, RemoteState}, + connection::server::{Established, InnerState}, error::RLPxError, - frame::RLPxCodec, utils::{ compress_pubkey, decompress_pubkey, ecdh_xchng, kdf, log_peer_debug, sha256, sha256_hmac, @@ -21,6 +23,7 @@ use ethrex_rlp::{ error::RLPDecodeError, structs::{Decoder, Encoder}, }; +use futures::{StreamExt, stream::SplitStream}; use k256::{ PublicKey, SecretKey, ecdsa::{self, RecoveryId, SigningKey, VerifyingKey}, @@ -28,73 +31,116 @@ use k256::{ }; use rand::Rng; use sha3::{Digest, Keccak256}; -use tokio::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt}; +use tokio::{ + io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt}, + net::{TcpSocket, TcpStream}, + sync::Mutex, +}; +use tokio_util::codec::Framed; + +use super::{ + codec::RLPxCodec, + server::{Initiator, Receiver}, +}; type Aes128Ctr64BE = ctr::Ctr64BE; // https://github.com/ethereum/go-ethereum/blob/master/p2p/peer.go#L44 pub const P2P_MAX_MESSAGE_SIZE: usize = 2048; -pub(crate) async fn as_receiver( - context: P2PContext, - peer_addr: SocketAddr, - mut stream: S, -) -> Result, RLPxError> -where - S: AsyncRead + AsyncWrite + std::marker::Unpin, -{ - let remote_state = receive_auth(&context.signer, &mut stream).await?; - let local_state = send_ack(remote_state.public_key, &mut stream).await?; - let hashed_nonces: [u8; 32] = - Keccak256::digest([local_state.nonce.0, remote_state.nonce.0].concat()).into(); - let node = Node::new( - peer_addr.ip(), - peer_addr.port(), - peer_addr.port(), - remote_state.public_key, - ); - let codec = RLPxCodec::new(&local_state, &remote_state, hashed_nonces)?; - log_peer_debug(&node, "Completed handshake as receiver!"); - Ok(RLPxConnection::new( - context.signer, - node, - stream, - codec, - context.storage, - context.blockchain, - context.client_version, - context.broadcast, - )) +pub(crate) struct RemoteState { + pub(crate) public_key: H512, + pub(crate) nonce: H256, + pub(crate) ephemeral_key: PublicKey, + pub(crate) init_message: Vec, } -pub(crate) async fn as_initiator( - context: P2PContext, - node: Node, - mut stream: S, -) -> Result, RLPxError> -where - S: AsyncRead + AsyncWrite + std::marker::Unpin, -{ - let local_state = send_auth(&context.signer, node.public_key, &mut stream).await?; - let remote_state = receive_ack(&context.signer, node.public_key, &mut stream).await?; - // Local node is initator - // keccak256(nonce || initiator-nonce) - let hashed_nonces: [u8; 32] = - Keccak256::digest([remote_state.nonce.0, local_state.nonce.0].concat()).into(); - let codec = RLPxCodec::new(&local_state, &remote_state, hashed_nonces)?; - log_peer_debug(&node, "Completed handshake as initiator!"); - Ok(RLPxConnection::new( - context.signer, - node, +pub(crate) struct LocalState { + pub(crate) nonce: H256, + pub(crate) ephemeral_key: SecretKey, + pub(crate) init_message: Vec, +} + +pub(crate) async fn perform( + state: InnerState, +) -> Result<(Established, SplitStream>), RLPxError> { + let (context, node, framed, inbound) = match state { + InnerState::Initiator(Initiator { context, node }) => { + let addr = SocketAddr::new(node.ip, node.tcp_port); + let mut stream = match tcp_stream(addr).await { + Ok(result) => result, + Err(error) => { + log_peer_debug(&node, &format!("Error creating tcp connection {error}")); + context.table.lock().await.replace_peer(node.node_id()); + return Err(error)?; + } + }; + let local_state = send_auth(&context.signer, node.public_key, &mut stream).await?; + let remote_state = receive_ack(&context.signer, node.public_key, &mut stream).await?; + // Local node is initator + // keccak256(nonce || initiator-nonce) + let hashed_nonces: [u8; 32] = + Keccak256::digest([remote_state.nonce.0, local_state.nonce.0].concat()).into(); + let codec = RLPxCodec::new(&local_state, &remote_state, hashed_nonces)?; + log_peer_debug(&node, "Completed handshake as initiator"); + (context, node, Framed::new(stream, codec), false) + } + InnerState::Receiver(Receiver { + context, + peer_addr, + stream, + }) => { + let Some(mut stream) = Arc::into_inner(stream) else { + return Err(RLPxError::StateError("Cannot use the stream".to_string())); + }; + let remote_state = receive_auth(&context.signer, &mut stream).await?; + let local_state = send_ack(remote_state.public_key, &mut stream).await?; + // Remote node is initiator + // keccak256(nonce || initiator-nonce) + let hashed_nonces: [u8; 32] = + Keccak256::digest([local_state.nonce.0, remote_state.nonce.0].concat()).into(); + let codec = RLPxCodec::new(&local_state, &remote_state, hashed_nonces)?; + let node = Node::new( + peer_addr.ip(), + peer_addr.port(), + peer_addr.port(), + remote_state.public_key, + ); + log_peer_debug(&node, "Completed handshake as receiver"); + (context, node, Framed::new(stream, codec), true) + } + InnerState::Established(_) => { + return Err(RLPxError::StateError("Already established".to_string())); + } + }; + let (sink, stream) = framed.split(); + Ok(( + Established { + signer: context.signer.clone(), + sink: Arc::new(Mutex::new(sink)), + node: node.clone(), + storage: context.storage.clone(), + blockchain: context.blockchain.clone(), + capabilities: vec![], + negotiated_eth_capability: None, + negotiated_snap_capability: None, + last_block_range_update_block: 0, + broadcasted_txs: HashSet::new(), + requested_pooled_txs: HashMap::new(), + client_version: context.client_version.clone(), + connection_broadcast_send: context.broadcast.clone(), + table: context.table.clone(), + backend_channel: None, + inbound, + }, stream, - codec, - context.storage, - context.blockchain, - context.client_version, - context.broadcast, )) } +async fn tcp_stream(addr: SocketAddr) -> Result { + TcpSocket::new_v4()?.connect(addr).await +} + async fn send_auth( signer: &SigningKey, remote_public_key: H512, @@ -534,7 +580,7 @@ mod tests { use hex_literal::hex; use k256::SecretKey; - use crate::rlpx::{handshake::decode_ack_message, utils::decompress_pubkey}; + use crate::rlpx::{connection::handshake::decode_ack_message, utils::decompress_pubkey}; #[test] fn test_ack_decoding() { diff --git a/crates/networking/p2p/rlpx/connection/mod.rs b/crates/networking/p2p/rlpx/connection/mod.rs new file mode 100644 index 0000000000..fcb8ad0ba4 --- /dev/null +++ b/crates/networking/p2p/rlpx/connection/mod.rs @@ -0,0 +1,3 @@ +mod codec; +mod handshake; +pub mod server; diff --git a/crates/networking/p2p/rlpx/connection/server.rs b/crates/networking/p2p/rlpx/connection/server.rs new file mode 100644 index 0000000000..51bfd6f066 --- /dev/null +++ b/crates/networking/p2p/rlpx/connection/server.rs @@ -0,0 +1,856 @@ +use std::{ + collections::{HashMap, HashSet}, + net::SocketAddr, + sync::Arc, + time::Duration, +}; + +use ethrex_blockchain::Blockchain; +use ethrex_common::{ + H256, + types::{MempoolTransaction, Transaction}, +}; +use ethrex_storage::Store; +use futures::{SinkExt as _, Stream, stream::SplitSink}; +use k256::{PublicKey, ecdsa::SigningKey}; +use rand::random; +use spawned_concurrency::{ + messages::Unused, + tasks::{CastResponse, GenServer, GenServerHandle, send_interval}, +}; +use tokio::{ + net::TcpStream, + sync::{Mutex, broadcast, mpsc::Sender}, + task, +}; +use tokio_stream::StreamExt; +use tokio_util::codec::Framed; +use tracing::{debug, error}; + +use crate::{ + discv4::server::MAX_PEERS_TCP_CONNECTIONS, + kademlia::{KademliaTable, PeerChannels}, + network::P2PContext, + rlpx::{ + connection::{codec::RLPxCodec, handshake}, + error::RLPxError, + eth::{ + backend, + blocks::{BlockBodies, BlockHeaders}, + receipts::{GetReceipts, Receipts}, + status::StatusMessage, + transactions::{GetPooledTransactions, NewPooledTransactionHashes, Transactions}, + update::BlockRangeUpdate, + }, + message::Message, + p2p::{ + self, Capability, DisconnectMessage, DisconnectReason, PingMessage, PongMessage, + SUPPORTED_ETH_CAPABILITIES, SUPPORTED_P2P_CAPABILITIES, SUPPORTED_SNAP_CAPABILITIES, + }, + utils::{log_peer_debug, log_peer_error, log_peer_warn}, + }, + snap::{ + process_account_range_request, process_byte_codes_request, process_storage_ranges_request, + process_trie_nodes_request, + }, + types::Node, +}; + +const PING_INTERVAL: Duration = Duration::from_secs(10); +const TX_BROADCAST_INTERVAL: Duration = Duration::from_millis(500); +const BLOCK_RANGE_UPDATE_INTERVAL: Duration = Duration::from_secs(60); + +pub(crate) type RLPxConnBroadcastSender = broadcast::Sender<(tokio::task::Id, Arc)>; + +type MsgResult = Result; +type RLPxConnectionHandle = GenServerHandle; + +#[derive(Clone)] +pub struct RLPxConnectionState(pub InnerState); + +#[derive(Clone)] +pub struct Initiator { + pub(crate) context: P2PContext, + pub(crate) node: Node, +} + +#[derive(Clone)] +pub struct Receiver { + pub(crate) context: P2PContext, + pub(crate) peer_addr: SocketAddr, + pub(crate) stream: Arc, +} + +#[derive(Clone)] +pub struct Established { + pub(crate) signer: SigningKey, + // Sending part of the TcpStream to connect with the remote peer + // The receiving part is owned by the stream listen loop task + pub(crate) sink: Arc, Message>>>, + pub(crate) node: Node, + pub(crate) storage: Store, + pub(crate) blockchain: Arc, + pub(crate) capabilities: Vec, + pub(crate) negotiated_eth_capability: Option, + pub(crate) negotiated_snap_capability: Option, + pub(crate) last_block_range_update_block: u64, + pub(crate) broadcasted_txs: HashSet, + pub(crate) requested_pooled_txs: HashMap, + pub(crate) client_version: String, + //// Send end of the channel used to broadcast messages + //// to other connected peers, is ok to have it here, + //// since internally it's an Arc. + //// The ID is to ignore the message sent from the same task. + //// This is used both to send messages and to received broadcasted + //// messages from other connections (sent from other peers). + //// The receive end is instantiated after the handshake is completed + //// under `handle_peer`. + /// TODO: Improve this mechanism + /// See https://github.com/lambdaclass/ethrex/issues/3388 + pub(crate) connection_broadcast_send: RLPxConnBroadcastSender, + pub(crate) table: Arc>, + pub(crate) backend_channel: Option>, + pub(crate) inbound: bool, +} + +#[derive(Clone)] +pub enum InnerState { + Initiator(Initiator), + Receiver(Receiver), + Established(Established), +} + +impl RLPxConnectionState { + pub fn new_as_receiver(context: P2PContext, peer_addr: SocketAddr, stream: TcpStream) -> Self { + Self(InnerState::Receiver(Receiver { + context, + peer_addr, + stream: Arc::new(stream), + })) + } + + pub fn new_as_initiator(context: P2PContext, node: &Node) -> Self { + Self(InnerState::Initiator(Initiator { + context, + node: node.clone(), + })) + } +} + +#[derive(Clone)] +#[allow(private_interfaces)] +pub enum CastMessage { + PeerMessage(Message), + BackendMessage(Message), + SendPing, + SendNewPooledTxHashes, + BlockRangeUpdate, + BroadcastMessage(task::Id, Arc), +} + +#[derive(Clone)] +#[allow(private_interfaces)] +pub enum OutMessage { + InitResponse { + node: Node, + framed: Arc>>, + }, + Done, + Error, +} + +#[derive(Debug)] +pub struct RLPxConnection {} + +impl RLPxConnection { + pub async fn spawn_as_receiver( + context: P2PContext, + peer_addr: SocketAddr, + stream: TcpStream, + ) -> RLPxConnectionHandle { + let state = RLPxConnectionState::new_as_receiver(context, peer_addr, stream); + RLPxConnection::start(state) + } + + pub async fn spawn_as_initiator(context: P2PContext, node: &Node) -> RLPxConnectionHandle { + let state = RLPxConnectionState::new_as_initiator(context, node); + RLPxConnection::start(state.clone()) + } +} + +impl GenServer for RLPxConnection { + type CallMsg = Unused; + type CastMsg = CastMessage; + type OutMsg = MsgResult; + type State = RLPxConnectionState; + type Error = RLPxError; + + fn new() -> Self { + Self {} + } + + async fn init( + &mut self, + handle: &GenServerHandle, + mut state: Self::State, + ) -> Result { + let (mut established_state, stream) = handshake::perform(state.0).await?; + log_peer_debug(&established_state.node, "Starting RLPx connection"); + + if let Err(reason) = initialize_connection(handle, &mut established_state, stream).await { + connection_failed( + &mut established_state, + "Failed to initialize RLPx connection", + reason, + ) + .await; + Err(RLPxError::Disconnected()) + } else { + // New state + state.0 = InnerState::Established(established_state); + Ok(state) + } + } + + async fn handle_cast( + &mut self, + message: Self::CastMsg, + _handle: &RLPxConnectionHandle, + mut state: Self::State, + ) -> CastResponse { + if let InnerState::Established(mut established_state) = state.0.clone() { + match message { + // TODO: handle all these "let _" + // See https://github.com/lambdaclass/ethrex/issues/3375 + Self::CastMsg::PeerMessage(message) => { + log_peer_debug( + &established_state.node, + &format!("Received peer message: {message}"), + ); + let _ = handle_peer_message(&mut established_state, message).await; + } + Self::CastMsg::BackendMessage(message) => { + log_peer_debug( + &established_state.node, + &format!("Received backend message: {message}"), + ); + let _ = handle_backend_message(&mut established_state, message).await; + } + Self::CastMsg::SendPing => { + let _ = send(&mut established_state, Message::Ping(PingMessage {})).await; + log_peer_debug(&established_state.node, "Ping sent"); + } + Self::CastMsg::SendNewPooledTxHashes => { + let _ = send_new_pooled_tx_hashes(&mut established_state).await; + } + Self::CastMsg::BroadcastMessage(id, msg) => { + log_peer_debug( + &established_state.node, + &format!("Received broadcasted message: {msg}"), + ); + let _ = handle_broadcast(&mut established_state, (id, msg)).await; + } + Self::CastMsg::BlockRangeUpdate => { + log_peer_debug(&established_state.node, "Block Range Update"); + let _ = handle_block_range_update(&mut established_state).await; + } + } + // Update the state + state.0 = InnerState::Established(established_state); + CastResponse::NoReply(state) + } else { + // Received a Cast message but connection is not ready. Log an error but keep the connection alive. + error!("Connection not yet established"); + CastResponse::NoReply(state) + } + } +} + +async fn initialize_connection( + handle: &RLPxConnectionHandle, + state: &mut Established, + mut stream: S, +) -> Result<(), RLPxError> +where + S: Unpin + Send + Stream> + 'static, +{ + post_handshake_checks(state.table.clone()).await?; + + exchange_hello_messages(state, &mut stream).await?; + + // Handshake OK: handle connection + // Create channels to communicate directly to the peer + let (peer_channels, sender) = PeerChannels::create(handle.clone()); + + // Updating the state to establish the backend channel + state.backend_channel = Some(sender); + + // NOTE: if the peer came from the discovery server it will already be inserted in the table + // but that might not always be the case, so we try to add it to the table + // Note: we don't ping the node we let the validation service do its job + { + let mut table_lock = state.table.lock().await; + table_lock.insert_node_forced(state.node.clone()); + table_lock.init_backend_communication( + state.node.node_id(), + peer_channels, + state.capabilities.clone(), + state.inbound, + ); + } + init_capabilities(state, &mut stream).await?; + log_peer_debug(&state.node, "Peer connection initialized."); + + // Send transactions transaction hashes from mempool at connection start + send_new_pooled_tx_hashes(state).await?; + + // Periodic broadcast check repeated events. + send_interval( + TX_BROADCAST_INTERVAL, + handle.clone(), + CastMessage::SendNewPooledTxHashes, + ); + + // Periodic Pings repeated events. + send_interval(PING_INTERVAL, handle.clone(), CastMessage::SendPing); + + // Periodic block range update. + send_interval( + BLOCK_RANGE_UPDATE_INTERVAL, + handle.clone(), + CastMessage::BlockRangeUpdate, + ); + + spawn_listener(handle.clone(), &state.node, stream); + + spawn_broadcast_listener(handle.clone(), state); + + Ok(()) +} + +async fn send_new_pooled_tx_hashes(state: &mut Established) -> Result<(), RLPxError> { + if SUPPORTED_ETH_CAPABILITIES + .iter() + .any(|cap| state.capabilities.contains(cap)) + { + let filter = + |tx: &Transaction| -> bool { !state.broadcasted_txs.contains(&tx.compute_hash()) }; + let txs: Vec = state + .blockchain + .mempool + .filter_transactions_with_filter_fn(&filter)? + .into_values() + .flatten() + .collect(); + if !txs.is_empty() { + let tx_count = txs.len(); + for tx in txs { + send( + state, + Message::NewPooledTransactionHashes(NewPooledTransactionHashes::new( + vec![(*tx).clone()], + &state.blockchain, + )?), + ) + .await?; + // Possible improvement: the mempool already knows the hash but the filter function does not return it + state.broadcasted_txs.insert((*tx).compute_hash()); + } + log_peer_debug( + &state.node, + &format!("Sent {tx_count} transactions to peer"), + ); + } + } + Ok(()) +} + +async fn send_block_range_update(state: &mut Established) -> Result<(), RLPxError> { + // BlockRangeUpdate was introduced in eth/69 + if let Some(eth) = &state.negotiated_eth_capability { + if eth.version >= 69 { + log_peer_debug(&state.node, "Sending BlockRangeUpdate"); + let update = BlockRangeUpdate::new(&state.storage).await?; + let lastet_block = update.lastest_block; + send(state, Message::BlockRangeUpdate(update)).await?; + state.last_block_range_update_block = lastet_block - (lastet_block % 32); + } + } + Ok(()) +} + +async fn should_send_block_range_update(state: &mut Established) -> Result { + let latest_block = state.storage.get_latest_block_number().await?; + if latest_block < state.last_block_range_update_block + || latest_block - state.last_block_range_update_block >= 32 + { + return Ok(true); + } + Ok(false) +} + +async fn init_capabilities(state: &mut Established, stream: &mut S) -> Result<(), RLPxError> +where + S: Unpin + Stream>, +{ + // Sending eth Status if peer supports it + if let Some(eth) = state.negotiated_eth_capability.clone() { + let status = StatusMessage::new(&state.storage, ð).await?; + log_peer_debug(&state.node, "Sending status"); + send(state, Message::Status(status)).await?; + // The next immediate message in the ETH protocol is the + // status, reference here: + // https://github.com/ethereum/devp2p/blob/master/caps/eth.md#status-0x00 + let msg = match receive(stream).await { + Some(msg) => msg?, + None => return Err(RLPxError::Disconnected()), + }; + match msg { + Message::Status(msg_data) => { + log_peer_debug(&state.node, "Received Status"); + backend::validate_status(msg_data, &state.storage, ð).await? + } + Message::Disconnect(disconnect) => { + return Err(RLPxError::HandshakeError(format!( + "Peer disconnected due to: {}", + disconnect.reason() + ))); + } + _ => { + return Err(RLPxError::HandshakeError( + "Expected a Status message".to_string(), + )); + } + } + } + Ok(()) +} + +async fn post_handshake_checks( + table: Arc>, +) -> Result<(), RLPxError> { + // Check if connected peers exceed the limit + let peer_count = { + let table_lock = table.lock().await; + table_lock.count_connected_peers() + }; + + if peer_count >= MAX_PEERS_TCP_CONNECTIONS { + return Err(RLPxError::DisconnectSent(DisconnectReason::TooManyPeers)); + } + + Ok(()) +} + +async fn send_disconnect_message(state: &mut Established, reason: Option) { + send(state, Message::Disconnect(DisconnectMessage { reason })) + .await + .unwrap_or_else(|_| { + log_peer_debug( + &state.node, + &format!("Could not send Disconnect message: ({reason:?})."), + ); + }); +} + +async fn connection_failed(state: &mut Established, error_text: &str, error: RLPxError) { + log_peer_debug(&state.node, &format!("{error_text}: ({error})")); + + // Send disconnect message only if error is different than RLPxError::DisconnectRequested + // because if it is a DisconnectRequested error it means that the peer requested the disconnection, not us. + if !matches!(error, RLPxError::DisconnectReceived(_)) { + send_disconnect_message(state, match_disconnect_reason(&error)).await; + } + + // Discard peer from kademlia table in some cases + match error { + // already connected, don't discard it + RLPxError::DisconnectReceived(DisconnectReason::AlreadyConnected) + | RLPxError::DisconnectSent(DisconnectReason::AlreadyConnected) => { + log_peer_debug(&state.node, "Peer already connected, don't replace it"); + } + _ => { + let remote_public_key = state.node.public_key; + log_peer_debug( + &state.node, + &format!("{error_text}: ({error}), discarding peer {remote_public_key}"), + ); + state.table.lock().await.replace_peer(state.node.node_id()); + } + } + + let _ = state.sink.lock().await.close().await; +} + +fn match_disconnect_reason(error: &RLPxError) -> Option { + match error { + RLPxError::DisconnectSent(reason) => Some(*reason), + RLPxError::DisconnectReceived(reason) => Some(*reason), + RLPxError::RLPDecodeError(_) => Some(DisconnectReason::NetworkError), + // TODO build a proper matching between error types and disconnection reasons + _ => None, + } +} + +async fn exchange_hello_messages( + state: &mut Established, + stream: &mut S, +) -> Result<(), RLPxError> +where + S: Unpin + Stream>, +{ + let supported_capabilities: Vec = [ + &SUPPORTED_ETH_CAPABILITIES[..], + &SUPPORTED_SNAP_CAPABILITIES[..], + &SUPPORTED_P2P_CAPABILITIES[..], + ] + .concat(); + let hello_msg = Message::Hello(p2p::HelloMessage::new( + supported_capabilities, + PublicKey::from(state.signer.verifying_key()), + state.client_version.clone(), + )); + + send(state, hello_msg).await?; + + // Receive Hello message + let msg = match receive(stream).await { + Some(msg) => msg?, + None => return Err(RLPxError::Disconnected()), + }; + + match msg { + Message::Hello(hello_message) => { + let mut negotiated_eth_version = 0; + let mut negotiated_snap_version = 0; + + log_peer_debug( + &state.node, + &format!( + "Hello message capabilities {:?}", + hello_message.capabilities + ), + ); + + // Check if we have any capability in common and store the highest version + for cap in &hello_message.capabilities { + match cap.protocol { + "eth" => { + if SUPPORTED_ETH_CAPABILITIES.contains(cap) + && cap.version > negotiated_eth_version + { + negotiated_eth_version = cap.version; + } + } + "snap" => { + if SUPPORTED_SNAP_CAPABILITIES.contains(cap) + && cap.version > negotiated_snap_version + { + negotiated_snap_version = cap.version; + } + } + _ => {} + } + } + + state.capabilities = hello_message.capabilities; + + if negotiated_eth_version == 0 { + return Err(RLPxError::NoMatchingCapabilities()); + } + debug!("Negotatied eth version: eth/{}", negotiated_eth_version); + state.negotiated_eth_capability = Some(Capability::eth(negotiated_eth_version)); + + if negotiated_snap_version != 0 { + debug!("Negotatied snap version: snap/{}", negotiated_snap_version); + state.negotiated_snap_capability = Some(Capability::snap(negotiated_snap_version)); + } + + state.node.version = Some(hello_message.client_id); + + Ok(()) + } + Message::Disconnect(disconnect) => Err(RLPxError::DisconnectReceived(disconnect.reason())), + _ => { + // Fail if it is not a hello message + Err(RLPxError::BadRequest("Expected Hello message".to_string())) + } + } +} + +async fn send(state: &mut Established, message: Message) -> Result<(), RLPxError> { + state.sink.lock().await.send(message).await +} + +/// Reads from the frame until a frame is available. +/// +/// Returns `None` when the stream buffer is 0. This could indicate that the client has disconnected, +/// but we cannot safely assume an EOF, as per the Tokio documentation. +/// +/// If the handshake has not been established, it is reasonable to terminate the connection. +/// +/// For an established connection, [`check_periodic_task`] will detect actual disconnections +/// while sending pings and you should not assume a disconnection. +/// +/// See [`Framed::new`] for more details. +async fn receive(stream: &mut S) -> Option> +where + S: Unpin + Stream>, +{ + stream.next().await +} + +// TODO replace this spawn, once it's implemented in spawned +// See https://github.com/lambdaclass/ethrex/issues/3387 and +// https://github.com/lambdaclass/spawned/issues/17 +fn spawn_listener(mut conn: RLPxConnectionHandle, node: &Node, mut stream: S) +where + S: Unpin + Send + Stream> + 'static, +{ + let node = node.clone(); + spawned_rt::tasks::spawn(async move { + loop { + match stream.next().await { + Some(Ok(message)) => { + let _ = conn.cast(CastMessage::PeerMessage(message)).await; + } + Some(Err(e)) => { + log_peer_debug(&node, &format!("Received RLPX Error in msg {e}")); + break; + } + // `None` does not neccessary means EOF, so we will keep the loop running + // (See Framed::new) + None => (), + } + } + }); +} + +// TODO Maybe provide a similar mechanism for this listener, or remove it when +// Broadcast is handled in a spawned GenServer +// See https://github.com/lambdaclass/ethrex/issues/3387 and +// https://github.com/lambdaclass/spawned/issues/17 and +// https://github.com/lambdaclass/ethrex/issues/3388 +fn spawn_broadcast_listener(mut handle: RLPxConnectionHandle, state: &mut Established) { + // Subscribe this connection to the broadcasting channel. + // TODO currently spawning a listener task that will suscribe to a broadcast channel and + // create RLPxConnection Broadcast messages to send the Genserver + // We have to improve this mechanism to avoid manual creation of channels and subscriptions + // (That is, we should have a spawned-based broadcaster or maybe the backend should handle the + // transactions propagation) + if state.negotiated_eth_capability.is_some() { + let mut receiver = state.connection_broadcast_send.subscribe(); + spawned_rt::tasks::spawn(async move { + loop { + if let Ok((id, msg)) = receiver.recv().await { + let _ = handle.cast(CastMessage::BroadcastMessage(id, msg)).await; + }; + } + }); + }; +} + +async fn handle_peer_message(state: &mut Established, message: Message) -> Result<(), RLPxError> { + let peer_supports_eth = state.negotiated_eth_capability.is_some(); + match message { + Message::Disconnect(msg_data) => { + log_peer_debug( + &state.node, + &format!("Received Disconnect: {}", msg_data.reason()), + ); + // TODO handle the disconnection request + return Err(RLPxError::DisconnectReceived(msg_data.reason())); + } + Message::Ping(_) => { + log_peer_debug(&state.node, "Sending pong message"); + send(state, Message::Pong(PongMessage {})).await?; + } + Message::Pong(_) => { + // We ignore received Pong messages + } + Message::Status(msg_data) => { + if let Some(eth) = &state.negotiated_eth_capability { + backend::validate_status(msg_data, &state.storage, eth).await? + }; + } + Message::GetAccountRange(req) => { + let response = process_account_range_request(req, state.storage.clone())?; + send(state, Message::AccountRange(response)).await? + } + Message::Transactions(txs) if peer_supports_eth => { + if state.blockchain.is_synced() { + let mut valid_txs = vec![]; + for tx in &txs.transactions { + if let Err(e) = state.blockchain.add_transaction_to_pool(tx.clone()).await { + log_peer_warn(&state.node, &format!("Error adding transaction: {e}")); + continue; + } + valid_txs.push(tx.clone()); + } + if !valid_txs.is_empty() { + broadcast_message(state, Message::Transactions(Transactions::new(valid_txs)))?; + } + } + } + Message::GetBlockHeaders(msg_data) if peer_supports_eth => { + let response = BlockHeaders { + id: msg_data.id, + block_headers: msg_data.fetch_headers(&state.storage).await, + }; + send(state, Message::BlockHeaders(response)).await?; + } + Message::GetBlockBodies(msg_data) if peer_supports_eth => { + let response = BlockBodies { + id: msg_data.id, + block_bodies: msg_data.fetch_blocks(&state.storage).await, + }; + send(state, Message::BlockBodies(response)).await?; + } + Message::GetReceipts(GetReceipts { id, block_hashes }) if peer_supports_eth => { + if let Some(eth) = &state.negotiated_eth_capability { + let mut receipts = Vec::new(); + for hash in block_hashes.iter() { + receipts.push(state.storage.get_receipts_for_block(hash)?); + } + let response = Receipts::new(id, receipts, eth)?; + send(state, Message::Receipts(response)).await?; + } + } + Message::BlockRangeUpdate(update) => { + if update.earliest_block > update.lastest_block { + return Err(RLPxError::InvalidBlockRange); + } + //TODO implement the logic + log_peer_debug( + &state.node, + &format!( + "Range block update: {} to {}", + update.earliest_block, update.lastest_block + ), + ); + } + Message::NewPooledTransactionHashes(new_pooled_transaction_hashes) if peer_supports_eth => { + let hashes = + new_pooled_transaction_hashes.get_transactions_to_request(&state.blockchain)?; + + let request = GetPooledTransactions::new(random(), hashes); + send(state, Message::GetPooledTransactions(request)).await?; + } + Message::GetPooledTransactions(msg) => { + let response = msg.handle(&state.blockchain)?; + send(state, Message::PooledTransactions(response)).await?; + } + Message::PooledTransactions(msg) if peer_supports_eth => { + if state.blockchain.is_synced() { + if let Some(requested) = state.requested_pooled_txs.get(&msg.id) { + if let Err(error) = msg.validate_requested(requested).await { + log_peer_warn( + &state.node, + &format!("disconnected from peer. Reason: {error}"), + ); + send_disconnect_message(state, Some(DisconnectReason::SubprotocolError)) + .await; + return Err(RLPxError::DisconnectSent( + DisconnectReason::SubprotocolError, + )); + } else { + state.requested_pooled_txs.remove(&msg.id); + } + } + msg.handle(&state.node, &state.blockchain).await?; + } + } + Message::GetStorageRanges(req) => { + let response = process_storage_ranges_request(req, state.storage.clone())?; + send(state, Message::StorageRanges(response)).await? + } + Message::GetByteCodes(req) => { + let response = process_byte_codes_request(req, state.storage.clone())?; + send(state, Message::ByteCodes(response)).await? + } + Message::GetTrieNodes(req) => { + let response = process_trie_nodes_request(req, state.storage.clone())?; + send(state, Message::TrieNodes(response)).await? + } + // Send response messages to the backend + message @ Message::AccountRange(_) + | message @ Message::StorageRanges(_) + | message @ Message::ByteCodes(_) + | message @ Message::TrieNodes(_) + | message @ Message::BlockBodies(_) + | message @ Message::BlockHeaders(_) + | message @ Message::Receipts(_) => { + state + .backend_channel + .as_mut() + // TODO: this unwrap() is temporary, until we fix the backend process to use spawned + .expect("Backend channel is not available") + .send(message) + .await? + } + // TODO: Add new message types and handlers as they are implemented + message => return Err(RLPxError::MessageNotHandled(format!("{message}"))), + }; + Ok(()) +} + +async fn handle_backend_message( + state: &mut Established, + message: Message, +) -> Result<(), RLPxError> { + log_peer_debug(&state.node, &format!("Sending message {message}")); + send(state, message).await?; + Ok(()) +} + +async fn handle_broadcast( + state: &mut Established, + (id, broadcasted_msg): (task::Id, Arc), +) -> Result<(), RLPxError> { + if id != tokio::task::id() { + match broadcasted_msg.as_ref() { + Message::Transactions(txs) => { + // TODO(#1131): Avoid cloning this vector. + let cloned = txs.transactions.clone(); + let new_msg = Message::Transactions(Transactions { + transactions: cloned, + }); + send(state, new_msg).await?; + } + msg => { + let error_message = format!("Non-supported message broadcasted: {msg}"); + log_peer_error(&state.node, &error_message); + return Err(RLPxError::BroadcastError(error_message)); + } + } + } + Ok(()) +} + +async fn handle_block_range_update(state: &mut Established) -> Result<(), RLPxError> { + if should_send_block_range_update(state).await? { + send_block_range_update(state).await + } else { + Ok(()) + } +} + +fn broadcast_message(state: &Established, msg: Message) -> Result<(), RLPxError> { + match msg { + txs_msg @ Message::Transactions(_) => { + let txs = Arc::new(txs_msg); + let task_id = tokio::task::id(); + let Ok(_) = state.connection_broadcast_send.send((task_id, txs)) else { + let error_message = "Could not broadcast received transactions"; + log_peer_error(&state.node, error_message); + return Err(RLPxError::BroadcastError(error_message.to_owned())); + }; + Ok(()) + } + msg => { + let error_message = format!("Broadcasting for msg: {msg} is not supported"); + log_peer_error(&state.node, &error_message); + Err(RLPxError::BroadcastError(error_message)) + } + } +} diff --git a/crates/networking/p2p/rlpx/error.rs b/crates/networking/p2p/rlpx/error.rs index 7a6b239709..0bf1ad7a16 100644 --- a/crates/networking/p2p/rlpx/error.rs +++ b/crates/networking/p2p/rlpx/error.rs @@ -18,9 +18,11 @@ pub enum CryptographyError { // TODO improve errors #[derive(Debug, Error)] -pub(crate) enum RLPxError { +pub enum RLPxError { #[error("{0}")] HandshakeError(String), + #[error("Invalid connection state: {0}")] + StateError(String), #[error("No matching capabilities")] NoMatchingCapabilities(), #[error("Peer disconnected")] diff --git a/crates/networking/p2p/rlpx/eth/eth68/receipts.rs b/crates/networking/p2p/rlpx/eth/eth68/receipts.rs index 100623b552..571ed3b14f 100644 --- a/crates/networking/p2p/rlpx/eth/eth68/receipts.rs +++ b/crates/networking/p2p/rlpx/eth/eth68/receipts.rs @@ -9,7 +9,7 @@ use ethrex_rlp::{ structs::{Decoder, Encoder}, }; -#[derive(Debug)] +#[derive(Debug, Clone)] pub(crate) struct Receipts68 { // id is a u64 chosen by the requesting peer, the responding peer must mirror the value for the response // https://github.com/ethereum/devp2p/blob/master/caps/eth.md#protocol-messages diff --git a/crates/networking/p2p/rlpx/eth/eth68/status.rs b/crates/networking/p2p/rlpx/eth/eth68/status.rs index 427684af01..e88dacae13 100644 --- a/crates/networking/p2p/rlpx/eth/eth68/status.rs +++ b/crates/networking/p2p/rlpx/eth/eth68/status.rs @@ -12,7 +12,7 @@ use ethrex_rlp::{ structs::{Decoder, Encoder}, }; -#[derive(Debug)] +#[derive(Debug, Clone)] pub(crate) struct StatusMessage68 { pub(crate) eth_version: u8, pub(crate) network_id: u64, diff --git a/crates/networking/p2p/rlpx/eth/eth69/receipts.rs b/crates/networking/p2p/rlpx/eth/eth69/receipts.rs index 3d46610d08..f013640785 100644 --- a/crates/networking/p2p/rlpx/eth/eth69/receipts.rs +++ b/crates/networking/p2p/rlpx/eth/eth69/receipts.rs @@ -9,7 +9,7 @@ use ethrex_rlp::{ structs::{Decoder, Encoder}, }; -#[derive(Debug)] +#[derive(Debug, Clone)] pub(crate) struct Receipts69 { // id is a u64 chosen by the requesting peer, the responding peer must mirror the value for the response // https://github.com/ethereum/devp2p/blob/master/caps/eth.md#protocol-messages diff --git a/crates/networking/p2p/rlpx/eth/eth69/status.rs b/crates/networking/p2p/rlpx/eth/eth69/status.rs index f828bc940b..9548974f6d 100644 --- a/crates/networking/p2p/rlpx/eth/eth69/status.rs +++ b/crates/networking/p2p/rlpx/eth/eth69/status.rs @@ -9,7 +9,7 @@ use ethrex_rlp::{ structs::{Decoder, Encoder}, }; -#[derive(Debug)] +#[derive(Debug, Clone)] pub(crate) struct StatusMessage69 { pub(crate) eth_version: u8, pub(crate) network_id: u64, diff --git a/crates/networking/p2p/rlpx/eth/receipts.rs b/crates/networking/p2p/rlpx/eth/receipts.rs index e2907d00a9..1ce76f052c 100644 --- a/crates/networking/p2p/rlpx/eth/receipts.rs +++ b/crates/networking/p2p/rlpx/eth/receipts.rs @@ -17,7 +17,7 @@ use ethrex_rlp::{ }; // https://github.com/ethereum/devp2p/blob/master/caps/eth.md#getreceipts-0x0f -#[derive(Debug)] +#[derive(Debug, Clone)] pub(crate) struct GetReceipts { // id is a u64 chosen by the requesting peer, the responding peer must mirror the value for the response // https://github.com/ethereum/devp2p/blob/master/caps/eth.md#protocol-messages @@ -56,7 +56,7 @@ impl RLPxMessage for GetReceipts { } // https://github.com/ethereum/devp2p/blob/master/caps/eth.md#receipts-0x10 -#[derive(Debug)] +#[derive(Debug, Clone)] pub(crate) enum Receipts { Receipts68(Receipts68), Receipts69(Receipts69), diff --git a/crates/networking/p2p/rlpx/eth/status.rs b/crates/networking/p2p/rlpx/eth/status.rs index 4d5f1126c5..c6660bb9ec 100644 --- a/crates/networking/p2p/rlpx/eth/status.rs +++ b/crates/networking/p2p/rlpx/eth/status.rs @@ -10,7 +10,7 @@ use ethrex_rlp::error::{RLPDecodeError, RLPEncodeError}; use ethrex_rlp::structs::Decoder; use ethrex_storage::Store; -#[derive(Debug)] +#[derive(Debug, Clone)] pub enum StatusMessage { StatusMessage68(StatusMessage68), StatusMessage69(StatusMessage69), diff --git a/crates/networking/p2p/rlpx/eth/transactions.rs b/crates/networking/p2p/rlpx/eth/transactions.rs index 04b41ddcbd..f103b4df46 100644 --- a/crates/networking/p2p/rlpx/eth/transactions.rs +++ b/crates/networking/p2p/rlpx/eth/transactions.rs @@ -64,7 +64,7 @@ impl RLPxMessage for Transactions { // https://github.com/ethereum/devp2p/blob/master/caps/eth.md#newpooledtransactionhashes-0x08 // Broadcast message -#[derive(Debug, Eq, PartialEq)] +#[derive(Debug, Clone, Eq, PartialEq)] pub(crate) struct NewPooledTransactionHashes { transaction_types: Bytes, transaction_sizes: Vec, @@ -160,7 +160,7 @@ impl RLPxMessage for NewPooledTransactionHashes { } // https://github.com/ethereum/devp2p/blob/master/caps/eth.md#getpooledtransactions-0x09 -#[derive(Debug)] +#[derive(Debug, Clone)] pub(crate) struct GetPooledTransactions { // id is a u64 chosen by the requesting peer, the responding peer must mirror the value for the response // https://github.com/ethereum/devp2p/blob/master/caps/eth.md#protocol-messages @@ -221,7 +221,7 @@ impl RLPxMessage for GetPooledTransactions { } // https://github.com/ethereum/devp2p/blob/master/caps/eth.md#pooledtransactions-0x0a -#[derive(Debug)] +#[derive(Debug, Clone)] pub(crate) struct PooledTransactions { // id is a u64 chosen by the requesting peer, the responding peer must mirror the value for the response // https://github.com/ethereum/devp2p/blob/master/caps/eth.md#protocol-messages diff --git a/crates/networking/p2p/rlpx/eth/update.rs b/crates/networking/p2p/rlpx/eth/update.rs index 91b1b9dce1..a438067743 100644 --- a/crates/networking/p2p/rlpx/eth/update.rs +++ b/crates/networking/p2p/rlpx/eth/update.rs @@ -11,7 +11,7 @@ use ethrex_rlp::{ }; use ethrex_storage::Store; -#[derive(Debug)] +#[derive(Debug, Clone)] pub(crate) struct BlockRangeUpdate { pub(crate) earliest_block: u64, pub(crate) lastest_block: u64, diff --git a/crates/networking/p2p/rlpx/message.rs b/crates/networking/p2p/rlpx/message.rs index b14fd79bb8..0b2814bf20 100644 --- a/crates/networking/p2p/rlpx/message.rs +++ b/crates/networking/p2p/rlpx/message.rs @@ -27,7 +27,7 @@ pub trait RLPxMessage: Sized { fn decode(msg_data: &[u8]) -> Result; } -#[derive(Debug)] +#[derive(Debug, Clone)] pub(crate) enum Message { Hello(HelloMessage), Disconnect(DisconnectMessage), diff --git a/crates/networking/p2p/rlpx/p2p.rs b/crates/networking/p2p/rlpx/p2p.rs index 2a3fb7d6e7..f7b754bb80 100644 --- a/crates/networking/p2p/rlpx/p2p.rs +++ b/crates/networking/p2p/rlpx/p2p.rs @@ -78,7 +78,7 @@ impl Serialize for Capability { } } -#[derive(Debug)] +#[derive(Debug, Clone)] pub(crate) struct HelloMessage { pub(crate) capabilities: Vec, pub(crate) node_id: PublicKey, @@ -211,7 +211,7 @@ impl From for u8 { val as u8 } } -#[derive(Debug)] +#[derive(Debug, Clone)] pub(crate) struct DisconnectMessage { pub(crate) reason: Option, } @@ -269,7 +269,7 @@ impl RLPxMessage for DisconnectMessage { } } -#[derive(Debug)] +#[derive(Debug, Clone, Copy)] pub(crate) struct PingMessage {} impl RLPxMessage for PingMessage { @@ -295,7 +295,7 @@ impl RLPxMessage for PingMessage { } } -#[derive(Debug)] +#[derive(Debug, Clone, Copy)] pub(crate) struct PongMessage {} impl RLPxMessage for PongMessage { diff --git a/crates/networking/p2p/rlpx/snap.rs b/crates/networking/p2p/rlpx/snap.rs index fa6877fedd..23ff0ca997 100644 --- a/crates/networking/p2p/rlpx/snap.rs +++ b/crates/networking/p2p/rlpx/snap.rs @@ -17,7 +17,7 @@ use ethrex_rlp::{ // Snap Capability Messages -#[derive(Debug)] +#[derive(Debug, Clone)] pub(crate) struct GetAccountRange { // id is a u64 chosen by the requesting peer, the responding peer must mirror the value for the response pub id: u64, @@ -27,7 +27,7 @@ pub(crate) struct GetAccountRange { pub response_bytes: u64, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub(crate) struct AccountRange { // id is a u64 chosen by the requesting peer, the responding peer must mirror the value for the response pub id: u64, @@ -35,7 +35,7 @@ pub(crate) struct AccountRange { pub proof: Vec, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub(crate) struct GetStorageRanges { pub id: u64, pub root_hash: H256, @@ -45,27 +45,27 @@ pub(crate) struct GetStorageRanges { pub response_bytes: u64, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub(crate) struct StorageRanges { pub id: u64, pub slots: Vec>, pub proof: Vec, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub(crate) struct GetByteCodes { pub id: u64, pub hashes: Vec, pub bytes: u64, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub(crate) struct ByteCodes { pub id: u64, pub codes: Vec, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub(crate) struct GetTrieNodes { pub id: u64, pub root_hash: H256, @@ -75,7 +75,7 @@ pub(crate) struct GetTrieNodes { pub bytes: u64, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub(crate) struct TrieNodes { pub id: u64, pub nodes: Vec, @@ -339,13 +339,13 @@ impl RLPxMessage for TrieNodes { // Intermediate structures -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct AccountRangeUnit { pub hash: H256, pub account: AccountStateSlim, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct AccountStateSlim { pub nonce: u64, pub balance: U256, @@ -353,7 +353,7 @@ pub struct AccountStateSlim { pub code_hash: Bytes, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct StorageSlot { pub hash: H256, pub data: U256,