diff --git a/Cargo.lock b/Cargo.lock index 69204ccaecd..7501ac17801 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -128,9 +128,9 @@ checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "alloy-chains" -version = "0.2.23" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35d744058a9daa51a8cf22a3009607498fcf82d3cf4c5444dd8056cdf651f471" +checksum = "4bc32535569185cbcb6ad5fa64d989a47bccb9a08e27284b1f2a3ccf16e6d010" dependencies = [ "alloy-primitives", "num_enum", @@ -152,7 +152,7 @@ dependencies = [ "auto_impl", "borsh", "c-kzg", - "derive_more 2.1.0", + "derive_more 2.0.1", "either", "k256", "once_cell", @@ -180,9 +180,9 @@ dependencies = [ [[package]] name = "alloy-dyn-abi" -version = "1.5.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3b1db3281bcaf03cfadb9d125fac55603526cc1d0577da555dc6184f5188f6f" +checksum = "3fdff496dd4e98a81f4861e66f7eaf5f2488971848bb42d9c892f871730245c8" dependencies = [ "alloy-json-abi", "alloy-primitives", @@ -245,7 +245,7 @@ dependencies = [ "auto_impl", "borsh", "c-kzg", - "derive_more 2.1.0", + "derive_more 2.0.1", "either", "serde", "serde_with", @@ -255,9 +255,9 @@ dependencies = [ [[package]] name = "alloy-json-abi" -version = "1.5.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bfca3dbbcb7498f0f60e67aff2ad6aff57032e22eb2fd03189854be11a22c03" +checksum = "5513d5e6bd1cba6bdcf5373470f559f320c05c8c59493b6e98912fbe6733943f" dependencies = [ "alloy-primitives", "alloy-sol-type-parser", @@ -273,7 +273,7 @@ checksum = "f72cf87cda808e593381fb9f005ffa4d2475552b7a6c5ac33d087bf77d82abd0" dependencies = [ "alloy-primitives", "alloy-sol-types", - "http 1.4.0", + "http 1.3.1", "serde", "serde_json", "thiserror 2.0.17", @@ -299,7 +299,7 @@ dependencies = [ "alloy-sol-types", "async-trait", "auto_impl", - "derive_more 2.1.0", + "derive_more 2.0.1", "futures-utils-wasm", "serde", "serde_json", @@ -321,20 +321,20 @@ dependencies = [ [[package]] name = "alloy-primitives" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c850e6ccbd34b8a463a1e934ffc8fc00e1efc5e5489f2ad82d7797949f3bd4e" +checksum = "7db950a29746be9e2f2c6288c8bd7a6202a81f999ce109a2933d2379970ec0fa" dependencies = [ "alloy-rlp", "arbitrary", "bytes", "cfg-if", "const-hex", - "derive_more 2.1.0", + "derive_more 2.0.1", "foldhash 0.2.0", "getrandom 0.3.4", - "hashbrown 0.16.1", - "indexmap 2.12.1", + "hashbrown 0.16.0", + "indexmap 2.12.0", "itoa", "k256", "keccak-asm", @@ -408,7 +408,7 @@ checksum = "64b728d511962dda67c1bc7ea7c03736ec275ed2cf4c35d9585298ac9ccf3b73" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.110", ] [[package]] @@ -510,41 +510,41 @@ dependencies = [ [[package]] name = "alloy-sol-macro" -version = "1.5.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2218e3aeb3ee665d117fdf188db0d5acfdc3f7b7502c827421cb78f26a2aec0" +checksum = "f3ce480400051b5217f19d6e9a82d9010cdde20f1ae9c00d53591e4a1afbb312" dependencies = [ "alloy-sol-macro-expander", "alloy-sol-macro-input", "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.110", ] [[package]] name = "alloy-sol-macro-expander" -version = "1.5.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b231cb8cc48e66dd1c6e11a1402f3ac86c3667cbc13a6969a0ac030ba7bb8c88" +checksum = "6d792e205ed3b72f795a8044c52877d2e6b6e9b1d13f431478121d8d4eaa9028" dependencies = [ "alloy-sol-macro-input", "const-hex", "heck", - "indexmap 2.12.1", + "indexmap 2.12.0", "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.110", "syn-solidity", "tiny-keccak", ] [[package]] name = "alloy-sol-macro-input" -version = "1.5.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49a522d79929c1bf0152b07567a38f7eaed3ab149e53e7528afa78ff11994668" +checksum = "0bd1247a8f90b465ef3f1207627547ec16940c35597875cdc09c49d58b19693c" dependencies = [ "const-hex", "dunce", @@ -552,15 +552,15 @@ dependencies = [ "macro-string", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.110", "syn-solidity", ] [[package]] name = "alloy-sol-type-parser" -version = "1.5.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0475c459859c8d9428af6ff3736614655a57efda8cc435a3b8b4796fa5ac1dd0" +checksum = "954d1b2533b9b2c7959652df3076954ecb1122a28cc740aa84e7b0a49f6ac0a9" dependencies = [ "serde", "winnow", @@ -568,9 +568,9 @@ dependencies = [ [[package]] name = "alloy-sol-types" -version = "1.5.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35287d9d821d5f26011bcd8d9101340898f761c9933cf50fca689bb7ed62fdeb" +checksum = "70319350969a3af119da6fb3e9bddb1bce66c9ea933600cb297c8b1850ad2a3c" dependencies = [ "alloy-json-abi", "alloy-primitives", @@ -587,7 +587,7 @@ dependencies = [ "alloy-json-rpc", "auto_impl", "base64 0.22.1", - "derive_more 2.1.0", + "derive_more 2.0.1", "futures", "futures-utils-wasm", "parking_lot", @@ -625,7 +625,7 @@ dependencies = [ "alloy-primitives", "alloy-rlp", "arrayvec", - "derive_more 2.1.0", + "derive_more 2.0.1", "nybbles", "serde", "smallvec", @@ -641,7 +641,7 @@ dependencies = [ "darling 0.21.3", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.110", ] [[package]] @@ -695,7 +695,7 @@ version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] @@ -706,7 +706,7 @@ checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" dependencies = [ "anstyle", "once_cell_polyfill", - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] @@ -824,7 +824,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62945a2f7e6de02a31fe400aa489f0e0f5b2502e69f95f853adb82a96c7a6b60" dependencies = [ "quote", - "syn 2.0.111", + "syn 2.0.110", ] [[package]] @@ -862,7 +862,7 @@ dependencies = [ "num-traits", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.110", ] [[package]] @@ -973,7 +973,7 @@ checksum = "3109e49b1e4909e9db6515a30c633684d68cdeaa252f215214cb4fa1a5bfee2c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.110", "synstructure", ] @@ -985,7 +985,7 @@ checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.110", ] [[package]] @@ -1064,7 +1064,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.110", ] [[package]] @@ -1075,7 +1075,7 @@ checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.110", ] [[package]] @@ -1104,7 +1104,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "16e2cdb6d5ed835199484bb92bb8b3edd526effe995c61732580439c1a67e2e9" dependencies = [ "base64 0.22.1", - "http 1.4.0", + "http 1.3.1", "log", "url", ] @@ -1117,7 +1117,7 @@ checksum = "ffdcb70bdbc4d478427380519163274ac86e52916e10f0a8889adf0f96d3fee7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.110", ] [[package]] @@ -1136,7 +1136,7 @@ dependencies = [ "axum-core", "bytes", "futures-util", - "http 1.4.0", + "http 1.3.1", "http-body 1.0.1", "http-body-util", "itoa", @@ -1162,7 +1162,7 @@ dependencies = [ "async-trait", "bytes", "futures-util", - "http 1.4.0", + "http 1.3.1", "http-body 1.0.1", "http-body-util", "mime", @@ -1215,9 +1215,9 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "base64ct" -version = "1.8.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e050f626429857a27ddccb31e0aca21356bfa709c04041aefddac081a8f068a" +checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba" [[package]] name = "beacon_chain" @@ -1232,8 +1232,8 @@ dependencies = [ "eth2_network_config", "ethereum_hashing", "ethereum_serde_utils", - "ethereum_ssz", - "ethereum_ssz_derive", + "ethereum_ssz 0.10.0", + "ethereum_ssz_derive 0.10.0", "execution_layer", "fixed_bytes", "fork_choice", @@ -1259,6 +1259,7 @@ dependencies = [ "proto_array", "rand 0.9.2", "rayon", + "reth-era", "safe_arith", "sensitive_url", "serde", @@ -1385,7 +1386,7 @@ dependencies = [ "regex", "rustc-hash 1.1.0", "shlex", - "syn 2.0.111", + "syn 2.0.110", ] [[package]] @@ -1397,7 +1398,7 @@ dependencies = [ "bitflags 2.10.0", "cexpr", "clang-sys", - "itertools 0.13.0", + "itertools 0.12.1", "log", "prettyplease", "proc-macro2", @@ -1405,7 +1406,7 @@ dependencies = [ "regex", "rustc-hash 2.1.1", "shlex", - "syn 2.0.111", + "syn 2.0.110", ] [[package]] @@ -1425,15 +1426,15 @@ checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" [[package]] name = "bitcoin-io" -version = "0.1.4" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dee39a0ee5b4095224a0cfc6bf4cc1baf0f9624b96b367e53b66d974e51d953" +checksum = "0b47c4ab7a93edb0c7198c5535ed9b52b63095f4e9b45279c6736cec4b856baf" [[package]] name = "bitcoin_hashes" -version = "0.14.1" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26ec84b80c482df901772e931a9a681e26a1b9ee2302edeff23cb30328745c8b" +checksum = "bb18c03d0db0247e147a21a6faafd5a7eb851c743db062de72018b6b7e8e4d16" dependencies = [ "bitcoin-io", "hex-conservative", @@ -1508,7 +1509,7 @@ dependencies = [ "blst", "ethereum_hashing", "ethereum_serde_utils", - "ethereum_ssz", + "ethereum_ssz 0.10.0", "fixed_bytes", "hex", "rand 0.9.2", @@ -1555,7 +1556,7 @@ dependencies = [ "clap", "clap_utils", "eth2_network_config", - "ethereum_ssz", + "ethereum_ssz 0.10.0", "hex", "lighthouse_network", "log", @@ -1570,9 +1571,9 @@ dependencies = [ [[package]] name = "borsh" -version = "1.6.0" +version = "1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1da5ab77c1437701eeff7c88d968729e7766172279eab0676857b3d63af7a6f" +checksum = "ad8646f98db542e39fc66e68a20b2144f6a732636df7c2354e74645faaa433ce" dependencies = [ "borsh-derive", "cfg_aliases", @@ -1580,15 +1581,15 @@ dependencies = [ [[package]] name = "borsh-derive" -version = "1.6.0" +version = "1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0686c856aa6aac0c4498f936d7d6a02df690f614c03e4d906d1018062b5c5e2c" +checksum = "fdd1d3c0c2f5833f22386f252fe8ed005c7f59fdcddeef025c01b4c3b9fd9ac3" dependencies = [ "once_cell", "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.110", ] [[package]] @@ -1613,7 +1614,7 @@ dependencies = [ "bls", "context_deserialize", "eth2", - "ethereum_ssz", + "ethereum_ssz 0.10.0", "lighthouse_version", "mockito", "reqwest", @@ -1625,9 +1626,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.19.1" +version = "3.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" [[package]] name = "byte-slice-cast" @@ -1667,9 +1668,9 @@ dependencies = [ [[package]] name = "camino" -version = "1.2.2" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e629a66d692cb9ff1a1c664e41771b3dcaf961985a9774c0eb0bd1b51cf60a48" +checksum = "276a59bf2b2c967788139340c9f0c5b12d7fd6630315c15c217e559de85d2609" dependencies = [ "serde_core", ] @@ -1714,9 +1715,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.49" +version = "1.2.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90583009037521a116abf44494efecd645ba48b6622457080f080b85544e2215" +checksum = "b97463e1064cb1b1c1384ad0a0b9c8abd0988e2a91f52606c80ef14aadb63e36" dependencies = [ "find-msvc-tools", "jobserver", @@ -1851,7 +1852,7 @@ dependencies = [ "anstream", "anstyle", "clap_lex", - "strsim", + "strsim 0.11.1", "terminal_size", ] @@ -1864,7 +1865,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.110", ] [[package]] @@ -1881,7 +1882,7 @@ dependencies = [ "clap", "dirs", "eth2_network_config", - "ethereum_ssz", + "ethereum_ssz 0.10.0", "hex", "serde", "serde_json", @@ -1900,7 +1901,7 @@ dependencies = [ "environment", "eth2", "eth2_config", - "ethereum_ssz", + "ethereum_ssz 0.10.0", "execution_layer", "futures", "genesis", @@ -1934,9 +1935,9 @@ dependencies = [ [[package]] name = "cmake" -version = "0.1.57" +version = "0.1.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75443c44cd6b379beb8c5b45d85d0773baf31cce901fe7bb252f4eff3008ef7d" +checksum = "e7caa3f9de89ddbe2c607f4101924c5abec803763ae9534e4f4d7d8f84aa81f0" dependencies = [ "cc", ] @@ -1970,9 +1971,9 @@ dependencies = [ [[package]] name = "compare_fields" -version = "0.1.1" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f45d0b4d61b582303179fb7a1a142bc9d647b7583db3b0d5f25a21d286fab9" +checksum = "05162add7c8618791829528194a271dca93f69194d35b19db1ca7fbfb8275278" dependencies = [ "compare_fields_derive", "itertools 0.14.0", @@ -1980,12 +1981,12 @@ dependencies = [ [[package]] name = "compare_fields_derive" -version = "0.1.1" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92ff1dbbda10d495b2c92749c002b2025e0be98f42d1741ecc9ff820d2f04dce" +checksum = "5f5ee468b2e568b668e2a686112935e7bbe9a81bf4fa6b9f6fc3410ea45fb7ce" dependencies = [ "quote", - "syn 2.0.111", + "syn 1.0.109", ] [[package]] @@ -2082,9 +2083,9 @@ dependencies = [ [[package]] name = "context_deserialize" -version = "0.2.1" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c523eea4af094b5970c321f4604abc42c5549d3cbae332e98325403fbbdbf70" +checksum = "5c5f9ea0a0ae2de4943f5ca71590b6dbd0b952475f0a0cafb30a470cec78c8b9" dependencies = [ "context_deserialize_derive", "serde", @@ -2092,12 +2093,12 @@ dependencies = [ [[package]] name = "context_deserialize_derive" -version = "0.2.1" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b7bf98c48ffa511b14bb3c76202c24a8742cea1efa9570391c5d41373419a09" +checksum = "5c57b2db1e4e3ed804dcc49894a144b68fe6c754b8f545eb1dda7ad3c7dbe7e6" dependencies = [ "quote", - "syn 2.0.111", + "syn 1.0.109", ] [[package]] @@ -2106,15 +2107,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" -[[package]] -name = "convert_case" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "633458d4ef8c78b72454de2d54fd6ab2e60f9e02be22f3c6104cdc8a4e0fceb9" -dependencies = [ - "unicode-segmentation", -] - [[package]] name = "core-foundation" version = "0.9.4" @@ -2161,9 +2153,9 @@ dependencies = [ [[package]] name = "crc" -version = "3.4.0" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eb8a2a1cd12ab0d987a5d5e825195d372001a4094a0376319d5a0ad71c1ba0d" +checksum = "9710d3b3739c2e349eb44fe848ad0b7c8cb1e42bd87ee49371df2f7acaf3e675" dependencies = [ "crc-catalog", ] @@ -2331,7 +2323,27 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.110", +] + +[[package]] +name = "darling" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a01d95850c592940db9b8194bc39f4bc0e89dee5c4265e4b1807c34a9aba453c" +dependencies = [ + "darling_core 0.13.4", + "darling_macro 0.13.4", +] + +[[package]] +name = "darling" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" +dependencies = [ + "darling_core 0.20.11", + "darling_macro 0.20.11", ] [[package]] @@ -2345,63 +2357,79 @@ dependencies = [ ] [[package]] -name = "darling" -version = "0.23.0" +name = "darling_core" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25ae13da2f202d56bd7f91c25fba009e7717a1e4a1cc98a76d844b65ae912e9d" +checksum = "859d65a907b6852c9361e3185c862aae7fafd2887876799fa55f5f99dc40d610" dependencies = [ - "darling_core 0.23.0", - "darling_macro 0.23.0", + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim 0.10.0", + "syn 1.0.109", ] [[package]] name = "darling_core" -version = "0.21.3" +version = "0.20.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1247195ecd7e3c85f83c8d2a366e4210d588e802133e1e355180a9870b517ea4" +checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", - "serde", - "strsim", - "syn 2.0.111", + "strsim 0.11.1", + "syn 2.0.110", ] [[package]] name = "darling_core" -version = "0.23.0" +version = "0.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9865a50f7c335f53564bb694ef660825eb8610e0a53d3e11bf1b0d3df31e03b0" +checksum = "1247195ecd7e3c85f83c8d2a366e4210d588e802133e1e355180a9870b517ea4" dependencies = [ + "fnv", "ident_case", "proc-macro2", "quote", - "strsim", - "syn 2.0.111", + "serde", + "strsim 0.11.1", + "syn 2.0.110", ] [[package]] name = "darling_macro" -version = "0.21.3" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" +checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835" dependencies = [ - "darling_core 0.21.3", + "darling_core 0.13.4", "quote", - "syn 2.0.111", + "syn 1.0.109", ] [[package]] name = "darling_macro" -version = "0.23.0" +version = "0.20.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d" +checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" dependencies = [ - "darling_core 0.23.0", + "darling_core 0.20.11", "quote", - "syn 2.0.111", + "syn 2.0.110", +] + +[[package]] +name = "darling_macro" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" +dependencies = [ + "darling_core 0.21.3", + "quote", + "syn 2.0.110", ] [[package]] @@ -2461,7 +2489,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d162beedaa69905488a8da94f5ac3edb4dd4788b732fadb7bd120b2625c1976" dependencies = [ "data-encoding", - "syn 2.0.111", + "syn 2.0.110", ] [[package]] @@ -2506,7 +2534,7 @@ dependencies = [ "alloy-json-abi", "alloy-primitives", "bls", - "ethereum_ssz", + "ethereum_ssz 0.10.0", "hex", "reqwest", "serde_json", @@ -2550,7 +2578,7 @@ checksum = "8034092389675178f570469e6c3b0465d3d30b4505c294a6550db47f3c17ad18" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.110", ] [[package]] @@ -2582,7 +2610,7 @@ checksum = "1e567bd82dcff979e4b03460c307b3cdc9e96fde3d73bed1496d2bc75d9dd62a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.110", ] [[package]] @@ -2591,33 +2619,31 @@ version = "0.99.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6edb4b64a43d977b8e99788fe3a04d483834fba1215a7e02caa415b626497f7f" dependencies = [ - "convert_case 0.4.0", + "convert_case", "proc-macro2", "quote", "rustc_version 0.4.1", - "syn 2.0.111", + "syn 2.0.110", ] [[package]] name = "derive_more" -version = "2.1.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10b768e943bed7bf2cab53df09f4bc34bfd217cdb57d971e769874c9a6710618" +checksum = "093242cf7570c207c83073cf82f79706fe7b8317e98620a47d5be7c3d8497678" dependencies = [ "derive_more-impl", ] [[package]] name = "derive_more-impl" -version = "2.1.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d286bfdaf75e988b4a78e013ecd79c581e06399ab53fbacd2d916c2f904f30b" +checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3" dependencies = [ - "convert_case 0.10.0", "proc-macro2", "quote", - "rustc_version 0.4.1", - "syn 2.0.111", + "syn 2.0.110", "unicode-xid", ] @@ -2733,7 +2759,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.110", ] [[package]] @@ -2828,7 +2854,7 @@ dependencies = [ "enum-ordinalize", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.110", ] [[package]] @@ -2842,8 +2868,8 @@ dependencies = [ "context_deserialize", "educe", "eth2_network_config", - "ethereum_ssz", - "ethereum_ssz_derive", + "ethereum_ssz 0.10.0", + "ethereum_ssz_derive 0.10.0", "execution_layer", "fork_choice", "fs2", @@ -3051,7 +3077,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.110", ] [[package]] @@ -3071,7 +3097,7 @@ checksum = "8ca9601fb2d62598ee17836250842873a413586e5d7ed88b356e38ddbb0ec631" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.110", ] [[package]] @@ -3109,7 +3135,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -3122,8 +3148,8 @@ dependencies = [ "eip_3076", "eth2_keystore", "ethereum_serde_utils", - "ethereum_ssz", - "ethereum_ssz_derive", + "ethereum_ssz 0.10.0", + "ethereum_ssz_derive 0.10.0", "futures", "futures-util", "mediatype", @@ -3207,7 +3233,7 @@ dependencies = [ "bytes", "discv5", "eth2_config", - "ethereum_ssz", + "ethereum_ssz 0.10.0", "fixed_bytes", "kzg", "pretty_reqwest_error", @@ -3274,15 +3300,30 @@ dependencies = [ [[package]] name = "ethereum_ssz" -version = "0.10.1" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2128a84f7a3850d54ee343334e3392cca61f9f6aa9441eec481b9394b43c238b" +checksum = "0dcddb2554d19cde19b099fadddde576929d7a4d0c1cd3512d1fd95cf174375c" +dependencies = [ + "alloy-primitives", + "ethereum_serde_utils", + "itertools 0.13.0", + "serde", + "serde_derive", + "smallvec", + "typenum", +] + +[[package]] +name = "ethereum_ssz" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e8cd8c4f47dfb947dbfe3cdf2945ae1da808dbedc592668658e827a12659ba1" dependencies = [ "alloy-primitives", "arbitrary", "context_deserialize", "ethereum_serde_utils", - "itertools 0.14.0", + "itertools 0.13.0", "serde", "serde_derive", "smallvec", @@ -3291,14 +3332,26 @@ dependencies = [ [[package]] name = "ethereum_ssz_derive" -version = "0.10.1" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd596f91cff004fc8d02be44c21c0f9b93140a04b66027ae052f5f8e05b48eba" +checksum = "a657b6b3b7e153637dc6bdc6566ad9279d9ee11a15b12cfb24a2e04360637e9f" dependencies = [ - "darling 0.23.0", + "darling 0.20.11", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.110", +] + +[[package]] +name = "ethereum_ssz_derive" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78d247bc40823c365a62e572441a8f8b12df03f171713f06bc76180fcd56ab71" +dependencies = [ + "darling 0.20.11", + "proc-macro2", + "quote", + "syn 2.0.110", ] [[package]] @@ -3382,7 +3435,7 @@ dependencies = [ "bytes", "eth2", "ethereum_serde_utils", - "ethereum_ssz", + "ethereum_ssz 0.10.0", "fixed_bytes", "fork_choice", "hash-db", @@ -3580,8 +3633,8 @@ name = "fork_choice" version = "0.1.0" dependencies = [ "beacon_chain", - "ethereum_ssz", - "ethereum_ssz_derive", + "ethereum_ssz 0.10.0", + "ethereum_ssz_derive 0.10.0", "fixed_bytes", "logging", "metrics", @@ -3702,7 +3755,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.110", ] [[package]] @@ -3775,7 +3828,7 @@ version = "0.2.0" dependencies = [ "bls", "ethereum_hashing", - "ethereum_ssz", + "ethereum_ssz 0.10.0", "int_to_bytes", "merkle_proof", "rayon", @@ -3865,7 +3918,7 @@ dependencies = [ "futures-sink", "futures-util", "http 0.2.12", - "indexmap 2.12.1", + "indexmap 2.12.0", "slab", "tokio", "tokio-util", @@ -3883,8 +3936,8 @@ dependencies = [ "fnv", "futures-core", "futures-sink", - "http 1.4.0", - "indexmap 2.12.1", + "http 1.3.1", + "indexmap 2.12.0", "slab", "tokio", "tokio-util", @@ -3946,13 +3999,12 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.16.1" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" dependencies = [ "foldhash 0.2.0", "serde", - "serde_core", ] [[package]] @@ -3975,11 +4027,11 @@ dependencies = [ [[package]] name = "hashlink" -version = "0.10.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1" +checksum = "ea0b22561a9c04a7cb1a302c013e0259cd3b4bb619f145b32f72b8b4bcbed230" dependencies = [ - "hashbrown 0.15.5", + "hashbrown 0.16.0", ] [[package]] @@ -4049,9 +4101,9 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-conservative" -version = "0.2.2" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fda06d18ac606267c40c04e41b9947729bf8b9efe74bd4e82b61a5f26a510b9f" +checksum = "5313b072ce3c597065a808dbf612c4c8e8590bdbf8b579508bf7a762c5eae6cd" dependencies = [ "arrayvec", ] @@ -4140,11 +4192,12 @@ dependencies = [ [[package]] name = "http" -version = "1.4.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" +checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" dependencies = [ "bytes", + "fnv", "itoa", ] @@ -4166,7 +4219,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", - "http 1.4.0", + "http 1.3.1", ] [[package]] @@ -4177,7 +4230,7 @@ checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" dependencies = [ "bytes", "futures-core", - "http 1.4.0", + "http 1.3.1", "http-body 1.0.1", "pin-project-lite", ] @@ -4196,7 +4249,7 @@ dependencies = [ "either", "eth2", "ethereum_serde_utils", - "ethereum_ssz", + "ethereum_ssz 0.10.0", "execution_layer", "fixed_bytes", "futures", @@ -4309,7 +4362,7 @@ dependencies = [ "futures-channel", "futures-core", "h2 0.4.12", - "http 1.4.0", + "http 1.3.1", "http-body 1.0.1", "httparse", "httpdate", @@ -4327,7 +4380,7 @@ version = "0.27.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" dependencies = [ - "http 1.4.0", + "http 1.3.1", "hyper 1.8.1", "hyper-util", "rustls 0.23.35", @@ -4353,16 +4406,16 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.19" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "727805d60e7938b76b826a6ef209eb70eaa1812794f9424d4a4e2d740662df5f" +checksum = "52e9a2a24dc5c6821e71a7030e1e14b7b632acac55c40e9d2e082c621261bb56" dependencies = [ "base64 0.22.1", "bytes", "futures-channel", "futures-core", "futures-util", - "http 1.4.0", + "http 1.3.1", "http-body 1.0.1", "hyper 1.8.1", "ipnet", @@ -4447,9 +4500,9 @@ checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" [[package]] name = "icu_properties" -version = "2.1.2" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" +checksum = "e93fcd3157766c0c8da2f8cff6ce651a31f0810eaa1c51ec363ef790bbb5fb99" dependencies = [ "icu_collections", "icu_locale_core", @@ -4461,9 +4514,9 @@ dependencies = [ [[package]] name = "icu_properties_data" -version = "2.1.2" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" +checksum = "02845b3647bb045f1100ecd6480ff52f34c35f82d9880e029d329c21d1054899" [[package]] name = "icu_provider" @@ -4560,7 +4613,7 @@ dependencies = [ "attohttpc", "bytes", "futures", - "http 1.4.0", + "http 1.3.1", "http-body-util", "hyper 1.8.1", "hyper-util", @@ -4588,7 +4641,7 @@ checksum = "a0eb5a3343abf848c0984fe4604b2b105da9539376e24fc0a3b0007411ae4fd9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.110", ] [[package]] @@ -4604,13 +4657,13 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.12.1" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2" +checksum = "6717a8d2a5a929a1a2eb43a12812498ed141a0bcfb7e8f7844fbdbe4303bba9f" dependencies = [ "arbitrary", "equivalent", - "hashbrown 0.16.1", + "hashbrown 0.16.0", "serde", "serde_core", ] @@ -4759,9 +4812,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.83" +version = "0.3.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "464a3709c7f55f1f721e5389aa6ea4e3bc6aba669353300af094b29ffbdde1d8" +checksum = "b011eec8cc36da2aab2d5cff675ec18454fad408585853910a202391cf9f8e65" dependencies = [ "once_cell", "wasm-bindgen", @@ -4836,8 +4889,8 @@ dependencies = [ "educe", "ethereum_hashing", "ethereum_serde_utils", - "ethereum_ssz", - "ethereum_ssz_derive", + "ethereum_ssz 0.10.0", + "ethereum_ssz_derive 0.10.0", "hex", "rayon", "rust_eth_kzg", @@ -4877,7 +4930,7 @@ dependencies = [ "eth2_network_config", "eth2_wallet", "ethereum_hashing", - "ethereum_ssz", + "ethereum_ssz 0.10.0", "execution_layer", "fixed_bytes", "hex", @@ -4925,9 +4978,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.178" +version = "0.2.177" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091" +checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" [[package]] name = "libloading" @@ -4963,7 +5016,7 @@ dependencies = [ [[package]] name = "libp2p" version = "0.56.1" -source = "git+https://github.com/libp2p/rust-libp2p.git#5e3519fb66b92c7f7c0dc744ab360fd8b669fe54" +source = "git+https://github.com/libp2p/rust-libp2p.git#5bad680f71a88be9a028e349770195d8a72356ce" dependencies = [ "bytes", "either", @@ -4994,7 +5047,7 @@ dependencies = [ [[package]] name = "libp2p-allow-block-list" version = "0.6.0" -source = "git+https://github.com/libp2p/rust-libp2p.git#5e3519fb66b92c7f7c0dc744ab360fd8b669fe54" +source = "git+https://github.com/libp2p/rust-libp2p.git#5bad680f71a88be9a028e349770195d8a72356ce" dependencies = [ "libp2p-core", "libp2p-identity", @@ -5004,7 +5057,7 @@ dependencies = [ [[package]] name = "libp2p-connection-limits" version = "0.6.0" -source = "git+https://github.com/libp2p/rust-libp2p.git#5e3519fb66b92c7f7c0dc744ab360fd8b669fe54" +source = "git+https://github.com/libp2p/rust-libp2p.git#5bad680f71a88be9a028e349770195d8a72356ce" dependencies = [ "libp2p-core", "libp2p-identity", @@ -5014,7 +5067,7 @@ dependencies = [ [[package]] name = "libp2p-core" version = "0.43.2" -source = "git+https://github.com/libp2p/rust-libp2p.git#5e3519fb66b92c7f7c0dc744ab360fd8b669fe54" +source = "git+https://github.com/libp2p/rust-libp2p.git#5bad680f71a88be9a028e349770195d8a72356ce" dependencies = [ "either", "fnv", @@ -5038,7 +5091,7 @@ dependencies = [ [[package]] name = "libp2p-dns" version = "0.44.0" -source = "git+https://github.com/libp2p/rust-libp2p.git#5e3519fb66b92c7f7c0dc744ab360fd8b669fe54" +source = "git+https://github.com/libp2p/rust-libp2p.git#5bad680f71a88be9a028e349770195d8a72356ce" dependencies = [ "async-trait", "futures", @@ -5053,7 +5106,7 @@ dependencies = [ [[package]] name = "libp2p-gossipsub" version = "0.50.0" -source = "git+https://github.com/libp2p/rust-libp2p.git#5e3519fb66b92c7f7c0dc744ab360fd8b669fe54" +source = "git+https://github.com/libp2p/rust-libp2p.git#5bad680f71a88be9a028e349770195d8a72356ce" dependencies = [ "async-channel 2.5.0", "asynchronous-codec", @@ -5065,7 +5118,7 @@ dependencies = [ "futures", "futures-timer", "getrandom 0.2.16", - "hashlink 0.10.0", + "hashlink 0.11.0", "hex_fmt", "libp2p-core", "libp2p-identity", @@ -5083,7 +5136,7 @@ dependencies = [ [[package]] name = "libp2p-identify" version = "0.47.0" -source = "git+https://github.com/libp2p/rust-libp2p.git#5e3519fb66b92c7f7c0dc744ab360fd8b669fe54" +source = "git+https://github.com/libp2p/rust-libp2p.git#5bad680f71a88be9a028e349770195d8a72356ce" dependencies = [ "asynchronous-codec", "either", @@ -5123,7 +5176,7 @@ dependencies = [ [[package]] name = "libp2p-mdns" version = "0.48.0" -source = "git+https://github.com/libp2p/rust-libp2p.git#5e3519fb66b92c7f7c0dc744ab360fd8b669fe54" +source = "git+https://github.com/libp2p/rust-libp2p.git#5bad680f71a88be9a028e349770195d8a72356ce" dependencies = [ "futures", "hickory-proto", @@ -5141,7 +5194,7 @@ dependencies = [ [[package]] name = "libp2p-metrics" version = "0.17.1" -source = "git+https://github.com/libp2p/rust-libp2p.git#5e3519fb66b92c7f7c0dc744ab360fd8b669fe54" +source = "git+https://github.com/libp2p/rust-libp2p.git#5bad680f71a88be9a028e349770195d8a72356ce" dependencies = [ "futures", "libp2p-core", @@ -5157,7 +5210,7 @@ dependencies = [ [[package]] name = "libp2p-mplex" version = "0.43.1" -source = "git+https://github.com/libp2p/rust-libp2p.git#5e3519fb66b92c7f7c0dc744ab360fd8b669fe54" +source = "git+https://github.com/libp2p/rust-libp2p.git#5bad680f71a88be9a028e349770195d8a72356ce" dependencies = [ "asynchronous-codec", "bytes", @@ -5175,7 +5228,7 @@ dependencies = [ [[package]] name = "libp2p-noise" version = "0.46.1" -source = "git+https://github.com/libp2p/rust-libp2p.git#5e3519fb66b92c7f7c0dc744ab360fd8b669fe54" +source = "git+https://github.com/libp2p/rust-libp2p.git#5bad680f71a88be9a028e349770195d8a72356ce" dependencies = [ "asynchronous-codec", "bytes", @@ -5197,7 +5250,7 @@ dependencies = [ [[package]] name = "libp2p-quic" version = "0.13.0" -source = "git+https://github.com/libp2p/rust-libp2p.git#5e3519fb66b92c7f7c0dc744ab360fd8b669fe54" +source = "git+https://github.com/libp2p/rust-libp2p.git#5bad680f71a88be9a028e349770195d8a72356ce" dependencies = [ "futures", "futures-timer", @@ -5217,14 +5270,14 @@ dependencies = [ [[package]] name = "libp2p-swarm" -version = "0.47.0" -source = "git+https://github.com/libp2p/rust-libp2p.git#5e3519fb66b92c7f7c0dc744ab360fd8b669fe54" +version = "0.47.1" +source = "git+https://github.com/libp2p/rust-libp2p.git#5bad680f71a88be9a028e349770195d8a72356ce" dependencies = [ "either", "fnv", "futures", "futures-timer", - "hashlink 0.10.0", + "hashlink 0.11.0", "libp2p-core", "libp2p-identity", "libp2p-swarm-derive", @@ -5239,17 +5292,17 @@ dependencies = [ [[package]] name = "libp2p-swarm-derive" version = "0.35.1" -source = "git+https://github.com/libp2p/rust-libp2p.git#5e3519fb66b92c7f7c0dc744ab360fd8b669fe54" +source = "git+https://github.com/libp2p/rust-libp2p.git#5bad680f71a88be9a028e349770195d8a72356ce" dependencies = [ "heck", "quote", - "syn 2.0.111", + "syn 2.0.110", ] [[package]] name = "libp2p-tcp" version = "0.44.1" -source = "git+https://github.com/libp2p/rust-libp2p.git#5e3519fb66b92c7f7c0dc744ab360fd8b669fe54" +source = "git+https://github.com/libp2p/rust-libp2p.git#5bad680f71a88be9a028e349770195d8a72356ce" dependencies = [ "futures", "futures-timer", @@ -5264,7 +5317,7 @@ dependencies = [ [[package]] name = "libp2p-tls" version = "0.6.2" -source = "git+https://github.com/libp2p/rust-libp2p.git#5e3519fb66b92c7f7c0dc744ab360fd8b669fe54" +source = "git+https://github.com/libp2p/rust-libp2p.git#5bad680f71a88be9a028e349770195d8a72356ce" dependencies = [ "futures", "futures-rustls", @@ -5282,7 +5335,7 @@ dependencies = [ [[package]] name = "libp2p-upnp" version = "0.6.0" -source = "git+https://github.com/libp2p/rust-libp2p.git#5e3519fb66b92c7f7c0dc744ab360fd8b669fe54" +source = "git+https://github.com/libp2p/rust-libp2p.git#5bad680f71a88be9a028e349770195d8a72356ce" dependencies = [ "futures", "futures-timer", @@ -5296,7 +5349,7 @@ dependencies = [ [[package]] name = "libp2p-yamux" version = "0.47.0" -source = "git+https://github.com/libp2p/rust-libp2p.git#5e3519fb66b92c7f7c0dc744ab360fd8b669fe54" +source = "git+https://github.com/libp2p/rust-libp2p.git#5bad680f71a88be9a028e349770195d8a72356ce" dependencies = [ "either", "futures", @@ -5309,9 +5362,9 @@ dependencies = [ [[package]] name = "libredox" -version = "0.1.11" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df15f6eac291ed1cf25865b1ee60399f57e7c227e7f51bdbd4c5270396a9ed50" +checksum = "416f7e718bdb06000964960ffa43b4335ad4012ae8b99060261aa4a8088d5ccb" dependencies = [ "bitflags 2.10.0", "libc", @@ -5330,9 +5383,9 @@ dependencies = [ [[package]] name = "libz-rs-sys" -version = "0.5.4" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15413ef615ad868d4d65dce091cb233b229419c7c0c4bcaa746c0901c49ff39c" +checksum = "c10501e7805cee23da17c7790e59df2870c0d4043ec6d03f67d31e2b53e77415" dependencies = [ "zlib-rs", ] @@ -5414,8 +5467,8 @@ dependencies = [ "discv5", "either", "eth2", - "ethereum_ssz", - "ethereum_ssz_derive", + "ethereum_ssz 0.10.0", + "ethereum_ssz_derive 0.10.0", "fixed_bytes", "fnv", "futures", @@ -5539,9 +5592,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.29" +version = "0.4.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" +checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" [[package]] name = "logging" @@ -5622,7 +5675,7 @@ checksum = "1b27834086c65ec3f9387b096d66e99f221cf081c2b738042aa252bcd41204e3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.110", ] [[package]] @@ -5644,13 +5697,13 @@ checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" [[package]] name = "match-lookup" -version = "0.1.2" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "757aee279b8bdbb9f9e676796fd459e4207a1f986e87886700abf589f5abf771" +checksum = "1265724d8cb29dbbc2b0f06fffb8bf1a8c0cf73a78eede9ba73a4a66c52a981e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 1.0.109", ] [[package]] @@ -5719,25 +5772,25 @@ dependencies = [ [[package]] name = "metastruct" -version = "0.1.4" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "969a1be9bd80794bdf93b23ab552c2ec6f3e83b33164824553fd996cdad513b8" +checksum = "d74f54f231f9a18d77393ecc5cc7ab96709b2a61ee326c2b2b291009b0cc5a07" dependencies = [ "metastruct_macro", ] [[package]] name = "metastruct_macro" -version = "0.1.4" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de9164f767d73a507c19205868c84da411dc7795f4bdabf497d3dd93cfef9930" +checksum = "985e7225f3a4dfbec47a0c6a730a874185fda840d365d7bbd6ba199dd81796d5" dependencies = [ - "darling 0.23.0", - "itertools 0.14.0", + "darling 0.13.4", + "itertools 0.10.5", "proc-macro2", "quote", "smallvec", - "syn 2.0.111", + "syn 1.0.109", ] [[package]] @@ -5758,8 +5811,8 @@ dependencies = [ "context_deserialize", "educe", "ethereum_hashing", - "ethereum_ssz", - "ethereum_ssz_derive", + "ethereum_ssz 0.10.0", + "ethereum_ssz_derive 0.10.0", "itertools 0.13.0", "parking_lot", "rayon", @@ -5805,9 +5858,9 @@ dependencies = [ [[package]] name = "mio" -version = "1.1.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" +checksum = "69d83b0086dc8ecf3ce9ae2874b2d1290252e2a30720bea58a5c6639b0092873" dependencies = [ "libc", "wasi", @@ -5843,7 +5896,7 @@ dependencies = [ "cfg-if", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.110", ] [[package]] @@ -5855,26 +5908,25 @@ dependencies = [ "cfg-if", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.110", ] [[package]] name = "mockito" -version = "1.7.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e0603425789b4a70fcc4ac4f5a46a566c116ee3e2a6b768dc623f7719c611de" +checksum = "7760e0e418d9b7e5777c0374009ca4c93861b9066f18cb334a20ce50ab63aa48" dependencies = [ "assert-json-diff", "bytes", "colored", - "futures-core", - "http 1.4.0", + "futures-util", + "http 1.3.1", "http-body 1.0.1", "http-body-util", "hyper 1.8.1", "hyper-util", "log", - "pin-project-lite", "rand 0.9.2", "regex", "serde_json", @@ -5898,7 +5950,7 @@ dependencies = [ "rustc_version 0.4.1", "smallvec", "tagptr", - "uuid 1.19.0", + "uuid 1.18.1", ] [[package]] @@ -5970,7 +6022,7 @@ dependencies = [ [[package]] name = "multistream-select" version = "0.13.0" -source = "git+https://github.com/libp2p/rust-libp2p.git#5e3519fb66b92c7f7c0dc744ab360fd8b669fe54" +source = "git+https://github.com/libp2p/rust-libp2p.git#5bad680f71a88be9a028e349770195d8a72356ce" dependencies = [ "bytes", "futures", @@ -6059,7 +6111,7 @@ dependencies = [ "educe", "eth2", "eth2_network_config", - "ethereum_ssz", + "ethereum_ssz 0.10.0", "execution_layer", "fixed_bytes", "fnv", @@ -6082,6 +6134,7 @@ dependencies = [ "rand 0.9.2", "rand_chacha 0.3.1", "rand_chacha 0.9.0", + "reth-era", "serde_json", "slot_clock", "smallvec", @@ -6194,7 +6247,7 @@ version = "0.50.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -6288,7 +6341,7 @@ checksum = "ff32365de1b6743cb203b710788263c44a03de03802daf96092f2da4fe6ba4d7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.110", ] [[package]] @@ -6392,7 +6445,7 @@ checksum = "50f6639e842a97dbea8886e3439710ae463120091e2e064518ba8e716e6ac36d" dependencies = [ "async-trait", "bytes", - "http 1.4.0", + "http 1.3.1", "opentelemetry", "reqwest", ] @@ -6403,7 +6456,7 @@ version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dbee664a43e07615731afc539ca60c6d9f1a9425e25ca09c57bc36c87c55852b" dependencies = [ - "http 1.4.0", + "http 1.3.1", "opentelemetry", "opentelemetry-http", "opentelemetry-proto", @@ -6452,8 +6505,8 @@ dependencies = [ "bitvec", "bls", "educe", - "ethereum_ssz", - "ethereum_ssz_derive", + "ethereum_ssz 0.10.0", + "ethereum_ssz_derive 0.10.0", "fixed_bytes", "itertools 0.14.0", "maplit", @@ -6537,7 +6590,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.110", ] [[package]] @@ -6612,9 +6665,9 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "pest" -version = "2.8.4" +version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbcfd20a6d4eeba40179f05735784ad32bdaef05ce8e8af05f180d45bb3e7e22" +checksum = "989e7521a040efde50c3ab6bbadafbe15ab6dc042686926be59ac35d74607df4" dependencies = [ "memchr", "ucd-trie", @@ -6637,7 +6690,7 @@ checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.110", ] [[package]] @@ -6840,7 +6893,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", - "syn 2.0.111", + "syn 2.0.110", ] [[package]] @@ -6882,7 +6935,7 @@ dependencies = [ "proc-macro-error-attr2", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.110", ] [[package]] @@ -6949,7 +7002,7 @@ checksum = "9adf1691c04c0a5ff46ff8f262b58beb07b0dbb61f96f9f54f6cbd82106ed87f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.110", ] [[package]] @@ -6979,7 +7032,7 @@ checksum = "095a99f75c69734802359b682be8daaf8980296731f6470434ea2c652af1dd30" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.110", ] [[package]] @@ -7002,7 +7055,7 @@ dependencies = [ "itertools 0.14.0", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.110", ] [[package]] @@ -7018,8 +7071,8 @@ dependencies = [ name = "proto_array" version = "0.2.0" dependencies = [ - "ethereum_ssz", - "ethereum_ssz_derive", + "ethereum_ssz 0.10.0", + "ethereum_ssz_derive 0.10.0", "fixed_bytes", "safe_arith", "serde", @@ -7064,7 +7117,7 @@ dependencies = [ [[package]] name = "quick-protobuf-codec" version = "0.3.1" -source = "git+https://github.com/libp2p/rust-libp2p.git#5e3519fb66b92c7f7c0dc744ab360fd8b669fe54" +source = "git+https://github.com/libp2p/rust-libp2p.git#5bad680f71a88be9a028e349770195d8a72356ce" dependencies = [ "asynchronous-codec", "bytes", @@ -7253,9 +7306,9 @@ dependencies = [ [[package]] name = "rapidhash" -version = "4.1.1" +version = "4.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8e65c75143ce5d47c55b510297eeb1182f3c739b6043c537670e9fc18612dae" +checksum = "2988730ee014541157f48ce4dcc603940e00915edc3c7f9a8d78092256bb2493" dependencies = [ "rustversion", ] @@ -7348,7 +7401,7 @@ checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.110", ] [[package]] @@ -7382,16 +7435,16 @@ checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" [[package]] name = "reqwest" -version = "0.12.26" +version = "0.12.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b4c14b2d9afca6a60277086b0cc6a6ae0b568f6f7916c943a8cdc79f8be240f" +checksum = "9d0946410b9f7b082a427e4ef5c8ff541a88b357bc6c637c40db3a68ac70a36f" dependencies = [ "base64 0.22.1", "bytes", "futures-channel", "futures-core", "futures-util", - "http 1.4.0", + "http 1.3.1", "http-body 1.0.1", "http-body-util", "hyper 1.8.1", @@ -7444,6 +7497,21 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e061d1b48cb8d38042de4ae0a7a6401009d6143dc80d2e2d6f31f0bdd6470c7" +[[package]] +name = "reth-era" +version = "1.9.3" +source = "git+https://github.com/paradigmxyz/reth?rev=62abfdaeb54e8a205a8ee085ddebd56047d93374#62abfdaeb54e8a205a8ee085ddebd56047d93374" +dependencies = [ + "alloy-consensus", + "alloy-eips", + "alloy-primitives", + "alloy-rlp", + "ethereum_ssz 0.9.1", + "ethereum_ssz_derive 0.9.1", + "snap", + "thiserror 2.0.17", +] + [[package]] name = "rfc6979" version = "0.4.0" @@ -7636,7 +7704,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -7691,9 +7759,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.13.2" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21e6f2ab2928ca4291b86736a8bd920a277a399bba1589409d72154ff87c1282" +checksum = "94182ad936a0c91c324cd46c6511b9510ed16af436d7b5bab34beab0afd55f7a" dependencies = [ "web-time", "zeroize", @@ -7742,7 +7810,7 @@ dependencies = [ [[package]] name = "rw-stream-sink" version = "0.4.0" -source = "git+https://github.com/libp2p/rust-libp2p.git#5e3519fb66b92c7f7c0dc744ab360fd8b669fe54" +source = "git+https://github.com/libp2p/rust-libp2p.git#5bad680f71a88be9a028e349770195d8a72356ce" dependencies = [ "futures", "pin-project", @@ -7978,7 +8046,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.110", ] [[package]] @@ -8002,7 +8070,7 @@ checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.110", ] [[package]] @@ -8019,15 +8087,15 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.16.1" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fa237f2807440d238e0364a218270b98f767a00d3dada77b1c53ae88940e2e7" +checksum = "10574371d41b0d9b2cff89418eda27da52bcaff2cc8741db26382a77c29131f1" dependencies = [ "base64 0.22.1", "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.12.1", + "indexmap 2.12.0", "schemars 0.9.0", "schemars 1.1.0", "serde_core", @@ -8038,14 +8106,14 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.16.1" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52a8e3ca0ca629121f70ab50f95249e5a6f925cc0f6ffe8256c45b728875706c" +checksum = "08a72d8216842fdd57820dc78d840bef99248e35fb2554ff923319e60f2d686b" dependencies = [ "darling 0.21.3", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.110", ] [[package]] @@ -8054,7 +8122,7 @@ version = "0.9.34+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" dependencies = [ - "indexmap 2.12.1", + "indexmap 2.12.0", "itoa", "ryu", "serde", @@ -8130,9 +8198,9 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "signal-hook-registry" -version = "1.4.7" +version = "1.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7664a098b8e616bdfcc2dc0e9ac44eb231eedf41db4e9fe95d8d32ec728dedad" +checksum = "b2a4719bff48cee6b39d12c020eeb490953ad2443b7055bd0b21fca26bd8c28b" dependencies = [ "libc", ] @@ -8167,9 +8235,9 @@ dependencies = [ [[package]] name = "simd-adler32" -version = "0.3.8" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" [[package]] name = "similar" @@ -8225,8 +8293,8 @@ dependencies = [ "bls", "byteorder", "educe", - "ethereum_ssz", - "ethereum_ssz_derive", + "ethereum_ssz 0.10.0", + "ethereum_ssz_derive 0.10.0", "filesystem", "fixed_bytes", "flate2", @@ -8378,7 +8446,7 @@ dependencies = [ "context_deserialize", "educe", "ethereum_serde_utils", - "ethereum_ssz", + "ethereum_ssz 0.10.0", "itertools 0.14.0", "serde", "serde_derive", @@ -8402,8 +8470,8 @@ dependencies = [ "bls", "educe", "ethereum_hashing", - "ethereum_ssz", - "ethereum_ssz_derive", + "ethereum_ssz 0.10.0", + "ethereum_ssz_derive 0.10.0", "fixed_bytes", "int_to_bytes", "integer-sqrt", @@ -8430,7 +8498,7 @@ version = "0.1.0" dependencies = [ "beacon_chain", "bls", - "ethereum_ssz", + "ethereum_ssz 0.10.0", "fixed_bytes", "state_processing", "tokio", @@ -8452,8 +8520,8 @@ dependencies = [ "criterion", "db-key", "directory", - "ethereum_ssz", - "ethereum_ssz_derive", + "ethereum_ssz 0.10.0", + "ethereum_ssz_derive 0.10.0", "fixed_bytes", "itertools 0.14.0", "leveldb", @@ -8480,6 +8548,12 @@ dependencies = [ "zstd", ] +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + [[package]] name = "strsim" version = "0.11.1" @@ -8504,7 +8578,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.110", ] [[package]] @@ -8515,16 +8589,16 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "superstruct" -version = "0.10.1" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bae4a9ccd7882533c1f210e400763ec6ee64c390fc12248c238276281863719e" +checksum = "3b986e4a629907f20a2c2a639a75bc22a8b5d99b444e0d83c395f4cb309022bf" dependencies = [ - "darling 0.23.0", - "itertools 0.14.0", + "darling 0.20.11", + "itertools 0.13.0", "proc-macro2", "quote", "smallvec", - "syn 2.0.111", + "syn 2.0.110", ] [[package]] @@ -8550,9 +8624,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.111" +version = "2.0.110" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "390cc9a294ab71bdb1aa2e99d13be9c753cd2d7bd6560c77118597410c4d2e87" +checksum = "a99801b5bd34ede4cf3fc688c5919368fea4e4814a4664359503e6015b280aea" dependencies = [ "proc-macro2", "quote", @@ -8561,14 +8635,14 @@ dependencies = [ [[package]] name = "syn-solidity" -version = "1.5.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60ceeb7c95a4536de0c0e1649bd98d1a72a4bb9590b1f3e45a8a0bfdb7c188c0" +checksum = "ff790eb176cc81bb8936aed0f7b9f14fc4670069a2d371b3e3b0ecce908b2cb3" dependencies = [ "paste", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.110", ] [[package]] @@ -8588,7 +8662,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.110", ] [[package]] @@ -8682,7 +8756,7 @@ dependencies = [ "getrandom 0.3.4", "once_cell", "rustix", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -8706,7 +8780,7 @@ name = "test_random_derive" version = "0.2.0" dependencies = [ "quote", - "syn 2.0.111", + "syn 2.0.110", ] [[package]] @@ -8735,7 +8809,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.110", ] [[package]] @@ -8746,7 +8820,7 @@ checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.110", ] [[package]] @@ -8927,7 +9001,7 @@ checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.110", ] [[package]] @@ -8980,20 +9054,20 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.7.4+spec-1.0.0" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe3cea6b2aa3b910092f6abd4053ea464fab5f9c170ba5e9a6aead16ec4af2b6" +checksum = "f2cdb639ebbc97961c51720f858597f7f24c4fc295327923af55b74c3c724533" dependencies = [ "serde_core", ] [[package]] name = "toml_edit" -version = "0.23.10+spec-1.0.0" +version = "0.23.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84c8b9f757e028cee9fa244aea147aab2a9ec09d5325a9b01e0a49730c2b5269" +checksum = "6485ef6d0d9b5d0ec17244ff7eb05310113c3f316f2d14200d4de56b3cb98f8d" dependencies = [ - "indexmap 2.12.1", + "indexmap 2.12.0", "toml_datetime", "toml_parser", "winnow", @@ -9001,9 +9075,9 @@ dependencies = [ [[package]] name = "toml_parser" -version = "1.0.5+spec-1.0.0" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c03bee5ce3696f31250db0bbaff18bc43301ce0e8db2ed1f07cbb2acf89984c" +checksum = "c0cbe268d35bdb4bb5a56a2de88d0ad0eb70af5384a99d648cd4b3d04039800e" dependencies = [ "winnow", ] @@ -9020,7 +9094,7 @@ dependencies = [ "base64 0.22.1", "bytes", "h2 0.4.12", - "http 1.4.0", + "http 1.3.1", "http-body 1.0.1", "http-body-util", "hyper 1.8.1", @@ -9047,7 +9121,7 @@ dependencies = [ "async-trait", "base64 0.22.1", "bytes", - "http 1.4.0", + "http 1.3.1", "http-body 1.0.1", "http-body-util", "hyper 1.8.1", @@ -9094,7 +9168,7 @@ checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" dependencies = [ "futures-core", "futures-util", - "indexmap 2.12.1", + "indexmap 2.12.0", "pin-project-lite", "slab", "sync_wrapper", @@ -9107,14 +9181,14 @@ dependencies = [ [[package]] name = "tower-http" -version = "0.6.8" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" +checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" dependencies = [ "bitflags 2.10.0", "bytes", "futures-util", - "http 1.4.0", + "http 1.3.1", "http-body 1.0.1", "iri-string", "pin-project-lite", @@ -9137,9 +9211,9 @@ checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" -version = "0.1.43" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d15d90a0b5c19378952d479dc858407149d7bb45a14de0142f6c534b16fc647" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ "log", "pin-project-lite", @@ -9149,32 +9223,32 @@ dependencies = [ [[package]] name = "tracing-appender" -version = "0.2.4" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "786d480bce6247ab75f005b14ae1624ad978d3029d9113f0a22fa1ac773faeaf" +checksum = "3566e8ce28cc0a3fe42519fc80e6b4c943cc4c8cef275620eb8dac2d3d4e06cf" dependencies = [ "crossbeam-channel", - "thiserror 2.0.17", + "thiserror 1.0.69", "time", "tracing-subscriber", ] [[package]] name = "tracing-attributes" -version = "0.1.31" +version = "0.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" +checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.110", ] [[package]] name = "tracing-core" -version = "0.1.35" +version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a04e24fab5c89c6a36eb8558c9656f30d81de51dfa4d3b45f26b21d61fa0a6c" +checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" dependencies = [ "once_cell", "valuable", @@ -9221,9 +9295,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.22" +version = "0.3.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e" +checksum = "2054a14f5307d601f88daf0553e1cbf472acc4f2c51afab632431cdcd72124d5" dependencies = [ "matchers", "nu-ansi-term", @@ -9250,27 +9324,27 @@ dependencies = [ [[package]] name = "tree_hash" -version = "0.12.1" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7fd51aa83d2eb83b04570808430808b5d24fdbf479a4d5ac5dee4a2e2dd2be4" +checksum = "2db21caa355767db4fd6129876e5ae278a8699f4a6959b1e3e7aff610b532d52" dependencies = [ "alloy-primitives", "ethereum_hashing", - "ethereum_ssz", + "ethereum_ssz 0.10.0", "smallvec", "typenum", ] [[package]] name = "tree_hash_derive" -version = "0.12.1" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8840ad4d852e325d3afa7fde8a50b2412f89dce47d7eb291c0cc7f87cd040f38" +checksum = "711cc655fcbb48384a87dc2bf641b991a15c5ad9afc3caa0b1ab1df3b436f70f" dependencies = [ - "darling 0.23.0", + "darling 0.21.3", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.110", ] [[package]] @@ -9321,8 +9395,8 @@ dependencies = [ "eth2_interop_keypairs", "ethereum_hashing", "ethereum_serde_utils", - "ethereum_ssz", - "ethereum_ssz_derive", + "ethereum_ssz 0.10.0", + "ethereum_ssz_derive 0.10.0", "fixed_bytes", "hex", "int_to_bytes", @@ -9421,12 +9495,6 @@ dependencies = [ "tinyvec", ] -[[package]] -name = "unicode-segmentation" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" - [[package]] name = "unicode-xid" version = "0.2.6" @@ -9502,9 +9570,9 @@ dependencies = [ [[package]] name = "uuid" -version = "1.19.0" +version = "1.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2e054861b4bd027cd373e18e8d8d8e6548085000e41290d95ce0c373a654b4a" +checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2" dependencies = [ "getrandom 0.3.4", "js-sys", @@ -9832,9 +9900,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.106" +version = "0.2.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d759f433fa64a2d763d1340820e46e111a7a5ab75f993d1852d70b03dbb80fd" +checksum = "da95793dfc411fbbd93f5be7715b0578ec61fe87cb1a42b12eb625caa5c5ea60" dependencies = [ "cfg-if", "once_cell", @@ -9845,9 +9913,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.56" +version = "0.4.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836d9622d604feee9e5de25ac10e3ea5f2d65b41eac0d9ce72eb5deae707ce7c" +checksum = "551f88106c6d5e7ccc7cd9a16f312dd3b5d36ea8b4954304657d5dfba115d4a0" dependencies = [ "cfg-if", "js-sys", @@ -9858,9 +9926,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.106" +version = "0.2.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48cb0d2638f8baedbc542ed444afc0644a29166f1595371af4fecf8ce1e7eeb3" +checksum = "04264334509e04a7bf8690f2384ef5265f05143a4bff3889ab7a3269adab59c2" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -9868,22 +9936,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.106" +version = "0.2.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cefb59d5cd5f92d9dcf80e4683949f15ca4b511f4ac0a6e14d4e1ac60c6ecd40" +checksum = "420bc339d9f322e562942d52e115d57e950d12d88983a14c79b86859ee6c7ebc" dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.110", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.106" +version = "0.2.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbc538057e648b67f72a982e708d485b2efa771e1ac05fec311f9f63e5800db4" +checksum = "76f218a38c84bcb33c25ec7059b07847d465ce0e0a76b995e134a45adcb6af76" dependencies = [ "unicode-ident", ] @@ -9917,9 +9985,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.83" +version = "0.3.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b32828d774c412041098d182a8b38b16ea816958e07cf40eec2bc080ae137ac" +checksum = "3a1f95c0d03a47f4ae1f7a64643a6bb97465d9b740f0fa8f90ea33915c99a9a1" dependencies = [ "js-sys", "wasm-bindgen", @@ -10011,7 +10079,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.48.0", ] [[package]] @@ -10073,7 +10141,7 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.110", ] [[package]] @@ -10084,7 +10152,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.110", ] [[package]] @@ -10353,9 +10421,9 @@ checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" [[package]] name = "winnow" -version = "0.7.14" +version = "0.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" +checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf" dependencies = [ "memchr", ] @@ -10538,28 +10606,28 @@ checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.110", "synstructure", ] [[package]] name = "zerocopy" -version = "0.8.31" +version = "0.8.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd74ec98b9250adb3ca554bdde269adf631549f51d8a8f8f0a10b50f1cb298c3" +checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.31" +version = "0.8.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8a8d209fdf45cf5138cbb5a506f6b52522a25afccc534d1475dad8e31105c6a" +checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.110", ] [[package]] @@ -10579,7 +10647,7 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.110", "synstructure", ] @@ -10601,7 +10669,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.110", ] [[package]] @@ -10634,7 +10702,7 @@ checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.110", ] [[package]] @@ -10646,16 +10714,16 @@ dependencies = [ "arbitrary", "crc32fast", "flate2", - "indexmap 2.12.1", + "indexmap 2.12.0", "memchr", "zopfli", ] [[package]] name = "zlib-rs" -version = "0.5.4" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51f936044d677be1a1168fae1d03b583a285a5dd9d8cbf7b24c23aa1fc775235" +checksum = "40990edd51aae2c2b6907af74ffb635029d5788228222c4bb811e9351c0caad3" [[package]] name = "zopfli" diff --git a/Cargo.toml b/Cargo.toml index 100a916c501..e8047c3acce 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -99,7 +99,7 @@ alloy-consensus = { version = "1", default-features = false } alloy-dyn-abi = { version = "1", default-features = false } alloy-json-abi = { version = "1", default-features = false } alloy-network = { version = "1", default-features = false } -alloy-primitives = { version = "1", default-features = false, features = ["rlp", "getrandom"] } +alloy-primitives = { version = "1.5", default-features = false, features = ["rlp", "getrandom"] } alloy-provider = { version = "1", default-features = false, features = ["reqwest"] } alloy-rlp = { version = "0.3", default-features = false } alloy-rpc-types-eth = { version = "1", default-features = false, features = ["serde"] } @@ -225,6 +225,7 @@ reqwest = { version = "0.12", default-features = false, features = [ "stream", "rustls-tls", ] } +reth-era = { git = "https://github.com/paradigmxyz/reth", package = "reth-era", rev = "62abfdaeb54e8a205a8ee085ddebd56047d93374" } ring = "0.17" rpds = "0.11" rusqlite = { version = "0.28", features = ["bundled"] } diff --git a/beacon_node/beacon_chain/Cargo.toml b/beacon_node/beacon_chain/Cargo.toml index 5e1c41b8302..b11463115db 100644 --- a/beacon_node/beacon_chain/Cargo.toml +++ b/beacon_node/beacon_chain/Cargo.toml @@ -47,6 +47,7 @@ parking_lot = { workspace = true } proto_array = { workspace = true } rand = { workspace = true } rayon = { workspace = true } +reth-era = { workspace = true } safe_arith = { workspace = true } sensitive_url = { workspace = true } serde = { workspace = true } diff --git a/beacon_node/beacon_chain/src/builder.rs b/beacon_node/beacon_chain/src/builder.rs index e5b656adf8d..d439f14fa45 100644 --- a/beacon_node/beacon_chain/src/builder.rs +++ b/beacon_node/beacon_chain/src/builder.rs @@ -6,6 +6,7 @@ use crate::beacon_chain::{ use crate::beacon_proposer_cache::BeaconProposerCache; use crate::custody_context::NodeCustodyType; use crate::data_availability_checker::DataAvailabilityChecker; +use crate::era_file_consumer::EraFileDir; use crate::fork_choice_signal::ForkChoiceSignalTx; use crate::fork_revert::{reset_fork_choice_to_finalization, revert_to_fork_boundary}; use crate::graffiti_calculator::{GraffitiCalculator, GraffitiOrigin}; @@ -37,8 +38,10 @@ use slasher::Slasher; use slot_clock::{SlotClock, TestingSlotClock}; use state_processing::{AllCaches, per_slot_processing}; use std::marker::PhantomData; +use std::path::Path; use std::sync::Arc; -use std::time::Duration; +use std::sync::atomic::{AtomicU64, Ordering}; +use std::time::{Duration, Instant}; use store::{Error as StoreError, HotColdDB, ItemStore, KeyValueStoreOp}; use task_executor::{ShutdownReason, TaskExecutor}; use tracing::{debug, error, info}; @@ -206,6 +209,134 @@ where self } + /// Import trusted era files into the store before building the chain. + pub fn era_files( + self, + era_files_dir: &Path, + mut genesis_state: BeaconState, + ) -> Result { + let genesis_state_root = genesis_state + .canonical_root() + .map_err(|e| format!("Error computing genesis state root: {e:?}"))?; + + let builder = self.genesis_state(genesis_state.clone())?; + let store = builder.store.clone().ok_or("era_files requires a store.")?; + + // Explicitly store the genesis state in the cold DB. In testing this seems necessary. + // TODO(era): Review why ^ + { + let mut ops = vec![]; + store + .store_cold_state(&genesis_state_root, &genesis_state, &mut ops) + .map_err(|e| format!("Error building genesis state write ops: {e:?}"))?; + store + .cold_db + .do_atomically(ops) + .map_err(|e| format!("Error writing genesis state: {e:?}"))?; + } + + // Import all blocks and states from the ERA files. + let era_dir = EraFileDir::new::(era_files_dir, &builder.spec)?; + let max_era = era_dir.max_era(); + let slots_per_historical_root = E::slots_per_historical_root() as u64; + + let imported_era_files_pointer = store + .get_era_import_pointer() + .map_err(|error| format!("Era import pointer read failed: {error:?}"))? + .unwrap_or(0); + info!( + ?era_files_dir, + max_slot = max_era * slots_per_historical_root, + current_slot = imported_era_files_pointer * slots_per_historical_root, + "Importing blocks and states from ERA files" + ); + let mut import_progress = Speedo::default(); + let mut import_last_log = Instant::now(); + for era_number in imported_era_files_pointer + 1..=max_era { + debug!(?era_files_dir, era_number, "Importing ERA file"); + era_dir.import_era_file(&store, era_number, &builder.spec)?; + debug!(?era_files_dir, era_number, "Imported ERA file"); + store + .set_era_import_pointer(era_number) + .map_err(|error| format!("Era import pointer write failed: {error:?}"))?; + debug!(?era_files_dir, era_number, "Persisted era pointer"); + + let now = Instant::now(); + let done_slots = era_number * slots_per_historical_root; + import_progress.observe(Slot::new(done_slots), now); + if now.duration_since(import_last_log) >= Duration::from_secs(5) { + import_last_log = now; + info!( + completed_era_files = era_number, + total_era_files = max_era, + completed_slots = done_slots, + total_slots = max_era * slots_per_historical_root, + slots_per_second = import_progress.slots_per_second().unwrap_or(0.0), + "Importing era files" + ); + } + } + + info!( + ?era_files_dir, + max_slot = max_era * slots_per_historical_root, + "Reconstructing states from ERA files" + ); + let total_era_files = max_era; + let completed_era_files = Arc::new(AtomicU64::new(0)); + let progress = Arc::new(Mutex::new((Speedo::default(), Instant::now()))); + + (1..=max_era).into_par_iter().try_for_each(|era_number| { + let already_reconstructed = store + .era_reconstruction_done(era_number) + .map_err(|error| format!("Era reconstruction marker read failed: {error:?}"))?; + + if !already_reconstructed { + let start_slot = Slot::new((era_number - 1) * slots_per_historical_root); + let end_slot = Slot::new(era_number * slots_per_historical_root); + store + .reconstruct_historic_states_on_range( + // Start reconstruction with state at the era file start, but the state has the + // block already applied. So start with the block at the next slot. + start_slot, + start_slot + Slot::new(1), + end_slot, + ) + .map_err(|error| { + format!("Era reconstruction failed for era {era_number}: {error:?}") + })?; + + store + .set_era_reconstruction_done(era_number) + .map_err(|error| { + format!("Era reconstruction marker write failed: {error:?}") + })?; + } + + let now = Instant::now(); + let done_era_files = completed_era_files.fetch_add(1, Ordering::Relaxed) + 1; + let done_slots = done_era_files.saturating_mul(slots_per_historical_root); + let mut progress = progress.lock(); + let (speedo, last_log) = &mut *progress; + speedo.observe(Slot::new(done_slots), now); + if now.duration_since(*last_log) >= Duration::from_secs(5) { + *last_log = now; + info!( + completed_era_files = done_era_files, + total_era_files, + completed_slots = done_slots, + total_slots = total_era_files.saturating_mul(slots_per_historical_root), + slots_per_second = speedo.slots_per_second().unwrap_or(0.0), + "Reconstructing from era files" + ); + } + + Ok::<(), String>(()) + })?; + + Ok(builder) + } + /// Sets the store migrator config (optional). pub fn store_migrator_config(mut self, config: MigratorConfig) -> Self { self.store_migrator_config = Some(config); @@ -1240,6 +1371,46 @@ fn build_data_columns_from_blobs( Ok(data_columns) } +/// Track recent slot completion rates for era reconstruction. +#[derive(Default)] +struct Speedo(Vec<(Slot, Instant)>); + +impl Speedo { + fn observe(&mut self, slot: Slot, instant: Instant) { + const SPEEDO_OBSERVATIONS: usize = 4; + if self.0.len() > SPEEDO_OBSERVATIONS { + self.0.remove(0); + } + self.0.push((slot, instant)); + } + + fn slots_per_second(&self) -> Option { + let speeds = self + .0 + .windows(2) + .filter_map(|windows| { + let (slot_a, instant_a) = windows[0]; + let (slot_b, instant_b) = windows[1]; + let distance = f64::from((slot_b - slot_a).as_u64() as u32); + let seconds = f64::from((instant_b - instant_a).as_millis() as u32) / 1_000.0; + if seconds > 0.0 { + Some(distance / seconds) + } else { + None + } + }) + .collect::>(); + + let count = speeds.len(); + let sum: f64 = speeds.iter().sum(); + if count > 0 { + Some(sum / f64::from(count as u32)) + } else { + None + } + } +} + #[cfg(not(debug_assertions))] #[cfg(test)] mod test { diff --git a/beacon_node/beacon_chain/src/era_file_consumer.rs b/beacon_node/beacon_chain/src/era_file_consumer.rs new file mode 100644 index 00000000000..9cbab9ca0bb --- /dev/null +++ b/beacon_node/beacon_chain/src/era_file_consumer.rs @@ -0,0 +1,424 @@ +use bls::FixedBytesExtended; +use rayon::prelude::*; +use reth_era::common::file_ops::StreamReader; +use reth_era::era::file::EraReader; +use reth_era::era::types::consensus::{CompressedBeaconState, CompressedSignedBeaconBlock}; +use std::fs::{self, File}; +use std::path::{Path, PathBuf}; +use store::{DBColumn, HotColdDB, ItemStore, KeyValueStoreOp}; +use tracing::{debug, debug_span, instrument, warn}; +use tree_hash::TreeHash; +use types::{ + BeaconState, ChainSpec, EthSpec, Hash256, HistoricalBatch, HistoricalSummary, + SignedBeaconBlock, Slot, +}; + +fn decode_block( + compressed: CompressedSignedBeaconBlock, + spec: &ChainSpec, +) -> Result, String> { + let bytes = compressed + .decompress() + .map_err(|error| format!("failed to decompress block: {error:?}"))?; + SignedBeaconBlock::from_ssz_bytes(&bytes, spec) + .map_err(|error| format!("failed to decode block: {error:?}")) +} + +fn decode_state( + compressed: CompressedBeaconState, + spec: &ChainSpec, +) -> Result, String> { + let bytes = compressed + .decompress() + .map_err(|error| format!("failed to decompress state: {error:?}"))?; + BeaconState::from_ssz_bytes(&bytes, spec) + .map_err(|error| format!("failed to decode state: {error:?}")) +} + +pub(crate) struct EraFileDir { + dir: PathBuf, + network_name: String, + genesis_validators_root: Hash256, + historical_roots: Vec, + historical_summaries: Vec, + max_era: u64, +} + +impl EraFileDir { + pub(crate) fn new(era_files_dir: &Path, spec: &ChainSpec) -> Result { + let mut era_files = list_era_files(era_files_dir)?; + era_files.sort_by_key(|(era_number, _)| *era_number); + + let network_name = spec + .config_name + .clone() + .unwrap_or_else(|| "unknown".to_string()); + + let Some((max_era, reference_path)) = era_files.last().cloned() else { + return Err("era files directory is empty".to_string()); + }; + + let reference_state = read_era_state::(&reference_path, &network_name, spec)?; + + // historical_roots was frozen in capella, and continued as historical_summaries + let historical_roots = reference_state.historical_roots().to_vec(); + // Pre-Capella states don't have historical_summaries property + let historical_summaries = match reference_state.historical_summaries() { + Ok(list) => list.to_vec(), + Err(_) => vec![], + }; + + let dir = era_files_dir.to_path_buf(); + let era_dir = Self { + dir, + network_name, + genesis_validators_root: reference_state.genesis_validators_root(), + historical_roots, + historical_summaries, + max_era, + }; + + // Verify that every expected era file name exists in the directory. + for era_number in 0..=era_dir.max_era { + let expected = era_dir.expected_path(era_number); + if !expected.exists() { + return Err(format!("missing era file: {expected:?}")); + } + } + + Ok(era_dir) + } + + pub(crate) fn max_era(&self) -> u64 { + self.max_era + } + + #[instrument(level = "debug", skip_all, fields(era_number = %era_number))] + pub(crate) fn import_era_file, Cold: ItemStore>( + &self, + store: &HotColdDB, + era_number: u64, + spec: &ChainSpec, + ) -> Result<(), String> { + let path = self.expected_path(era_number); + debug!(?path, era_number, "Importing era file"); + let file = File::open(path).map_err(|error| format!("failed to open era file: {error}"))?; + let era_file = { + let _span = debug_span!("era_import_read").entered(); + EraReader::new(file) + .read_and_assemble(self.network_name.clone()) + .map_err(|error| format!("failed to parse era file: {error:?}"))? + }; + + // Consistency checks: ensure the era state matches the expected historical root and that + // each block root matches the state block_roots for its slot. + let mut state = { + let _span = debug_span!("era_import_decode_state").entered(); + decode_state::(era_file.group.era_state, spec)? + }; + let expected_root = self + .era_file_name_root(era_number) + .ok_or_else(|| format!("missing historical root for era {era_number}"))?; + let actual_root = era_root_from_state(&state, era_number)?; + if expected_root != actual_root { + return Err(format!( + "era root mismatch for era {era_number}: expected {expected_root:?}, got {actual_root:?}" + )); + } + + let slots_per_historical_root = E::slots_per_historical_root() as u64; + let _start_slot = Slot::new(era_number.saturating_sub(1) * slots_per_historical_root); + let end_slot = Slot::new(era_number * slots_per_historical_root); + if state.slot() != end_slot { + return Err(format!( + "era state slot mismatch: expected {end_slot}, got {}", + state.slot() + )); + } + + let historical_summaries_active_at_slot = match store.spec.capella_fork_epoch { + // For mainnet case, Capella activates at 194048 epoch = 6209536 slot = 758 era number. + // The last epoch processing before capella transition adds a last entry to historical + // roots. So historical_roots.len() == 758 at the capella fork boundary. An ERA file + // includes the state AFTER advanced (or applying) the block at the final slot, so the + // state for ERA file 758 is of the Capella variant. However, historical summaries are + // still empty. + Some(epoch) => { + epoch.start_slot(E::slots_per_epoch()) + + Slot::new(E::slots_per_historical_root() as u64) + } + None => Slot::max_value(), + }; + + // Check that the block roots vector in this state match the historical summary in the last + // state. Asserts that the blocks are exactly the expected ones given a trusted final state + if era_number == 0 { + // Skip checking genesis state era file for now + } else if state.slot() >= historical_summaries_active_at_slot { + // Post-capella state, check against historical summaries + // ```py + // historical_summary = HistoricalSummary( + // block_summary_root=hash_tree_root(state.block_roots), + // state_summary_root=hash_tree_root(state.state_roots), + // ) + // state.historical_summaries.append(historical_summary) + // ``` + let index = era_number.saturating_sub(1) as usize; + // historical_summaries started to be appended after capella, so we need to offset + let summary_index = index + .checked_sub(self.historical_roots.len()) + .ok_or_else(|| format!( + "Not enough historical roots era number {era_number} index {index} historical_roots len {}", + self.historical_roots.len() + ))?; + let expected_root = self + .historical_summaries + .get(summary_index) + .ok_or_else(|| format!("missing historical summary for era {era_number}"))? + .block_summary_root(); + let actual_root = state.block_roots().tree_hash_root(); + if actual_root != expected_root { + return Err(format!( + "block summary root post-capella mismatch for era {}: {:?} != {:?}", + era_number, expected_root, actual_root + )); + } + } else { + // Pre-capella state, check against historical roots + // ```py + // historical_batch = HistoricalBatch(block_roots=state.block_roots, state_roots=state.state_roots) + // state.historical_roots.append(hash_tree_root(historical_batch)) + // ``` + let index = era_number.saturating_sub(1) as usize; + let expected_root = *self + .historical_roots + .get(index) + .ok_or_else(|| format!("missing historical root for era {era_number}"))?; + let historical_batch = HistoricalBatch:: { + block_roots: state.block_roots().clone(), + state_roots: state.state_roots().clone(), + }; + let actual_root = historical_batch.tree_hash_root(); + if actual_root != expected_root { + return Err(format!( + "block summary root pre-capella mismatch for era {}: {:?} != {:?}", + era_number, expected_root, actual_root + )); + } + } + + debug!(era_number, "Importing blocks from era file"); + // TODO(era): Block signatures are not verified here and are trusted. + // decode and hash is split in two loops to track timings better. If we add spans for each + // block it's too short and the data is not really useful. + let decoded_blocks = { + let _span = debug_span!("era_import_decode_blocks").entered(); + era_file + .group + .blocks + .into_par_iter() + .map(|compressed_block| decode_block::(compressed_block, spec)) + .collect::, _>>()? + }; + let blocks_with_roots = { + let _span = debug_span!("era_import_hash_blocks").entered(); + decoded_blocks + .into_par_iter() + .map(|block| (block.canonical_root(), block)) + .collect::>() + }; + + let mut block_ops = vec![]; + { + let _ = debug_span!("era_import_db_ops_blocks").entered(); + for (block_root, block) in blocks_with_roots { + let slot = block.slot(); + // Check consistency that this block is expected w.r.t. the state in the era file. + // Since we check that the state block roots match the historical summary, we know that + // this block root is the expected one. + let expected_block_root = state + .get_block_root(slot) + .map_err(|error| format!("failed to read block root {slot}: {error:?}"))?; + if *expected_block_root != block_root { + return Err(format!( + "block root mismatch at slot {slot}: expected {expected_block_root:?}, got {block_root:?}" + )); + } + store + .block_as_kv_store_ops(&block_root, block, &mut block_ops) + .map_err(|error| format!("failed to store block: {error:?}"))?; + } + } + { + let _ = debug_span!("era_import_write_blocks").entered(); + store + .hot_db + .do_atomically(block_ops) + .map_err(|error| format!("failed to store blocks: {error:?}"))?; + } + + // Populate the cold DB slot -> block root index from the state.block_roots() + { + let _span = debug_span!("era_import_write_block_index").entered(); + write_block_root_index_for_era(store, &state, era_number)?; + } + + debug!(era_number, "Importing state from era file"); + { + let _span = debug_span!("era_import_write_state").entered(); + let state_root = state + .canonical_root() + .map_err(|error| format!("failed to hash state: {error:?}"))?; + // Use put_cold_state as the split is not updated and we need the state into the cold store. + store + .put_cold_state(&state_root, &state) + .map_err(|error| format!("failed to store state: {error:?}"))?; + } + Ok(()) + } + + fn expected_path(&self, era_number: u64) -> PathBuf { + let root = self + .era_file_name_root(era_number) + .unwrap_or_else(Hash256::zero); + let short = root + .as_slice() + .iter() + .take(4) + .map(|byte| format!("{byte:02x}")) + .collect::(); + let filename = format!("{}-{era_number:05}-{short}.era", self.network_name); + self.dir.join(filename) + } + + // era_file_name_root for file naming: + // short-era-root is the first 4 bytes of the last historical root in the last state in the + // era file, lower-case hex-encoded (8 characters), except the genesis era which instead + // uses the genesis_validators_root field from the genesis state. + // - The root is available as state.historical_roots[era - 1] except for genesis, which is + // state.genesis_validators_root + // - Post-Capella, the root must be computed from + // `state.historical_summaries[era - state.historical_roots.len - 1]` + fn era_file_name_root(&self, era_number: u64) -> Option { + if era_number == 0 { + return Some(self.genesis_validators_root); + } + let index = era_number.saturating_sub(1) as usize; + if let Some(root) = self.historical_roots.get(index) { + return Some(*root); + } + let summary_index = index.saturating_sub(self.historical_roots.len()); + self.historical_summaries + .get(summary_index) + .map(|summary| summary.tree_hash_root()) + } +} + +fn read_era_state( + path: &Path, + network_name: &str, + spec: &ChainSpec, +) -> Result, String> { + let file = File::open(path).map_err(|error| format!("failed to open era file: {error}"))?; + let era_file = EraReader::new(file) + .read_and_assemble(network_name.to_string()) + .map_err(|error| format!("failed to parse era file: {error:?}"))?; + decode_state::(era_file.group.era_state, spec) +} + +fn era_root_from_state( + state: &BeaconState, + era_number: u64, +) -> Result { + if era_number == 0 { + return Ok(state.genesis_validators_root()); + } + let index = era_number + .checked_sub(1) + .ok_or_else(|| "invalid era number".to_string())? as usize; + if let Some(root) = state.historical_roots().get(index) { + return Ok(*root); + } + if let Ok(summaries) = state.historical_summaries() { + let summary_index = index.saturating_sub(state.historical_roots().len()); + let summary = summaries + .get(summary_index) + .ok_or_else(|| "missing historical summary".to_string())?; + return Ok(summary.tree_hash_root()); + } + Err(format!("missing historical root for era {era_number}")) +} + +fn write_block_root_index_for_era, Cold: ItemStore>( + store: &HotColdDB, + state: &BeaconState, + era_number: u64, +) -> Result<(), String> { + let end_slot = state.slot(); + let slots_per_historical_root = E::slots_per_historical_root() as u64; + let expected_end_slot = Slot::new(era_number * slots_per_historical_root); + if end_slot != expected_end_slot { + return Err(format!( + "era state slot mismatch: expected {expected_end_slot}, got {end_slot}" + )); + } + + let start_slot = end_slot.saturating_sub(slots_per_historical_root); + + let ops = (start_slot.as_u64()..end_slot.as_u64()) + .map(|slot_u64| { + let slot = Slot::new(slot_u64); + let block_root = state + .get_block_root(slot) + .map_err(|error| format!("failed to read block root {slot}: {error:?}"))?; + // TODO(era): Should we write BeaconBlockRoots for missed slots? + Ok(KeyValueStoreOp::PutKeyValue( + DBColumn::BeaconBlockRoots, + slot_u64.to_be_bytes().to_vec(), + block_root.as_slice().to_vec(), + )) + }) + .collect::, String>>()?; + + store + .cold_db + .do_atomically(ops) + .map_err(|error| format!("failed to store block root index: {error:?}"))?; + + Ok(()) +} + +fn list_era_files(dir: &Path) -> Result, String> { + let entries = fs::read_dir(dir).map_err(|error| format!("failed to read era dir: {error}"))?; + let mut era_files = Vec::new(); + + for entry in entries { + let entry = entry.map_err(|error| format!("failed to read era entry: {error}"))?; + let path = entry.path(); + let Some(file_name) = path.file_name().and_then(|name| name.to_str()) else { + continue; + }; + + if !file_name.ends_with(".era") { + continue; + } + + let Some((prefix, _hash_part)) = file_name.rsplit_once('-') else { + continue; + }; + let Some((_network_name, era_part)) = prefix.rsplit_once('-') else { + continue; + }; + let Some(era_number) = era_part.parse().ok() else { + continue; + }; + + era_files.push((era_number, path)); + } + + if era_files.is_empty() { + warn!(?dir, "Era files directory is empty"); + } + + Ok(era_files) +} diff --git a/beacon_node/beacon_chain/src/lib.rs b/beacon_node/beacon_chain/src/lib.rs index e77739e2d53..fb1c0ecdecd 100644 --- a/beacon_node/beacon_chain/src/lib.rs +++ b/beacon_node/beacon_chain/src/lib.rs @@ -20,6 +20,7 @@ pub mod custody_context; pub mod data_availability_checker; pub mod data_column_verification; mod early_attester_cache; +mod era_file_consumer; mod errors; pub mod events; pub mod execution_payload; diff --git a/beacon_node/client/src/builder.rs b/beacon_node/client/src/builder.rs index 1b395ac8da5..5f007b286e2 100644 --- a/beacon_node/client/src/builder.rs +++ b/beacon_node/client/src/builder.rs @@ -248,7 +248,12 @@ where ClientGenesis::DepositContract } else if chain_exists { - if matches!(client_genesis, ClientGenesis::WeakSubjSszBytes { .. }) + if matches!(client_genesis, ClientGenesis::EraFiles { .. }) { + info!( + msg = "database already exists, use --purge-db to force era import", + "Refusing to import era files" + ); + } else if matches!(client_genesis, ClientGenesis::WeakSubjSszBytes { .. }) || matches!(client_genesis, ClientGenesis::CheckpointSyncUrl { .. }) { info!( @@ -460,6 +465,11 @@ where return Err("Loading genesis from deposit contract no longer supported".to_string()); } ClientGenesis::FromStore => builder.resume_from_db()?, + ClientGenesis::EraFiles { era_files_dir } => { + info!(?era_files_dir, "Importing era files"); + let genesis_state = genesis_state(&runtime_context, &config).await?; + builder.era_files(&era_files_dir, genesis_state)? + } }; self.beacon_chain_builder = Some(beacon_chain_builder); diff --git a/beacon_node/client/src/config.rs b/beacon_node/client/src/config.rs index aeaa196df86..db5ad0d217a 100644 --- a/beacon_node/client/src/config.rs +++ b/beacon_node/client/src/config.rs @@ -45,6 +45,9 @@ pub enum ClientGenesis { CheckpointSyncUrl { url: SensitiveUrl, }, + EraFiles { + era_files_dir: PathBuf, + }, } /// The core configuration of a Lighthouse beacon node. diff --git a/beacon_node/lighthouse_network/src/config.rs b/beacon_node/lighthouse_network/src/config.rs index cb94bfff22b..8f45da2926d 100644 --- a/beacon_node/lighthouse_network/src/config.rs +++ b/beacon_node/lighthouse_network/src/config.rs @@ -118,6 +118,8 @@ pub struct Config { /// Whether we are running a block proposer only node. pub proposer_only: bool, + /// Optional directory containing `.era` files for backfill. + pub era_files_dir: Option, /// Whether metrics are enabled. pub metrics_enabled: bool, @@ -357,6 +359,7 @@ impl Default for Config { shutdown_after_sync: false, topics: Vec::new(), proposer_only: false, + era_files_dir: None, metrics_enabled: false, enable_light_client_server: true, outbound_rate_limiter_config: None, diff --git a/beacon_node/network/Cargo.toml b/beacon_node/network/Cargo.toml index 78dc0c48a75..b7d36b880d6 100644 --- a/beacon_node/network/Cargo.toml +++ b/beacon_node/network/Cargo.toml @@ -35,6 +35,7 @@ metrics = { workspace = true } operation_pool = { workspace = true } parking_lot = { workspace = true } rand = { workspace = true } +reth-era = { workspace = true } slot_clock = { workspace = true } smallvec = { workspace = true } ssz_types = { workspace = true } diff --git a/beacon_node/network/src/network_beacon_processor/sync_methods.rs b/beacon_node/network/src/network_beacon_processor/sync_methods.rs index a6b3ea9e4b1..55bd523c892 100644 --- a/beacon_node/network/src/network_beacon_processor/sync_methods.rs +++ b/beacon_node/network/src/network_beacon_processor/sync_methods.rs @@ -613,16 +613,7 @@ impl NetworkBeaconProcessor { process_id: ChainSegmentProcessId, downloaded_blocks: Vec>, ) { - let ChainSegmentProcessId::BackSyncBatchId(epoch) = process_id else { - // this a request from RangeSync, this should _never_ happen - crit!( - error = - "process_chain_segment_backfill called on a variant other than BackSyncBatchId", - "Please notify the devs" - ); - return; - }; - + let block_count = downloaded_blocks.len(); let start_slot = downloaded_blocks.first().map(|b| b.slot().as_u64()); let end_slot = downloaded_blocks.last().map(|b| b.slot().as_u64()); let sent_blocks = downloaded_blocks.len(); @@ -638,15 +629,16 @@ impl NetworkBeaconProcessor { let result = match self.process_backfill_blocks(downloaded_blocks) { (imported_blocks, Ok(_)) => { debug!( - batch_epoch = %epoch, - first_block_slot = start_slot, - keep_execution_payload = !self.chain.store.get_config().prune_payloads, - last_block_slot = end_slot, - processed_blocks = sent_blocks, - processed_blobs = n_blobs, - processed_data_columns = n_data_columns, - service= "sync", - "Backfill batch processed"); + block_count, + first_block_slot = start_slot, + keep_execution_payload = !self.chain.store.get_config().prune_payloads, + last_block_slot = end_slot, + processed_blocks = sent_blocks, + processed_blobs = n_blobs, + processed_data_columns = n_data_columns, + service = "sync", + "Backfill batch processed" + ); BatchProcessResult::Success { sent_blocks, imported_blocks, @@ -654,7 +646,7 @@ impl NetworkBeaconProcessor { } (_, Err(e)) => { debug!( - batch_epoch = %epoch, + block_count, first_block_slot = start_slot, last_block_slot = end_slot, processed_blobs = n_blobs, diff --git a/beacon_node/src/cli.rs b/beacon_node/src/cli.rs index 9553fe60ba2..8e6475f7f5b 100644 --- a/beacon_node/src/cli.rs +++ b/beacon_node/src/cli.rs @@ -414,6 +414,15 @@ pub fn cli_app() -> Command { .help_heading(FLAG_HEADER) .display_order(0) ) + .arg( + Arg::new("era-files-dir") + .long("era-files-dir") + .value_name("DIR") + .help("Directory containing `.era` files to use for backfill.") + .action(ArgAction::Set) + .help_heading(FLAG_HEADER) + .display_order(0) + ) .arg( Arg::new("complete-blob-backfill") .long("complete-blob-backfill") diff --git a/beacon_node/src/config.rs b/beacon_node/src/config.rs index 752cf105505..f8d748cbcae 100644 --- a/beacon_node/src/config.rs +++ b/beacon_node/src/config.rs @@ -808,6 +808,14 @@ pub fn get_config( client_config.chain.genesis_backfill = true; } + if let Some(dir) = clap_utils::parse_optional::(cli_args, "era-files-dir")? { + let path = PathBuf::from(dir); + client_config.store.era_files_dir = Some(path.clone()); + client_config.genesis = ClientGenesis::EraFiles { + era_files_dir: path, + }; + } + client_config.chain.complete_blob_backfill = cli_args.get_flag("complete-blob-backfill"); // Ensure `prune_blobs` is false whenever complete-blob-backfill is set. This overrides any diff --git a/beacon_node/store/src/config.rs b/beacon_node/store/src/config.rs index 29705283fa9..99b2d10e407 100644 --- a/beacon_node/store/src/config.rs +++ b/beacon_node/store/src/config.rs @@ -5,6 +5,7 @@ use ssz::{Decode, Encode}; use ssz_derive::{Decode, Encode}; use std::io::{Read, Write}; use std::num::NonZeroUsize; +use std::path::PathBuf; use strum::{Display, EnumString, VariantNames}; use superstruct::superstruct; use types::EthSpec; @@ -64,6 +65,8 @@ pub struct StoreConfig { /// The margin for blob pruning in epochs. The oldest blobs are pruned up until /// data_availability_boundary - blob_prune_margin_epochs. Default: 0. pub blob_prune_margin_epochs: u64, + /// Optional path for era file import/production. + pub era_files_dir: Option, } /// Variant of `StoreConfig` that gets written to disk. Contains immutable configuration params. @@ -120,6 +123,7 @@ impl Default for StoreConfig { prune_blobs: true, epochs_per_blob_prune: DEFAULT_EPOCHS_PER_BLOB_PRUNE, blob_prune_margin_epochs: DEFAULT_BLOB_PUNE_MARGIN_EPOCHS, + era_files_dir: None, } } } diff --git a/beacon_node/store/src/hot_cold_store.rs b/beacon_node/store/src/hot_cold_store.rs index 6e165702a27..44b952233a7 100644 --- a/beacon_node/store/src/hot_cold_store.rs +++ b/beacon_node/store/src/hot_cold_store.rs @@ -88,6 +88,16 @@ pub struct HotColdDB, Cold: ItemStore> { _phantom: PhantomData, } +fn era_import_pointer_key() -> &'static [u8] { + b"era_import_ptr" +} + +fn era_reconstruction_key(era_number: u64) -> Vec { + let mut key = b"era_recon:".to_vec(); + key.extend_from_slice(&era_number.to_be_bytes()); + key +} + #[derive(Debug)] struct BlockCache { block_cache: LruCache>, @@ -196,7 +206,7 @@ pub enum HotColdDBError { RestorePointDecodeError(ssz::DecodeError), BlockReplayBeaconError(BeaconStateError), BlockReplaySlotError(SlotProcessingError), - BlockReplayBlockError(BlockProcessingError), + BlockReplayBlockError(Slot, BlockProcessingError), InvalidSlotsPerRestorePoint { slots_per_restore_point: u64, slots_per_historical_root: u64, @@ -1092,6 +1102,17 @@ impl, Cold: ItemStore> HotColdDB } } + /// Store and commit a state into the cold db store. + pub fn put_cold_state( + &self, + state_root: &Hash256, + state: &BeaconState, + ) -> Result<(), Error> { + let mut ops: Vec = Vec::new(); + self.store_cold_state(state_root, state, &mut ops)?; + self.cold_db.do_atomically(ops) + } + /// Fetch a state from the store. /// /// If `slot` is provided then it will be used as a hint as to which database should @@ -2084,31 +2105,16 @@ impl, Cold: ItemStore> HotColdDB self.store_cold_state_summary(state_root, state.slot(), ops)?; let slot = state.slot(); - match self.cold_storage_strategy(slot)? { - StorageStrategy::ReplayFrom(from) => { - debug!( - strategy = "replay", - from_slot = %from, - %slot, - "Storing cold state", - ); + let strategy = self.cold_storage_strategy(slot)?; + debug!(?strategy, %slot, "Storing cold state"); + match strategy { + StorageStrategy::ReplayFrom(_) => { // Already have persisted the state summary, don't persist anything else } StorageStrategy::Snapshot => { - debug!( - strategy = "snapshot", - %slot, - "Storing cold state" - ); self.store_cold_state_as_snapshot(state, ops)?; } StorageStrategy::DiffFrom(from) => { - debug!( - strategy = "diff", - from_slot = %from, - %slot, - "Storing cold state" - ); self.store_cold_state_as_diff(state, from, ops)?; } } @@ -3137,6 +3143,41 @@ impl, Cold: ItemStore> HotColdDB self.config.compact_on_prune } + pub fn get_era_import_pointer(&self) -> Result, Error> { + let Some(bytes) = self + .hot_db + .get_bytes(DBColumn::BeaconMeta, era_import_pointer_key())? + else { + return Ok(None); + }; + let bytes: [u8; 8] = bytes + .as_slice() + .try_into() + .map_err(|_| Error::InvalidBytes)?; + Ok(Some(u64::from_be_bytes(bytes))) + } + + pub fn set_era_import_pointer(&self, era_number: u64) -> Result<(), Error> { + self.hot_db.put_bytes( + DBColumn::BeaconMeta, + era_import_pointer_key(), + &era_number.to_be_bytes(), + ) + } + + pub fn era_reconstruction_done(&self, era_number: u64) -> Result { + self.hot_db + .key_exists(DBColumn::BeaconMeta, &era_reconstruction_key(era_number)) + } + + pub fn set_era_reconstruction_done(&self, era_number: u64) -> Result<(), Error> { + self.hot_db.put_bytes( + DBColumn::BeaconMeta, + &era_reconstruction_key(era_number), + &[1u8], + ) + } + /// Load the timestamp of the last compaction as a `Duration` since the UNIX epoch. pub fn load_compaction_timestamp(&self) -> Result, Error> { Ok(self diff --git a/beacon_node/store/src/reconstruct.rs b/beacon_node/store/src/reconstruct.rs index 7aca692ef9b..5f20dcb161c 100644 --- a/beacon_node/store/src/reconstruct.rs +++ b/beacon_node/store/src/reconstruct.rs @@ -1,15 +1,16 @@ //! Implementation of historic state reconstruction (given complete block history). +use crate::forwards_iter::FrozenForwardsIterator; use crate::hot_cold_store::{HotColdDB, HotColdDBError}; -use crate::metrics; +use crate::{DBColumn, KeyValueStoreOp, metrics}; use crate::{Error, ItemStore}; -use itertools::{Itertools, process_results}; +use itertools::process_results; use state_processing::{ BlockSignatureStrategy, ConsensusContext, VerifyBlockRoot, per_block_processing, per_slot_processing, }; use std::sync::Arc; use tracing::{debug, info}; -use types::EthSpec; +use types::{EthSpec, Slot}; impl HotColdDB where @@ -53,40 +54,103 @@ where return Ok(()); } - // If `num_blocks` is not specified iterate all blocks. Add 1 so that we end on an epoch - // boundary when `num_blocks` is a multiple of an epoch boundary. We want to be *inclusive* - // of the state at slot `lower_limit_slot + num_blocks`. - let block_root_iter = self - .forwards_block_roots_iterator_until(lower_limit_slot, upper_limit_slot - 1, || { - Err(Error::StateShouldNotBeRequired(upper_limit_slot - 1)) - })? - .take(num_blocks.map_or(usize::MAX, |n| n + 1)); + let from_slot = lower_limit_slot; + let to_slot = if let Some(num_blocks) = num_blocks { + std::cmp::min(upper_limit_slot, from_slot + Slot::new(num_blocks as u64)) + } else { + upper_limit_slot + }; + + self.reconstruct_historic_states_on_range(from_slot, from_slot, to_slot)?; + + let remaining = upper_limit_slot + .as_u64() + .saturating_sub(1) + .saturating_sub(to_slot.as_u64()); + info!( + slot = %to_slot, + remaining = %remaining, + "State reconstruction in progress" + ); + + // Update anchor. + let old_anchor = anchor.clone(); + + let reconstruction_complete = to_slot == upper_limit_slot; + if reconstruction_complete { + let new_anchor = old_anchor.as_archive_anchor(); + self.compare_and_set_anchor_info_with_write(old_anchor, new_anchor)?; + + return Ok(()); + } else { + // The lower limit has been raised, store it. + anchor.state_lower_limit = to_slot; + + self.compare_and_set_anchor_info_with_write(old_anchor, anchor.clone())?; + } + + // Check that the split point wasn't mutated during the state reconstruction process. + // It shouldn't have been, due to the serialization of requests through the store migrator, + // so this is just a paranoid check. + let latest_split = self.get_split_info(); + if split != latest_split { + return Err(Error::SplitPointModified(latest_split.slot, split.slot)); + } + + Ok(()) + } + + pub fn reconstruct_historic_states_on_range( + self: &Arc, + with_state_at_slot: Slot, + from_slot: Slot, + to_slot: Slot, + ) -> Result<(), Error> { + debug!( + %from_slot, + %to_slot, + "Starting state reconstruction batch" + ); + + let _t = metrics::start_timer(&metrics::STORE_BEACON_RECONSTRUCTION_TIME); + + let block_root_iter = + FrozenForwardsIterator::new(self, DBColumn::BeaconBlockRoots, from_slot, to_slot)?; // The state to be advanced. - let mut state = self.load_cold_state_by_slot(lower_limit_slot)?; + let mut state = self.load_cold_state_by_slot(with_state_at_slot)?; state.build_caches(&self.spec)?; process_results(block_root_iter, |iter| -> Result<(), Error> { let mut io_batch = vec![]; - let mut prev_state_root = None; - for ((prev_block_root, _), (block_root, slot)) in iter.tuple_windows() { - let is_skipped_slot = prev_block_root == block_root; - - let block = if is_skipped_slot { - None - } else { - Some( - self.get_blinded_block(&block_root)? - .ok_or(Error::BlockNotFound(block_root))?, - ) + for (block_root, slot) in iter { + io_batch.push(KeyValueStoreOp::PutKeyValue( + DBColumn::BeaconBlockRoots, + slot.as_u64().to_be_bytes().to_vec(), + block_root.as_slice().to_vec(), + )); + + let block = { + let block = self + .get_blinded_block(&block_root)? + .ok_or(Error::BlockNotFound(block_root))?; + if block.slot() == slot && block.slot() > self.spec.genesis_slot { + // If block.slot != slot means it's a skipped slot. + // Also skip applying the genesis slot. + Some(block) + } else { + None + } }; // Advance state to slot. - per_slot_processing(&mut state, prev_state_root.take(), &self.spec) - .map_err(HotColdDBError::BlockReplaySlotError)?; + while state.slot() < slot { + per_slot_processing(&mut state, prev_state_root.take(), &self.spec) + .map_err(HotColdDBError::BlockReplaySlotError)?; + } // Apply block. if let Some(block) = block { @@ -102,7 +166,7 @@ where &mut ctxt, &self.spec, ) - .map_err(HotColdDBError::BlockReplayBlockError)?; + .map_err(|e| HotColdDBError::BlockReplayBlockError(block.slot(), e))?; prev_state_root = Some(block.state_root()); } @@ -114,58 +178,21 @@ where // Stage state for storage in freezer DB. self.store_cold_state(&state_root, &state, &mut io_batch)?; - let batch_complete = - num_blocks.is_some_and(|n_blocks| slot == lower_limit_slot + n_blocks as u64); - let reconstruction_complete = slot + 1 == upper_limit_slot; + let batch_complete = slot + 1 == to_slot; // Commit the I/O batch if: // // - The diff/snapshot for this slot is required for future slots, or // - The reconstruction batch is complete (we are about to return), or // - Reconstruction is complete. - if self.hierarchy.should_commit_immediately(slot)? - || batch_complete - || reconstruction_complete - { - info!( - %slot, - remaining = %(upper_limit_slot - 1 - slot), - "State reconstruction in progress" - ); - + if self.hierarchy.should_commit_immediately(slot)? || batch_complete { self.cold_db.do_atomically(std::mem::take(&mut io_batch))?; - // Update anchor. - let old_anchor = anchor.clone(); - - if reconstruction_complete { - // The two limits have met in the middle! We're done! - // Perform one last integrity check on the state reached. - let computed_state_root = state.update_tree_hash_cache()?; - if computed_state_root != state_root { - return Err(Error::StateReconstructionRootMismatch { - slot, - expected: state_root, - computed: computed_state_root, - }); - } - - let new_anchor = old_anchor.as_archive_anchor(); - self.compare_and_set_anchor_info_with_write(old_anchor, new_anchor)?; - - return Ok(()); - } else { - // The lower limit has been raised, store it. - anchor.state_lower_limit = slot; - - self.compare_and_set_anchor_info_with_write(old_anchor, anchor.clone())?; - } - // If this is the end of the batch, return Ok. The caller will run another // batch when there is idle capacity. if batch_complete { debug!( - start_slot = %lower_limit_slot, + start_slot = %from_slot, end_slot = %slot, "Finished state reconstruction batch" ); @@ -179,14 +206,6 @@ where Err(Error::StateReconstructionLogicError) })??; - // Check that the split point wasn't mutated during the state reconstruction process. - // It shouldn't have been, due to the serialization of requests through the store migrator, - // so this is just a paranoid check. - let latest_split = self.get_split_info(); - if split != latest_split { - return Err(Error::SplitPointModified(latest_split.slot, split.slot)); - } - Ok(()) } } diff --git a/book/src/help_bn.md b/book/src/help_bn.md index d3aa27c8a77..03e6747d97c 100644 --- a/book/src/help_bn.md +++ b/book/src/help_bn.md @@ -496,6 +496,8 @@ Flags: --enable-private-discovery Lighthouse by default does not discover private IP addresses. Set this flag to enable connection attempts to local addresses. + --era-files-dir + Directory containing `.era` files to use for backfill. --genesis-backfill Attempts to download blocks all the way back to genesis when checkpoint syncing. diff --git a/consensus/state_processing/src/per_block_processing.rs b/consensus/state_processing/src/per_block_processing.rs index 1de5083f6f3..4ec2249ce48 100644 --- a/consensus/state_processing/src/per_block_processing.rs +++ b/consensus/state_processing/src/per_block_processing.rs @@ -221,7 +221,10 @@ pub fn process_block_header( // Verify that the slots match verify!( block_header.slot == state.slot(), - HeaderInvalid::StateSlotMismatch + HeaderInvalid::StateSlotMismatch { + state: state.slot(), + header: block_header.slot, + } ); // Verify that the block is newer than the latest block header diff --git a/consensus/state_processing/src/per_block_processing/errors.rs b/consensus/state_processing/src/per_block_processing/errors.rs index 5c1db9d732e..124cef1c665 100644 --- a/consensus/state_processing/src/per_block_processing/errors.rs +++ b/consensus/state_processing/src/per_block_processing/errors.rs @@ -277,7 +277,10 @@ impl From for BlockOperationError { #[derive(Debug, PartialEq, Clone)] pub enum HeaderInvalid { ProposalSignatureInvalid, - StateSlotMismatch, + StateSlotMismatch { + state: Slot, + header: Slot, + }, OlderThanLatestBlockHeader { latest_block_header_slot: Slot, block_slot: Slot, diff --git a/consensus/state_processing/src/per_block_processing/tests.rs b/consensus/state_processing/src/per_block_processing/tests.rs index 739717b33ff..c07c464f9e0 100644 --- a/consensus/state_processing/src/per_block_processing/tests.rs +++ b/consensus/state_processing/src/per_block_processing/tests.rs @@ -107,12 +107,12 @@ async fn invalid_block_header_state_slot() { &spec, ); - assert_eq!( + assert!(matches!( result, Err(BlockProcessingError::HeaderInvalid { - reason: HeaderInvalid::StateSlotMismatch + reason: HeaderInvalid::StateSlotMismatch { .. } }) - ); + )); } #[tokio::test] diff --git a/consensus/types/src/state/historical_summary.rs b/consensus/types/src/state/historical_summary.rs index f520e464837..eca28b88fb0 100644 --- a/consensus/types/src/state/historical_summary.rs +++ b/consensus/types/src/state/historical_summary.rs @@ -47,4 +47,8 @@ impl HistoricalSummary { state_summary_root: state.state_roots().tree_hash_root(), } } + + pub fn block_summary_root(&self) -> Hash256 { + self.block_summary_root + } }