diff --git a/Cargo.lock b/Cargo.lock index 54ed12b176..7bf7092595 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -178,54 +178,35 @@ checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" [[package]] name = "alloy-consensus" -version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy.git?rev=974d488bab5e21e9f17452a39a4bfa56677367b2#974d488bab5e21e9f17452a39a4bfa56677367b2" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f58047cc851e58c26224521d1ecda466e3d746ebca0274cd5427aa660a88c353" dependencies = [ "alloy-eips", - "alloy-network", "alloy-primitives", "alloy-rlp", + "c-kzg", ] [[package]] name = "alloy-eips" -version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy.git?rev=974d488bab5e21e9f17452a39a4bfa56677367b2#974d488bab5e21e9f17452a39a4bfa56677367b2" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d32a3e14fa0d152d00bd8daf605eb74ad397efb0f54bd7155585823dddb4401e" dependencies = [ "alloy-primitives", "alloy-rlp", + "c-kzg", + "once_cell", "serde", - "thiserror", -] - -[[package]] -name = "alloy-json-rpc" -version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy.git?rev=974d488bab5e21e9f17452a39a4bfa56677367b2#974d488bab5e21e9f17452a39a4bfa56677367b2" -dependencies = [ - "alloy-primitives", - "serde", - "serde_json", - "thiserror", -] - -[[package]] -name = "alloy-network" -version = "0.1.0" -source = "git+https://github.com/alloy-rs/alloy.git?rev=974d488bab5e21e9f17452a39a4bfa56677367b2#974d488bab5e21e9f17452a39a4bfa56677367b2" -dependencies = [ - "alloy-eips", - "alloy-json-rpc", - "alloy-primitives", - "alloy-rlp", - "serde", + "sha2 0.10.8", ] [[package]] name = "alloy-primitives" -version = "0.6.4" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "600d34d8de81e23b6d909c094e23b3d357e01ca36b78a8c5424c501eedbe86f0" +checksum = "ccb3ead547f4532bc8af961649942f0b9c16ee9226e26caa3f38420651cc0bf4" dependencies = [ "alloy-rlp", "bytes", @@ -245,9 +226,9 @@ dependencies = [ [[package]] name = "alloy-rlp" -version = "0.3.5" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b155716bab55763c95ba212806cf43d05bcc70e5f35b02bad20cf5ec7fe11fed" +checksum = "a43b18702501396fa9bcdeecd533bc85fac75150d308fc0f6800a01e6234a003" dependencies = [ "alloy-rlp-derive", "arrayvec", @@ -256,13 +237,13 @@ dependencies = [ [[package]] name = "alloy-rlp-derive" -version = "0.3.5" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8037e03c7f462a063f28daec9fda285a9a89da003c552f8637a80b9c8fd96241" +checksum = "d83524c1f6162fcb5b0decf775498a125066c86dda6066ed609531b0e912f85a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.72", ] [[package]] @@ -318,9 +299,9 @@ dependencies = [ [[package]] name = "anstyle-query" -version = "1.0.3" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a64c907d4e79225ac72e2a354c9ce84d50ebb4586dee56c82b3ee73004f537f5" +checksum = "ad186efb764318d35165f1758e7dcef3b10628e26d41a44bc5550652e6804391" dependencies = [ "windows-sys 0.52.0", ] @@ -395,7 +376,7 @@ dependencies = [ "ark-std 0.4.0", "derivative", "digest 0.10.7", - "itertools", + "itertools 0.10.5", "num-bigint", "num-traits", "paste", @@ -497,9 +478,9 @@ checksum = "7d902e3d592a523def97af8f317b08ce16b7ab854c1985a0c671e6f15cebc236" [[package]] name = "arrayref" -version = "0.3.7" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" +checksum = "9d151e35f61089500b617991b791fc8bfd237ae50cd5950803758a179b41e67a" [[package]] name = "arrayvec" @@ -531,7 +512,7 @@ checksum = "7378575ff571966e99a744addeff0bff98b8ada0dedf1956d59e634db95eaac1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.72", "synstructure", ] @@ -543,7 +524,7 @@ checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.72", ] [[package]] @@ -565,9 +546,9 @@ dependencies = [ [[package]] name = "async-io" -version = "2.3.2" +version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcccb0f599cfa2f8ace422d3555572f47424da5648a4382a9dd0310ff8210884" +checksum = "0d6baa8f0178795da0e71bc42c9e5d13261aac7ee549853162e66a241ba17964" dependencies = [ "async-lock", "cfg-if", @@ -584,24 +565,24 @@ dependencies = [ [[package]] name = "async-lock" -version = "3.3.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d034b430882f8381900d3fe6f0aaa3ad94f2cb4ac519b429692a1bc2dda4ae7b" +checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" dependencies = [ - "event-listener 4.0.3", + "event-listener 5.3.1", "event-listener-strategy", "pin-project-lite", ] [[package]] name = "async-trait" -version = "0.1.80" +version = "0.1.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" +checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.72", ] [[package]] @@ -671,7 +652,7 @@ checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.72", ] [[package]] @@ -691,9 +672,9 @@ dependencies = [ "bytes", "futures-util", "http 1.1.0", - "http-body 1.0.0", + "http-body 1.0.1", "http-body-util", - "hyper 1.3.1", + "hyper 1.4.1", "hyper-util", "itoa", "matchit", @@ -724,7 +705,7 @@ dependencies = [ "bytes", "futures-util", "http 1.1.0", - "http-body 1.0.0", + "http-body 1.0.1", "http-body-util", "mime", "pin-project-lite", @@ -737,9 +718,9 @@ dependencies = [ [[package]] name = "backtrace" -version = "0.3.72" +version = "0.3.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17c6a35df3749d2e8bb1b7b21a976d82b15548788d2735b9d82f329268f71a11" +checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" dependencies = [ "addr2line", "cc", @@ -813,7 +794,7 @@ dependencies = [ "genesis", "hex", "int_to_bytes", - "itertools", + "itertools 0.10.5", "kzg", "lazy_static", "lighthouse_metrics", @@ -869,7 +850,7 @@ dependencies = [ "genesis", "hex", "http_api", - "hyper 1.3.1", + "hyper 1.4.1", "lighthouse_network", "monitoring_api", "node_test_rig", @@ -890,7 +871,7 @@ version = "0.1.0" dependencies = [ "fnv", "futures", - "itertools", + "itertools 0.10.5", "lazy_static", "lighthouse_metrics", "lighthouse_network", @@ -922,10 +903,10 @@ version = "0.69.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a00dc851838a2120612785d195287475a3ac45514741da670b735818822129a0" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "cexpr", "clang-sys", - "itertools", + "itertools 0.12.1", "lazy_static", "lazycell", "proc-macro2", @@ -933,7 +914,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.66", + "syn 2.0.72", ] [[package]] @@ -959,9 +940,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "bitvec" @@ -1040,9 +1021,9 @@ dependencies = [ [[package]] name = "blst" -version = "0.3.11" +version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c94087b935a822949d3291a9989ad2b2051ea141eda0fd4e478a75f6aa3e604b" +checksum = "62dc83a094a71d43eeadd254b1ec2d24cb6a0bb6cadce00df51f0db594711a32" dependencies = [ "cc", "glob", @@ -1128,9 +1109,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.6.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" +checksum = "a12916984aab3fa6e39d655a33e09c0071eb36d6ab3aea5c2d78551f1df6d952" dependencies = [ "serde", ] @@ -1167,6 +1148,7 @@ dependencies = [ "glob", "hex", "libc", + "serde", ] [[package]] @@ -1209,13 +1191,12 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.0.98" +version = "1.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41c270e7540d725e65ac7f1b212ac8ce349719624d7bcff99f8e2e488e8cf03f" +checksum = "2aba8f4e9906c7ce3c73463f62a7f0c65183ada1a2d47e397cc8810827f9694f" dependencies = [ "jobserver", "libc", - "once_cell", ] [[package]] @@ -1272,7 +1253,7 @@ dependencies = [ "android-tzdata", "iana-time-zone", "num-traits", - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] @@ -1324,9 +1305,9 @@ dependencies = [ [[package]] name = "clang-sys" -version = "1.8.2" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f803f94ecf597339c7a34eed2036ef83f86aaba937f001f7c5b5e251f043f1f9" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" dependencies = [ "glob", "libc", @@ -1335,9 +1316,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.4" +version = "4.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" +checksum = "8f6b81fb3c84f5563d509c59b5a48d935f689e993afa90fe39047f05adef9142" dependencies = [ "clap_builder", "clap_derive", @@ -1345,9 +1326,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.2" +version = "4.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" +checksum = "5ca6706fd5224857d9ac5eb9355f6683563cc0541c7cd9d014043b57cbec78ac" dependencies = [ "anstream", "anstyle", @@ -1358,21 +1339,21 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.4" +version = "4.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" +checksum = "2bac35c6dafb060fd4d275d9a4ffae97917c13a6327903a8be2153cd964f7085" dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.72", ] [[package]] name = "clap_lex" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" +checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70" [[package]] name = "clap_utils" @@ -1451,7 +1432,7 @@ name = "compare_fields" version = "0.2.0" dependencies = [ "compare_fields_derive", - "itertools", + "itertools 0.10.5", ] [[package]] @@ -1557,7 +1538,7 @@ dependencies = [ "clap", "criterion-plot", "is-terminal", - "itertools", + "itertools 0.10.5", "num-traits", "once_cell", "oorandom", @@ -1578,7 +1559,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" dependencies = [ "cast", - "itertools", + "itertools 0.10.5", ] [[package]] @@ -1737,7 +1718,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.72", ] [[package]] @@ -1746,8 +1727,18 @@ version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a01d95850c592940db9b8194bc39f4bc0e89dee5c4265e4b1807c34a9aba453c" dependencies = [ - "darling_core", - "darling_macro", + "darling_core 0.13.4", + "darling_macro 0.13.4", +] + +[[package]] +name = "darling" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" +dependencies = [ + "darling_core 0.20.10", + "darling_macro 0.20.10", ] [[package]] @@ -1764,17 +1755,42 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "darling_core" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim 0.11.1", + "syn 2.0.72", +] + [[package]] name = "darling_macro" version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835" dependencies = [ - "darling_core", + "darling_core 0.13.4", "quote", "syn 1.0.109", ] +[[package]] +name = "darling_macro" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" +dependencies = [ + "darling_core 0.20.10", + "quote", + "syn 2.0.72", +] + [[package]] name = "darwin-libproc" version = "0.1.2" @@ -1937,29 +1953,29 @@ checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.72", ] [[package]] name = "derive_more" -version = "0.99.17" +version = "0.99.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" dependencies = [ "convert_case", "proc-macro2", "quote", "rustc_version 0.4.0", - "syn 1.0.109", + "syn 2.0.72", ] [[package]] name = "diesel" -version = "2.1.6" +version = "2.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff236accb9a5069572099f0b350a92e9560e8e63a9b8d546162f4a5e03026bb2" +checksum = "bf97ee7261bb708fa3402fa9c17a54b70e90e3cb98afb3dc8999d5512cb03f94" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "byteorder", "diesel_derives", "itoa", @@ -1969,21 +1985,22 @@ dependencies = [ [[package]] name = "diesel_derives" -version = "2.1.4" +version = "2.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14701062d6bed917b5c7103bdffaee1e4609279e240488ad24e7bd979ca6866c" +checksum = "d6ff2be1e7312c858b2ef974f5c7089833ae57b5311b334b30923af58e5718d8" dependencies = [ "diesel_table_macro_syntax", + "dsl_auto_type", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.72", ] [[package]] name = "diesel_migrations" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6036b3f0120c5961381b570ee20a02432d7e2d27ea60de9578799cf9156914ac" +checksum = "8a73ce704bad4231f001bff3314d91dce4aba0770cee8b233991859abc15c1f6" dependencies = [ "diesel", "migrations_internals", @@ -1992,11 +2009,11 @@ dependencies = [ [[package]] name = "diesel_table_macro_syntax" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc5557efc453706fed5e4fa85006fe9817c224c3f480a34c7e5959fd700921c5" +checksum = "209c735641a413bc68c4923a9d6ad4bcb3ca306b794edaa7eb0b3228a99ffb25" dependencies = [ - "syn 2.0.66", + "syn 2.0.72", ] [[package]] @@ -2103,13 +2120,27 @@ dependencies = [ [[package]] name = "displaydoc" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.72", +] + +[[package]] +name = "dsl_auto_type" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5d9abe6314103864cc2d8901b7ae224e0ab1a103a0a416661b4097b0779b607" +dependencies = [ + "darling 0.20.10", + "either", + "heck 0.5.0", + "proc-macro2", + "quote", + "syn 2.0.72", ] [[package]] @@ -2209,9 +2240,9 @@ dependencies = [ [[package]] name = "either" -version = "1.12.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "elliptic-curve" @@ -2289,7 +2320,7 @@ dependencies = [ "heck 0.4.1", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.72", ] [[package]] @@ -2666,22 +2697,22 @@ dependencies = [ [[package]] name = "ethereum_ssz" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e61ffea29f26e8249d35128a82ec8d3bd4fbc80179ea5f5e5e3daafef6a80fcb" +checksum = "7d3627f83d8b87b432a5fad9934b4565260722a141a2c40f371f8080adec9425" dependencies = [ "ethereum-types 0.14.1", - "itertools", + "itertools 0.10.5", "smallvec", ] [[package]] name = "ethereum_ssz_derive" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6085d7fd3cf84bd2b8fec150d54c8467fb491d8db9c460607c5534f653a0ee38" +checksum = "8eccd5378ec34a07edd3d9b48088cbc63309d0367d14ba10b0cdb1d1791080ea" dependencies = [ - "darling", + "darling 0.13.4", "proc-macro2", "quote", "syn 1.0.109", @@ -2818,9 +2849,9 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "event-listener" -version = "4.0.3" +version = "5.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b215c49b2b248c855fb73579eb1f4f26c38ffdc12973e20e07b91d78d5646e" +checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" dependencies = [ "concurrent-queue", "parking", @@ -2829,11 +2860,11 @@ dependencies = [ [[package]] name = "event-listener-strategy" -version = "0.4.0" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "958e4d70b6d5e81971bebec42271ec641e7ff4e170a6fa605f2b8a8b65cb97d3" +checksum = "0f214dc438f977e6d4e3500aaa277f5ad94ca83fbbd9b1a15713ce2344ccc5a1" dependencies = [ - "event-listener 4.0.3", + "event-listener 5.3.1", "pin-project-lite", ] @@ -2865,6 +2896,7 @@ name = "execution_layer" version = "0.1.0" dependencies = [ "alloy-consensus", + "alloy-primitives", "alloy-rlp", "arc-swap", "builder_client", @@ -3130,9 +3162,9 @@ dependencies = [ [[package]] name = "futures-bounded" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1e2774cc104e198ef3d3e1ff4ab40f86fa3245d6cb6a3a46174f21463cee173" +checksum = "91f328e7fb845fc832912fb6a34f40cf6d1888c92f974d1893a54e97b5ff542e" dependencies = [ "futures-timer", "futures-util", @@ -3190,7 +3222,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.72", ] [[package]] @@ -3200,7 +3232,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f2f12607f92c69b12ed746fabf9ca4f5c482cba46679c1a75b874ed7c26adb" dependencies = [ "futures-io", - "rustls 0.23.8", + "rustls 0.23.12", "rustls-pki-types", ] @@ -3348,7 +3380,7 @@ checksum = "53010ccb100b96a67bc32c0175f0ed1426b31b655d562898e57325f81c023ac0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.72", ] [[package]] @@ -3372,7 +3404,7 @@ dependencies = [ "futures-ticker", "futures-timer", "getrandom", - "hashlink 0.9.0", + "hashlink 0.9.1", "hex_fmt", "libp2p", "prometheus-client", @@ -3490,9 +3522,9 @@ dependencies = [ [[package]] name = "hashlink" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "692eaaf7f7607518dd3cef090f1474b61edc5301d8012f09579920df68b725ee" +checksum = "6ba4ff7128dee98c7dc9794b6a411377e1404dba1c97deb8d1a55297bd25d8af" dependencies = [ "hashbrown 0.14.5", ] @@ -3548,14 +3580,17 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" +[[package]] +name = "hermit-abi" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" + [[package]] name = "hex" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" -dependencies = [ - "serde", -] [[package]] name = "hex-literal" @@ -3710,9 +3745,9 @@ dependencies = [ [[package]] name = "http-body" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", "http 1.1.0", @@ -3720,14 +3755,14 @@ dependencies = [ [[package]] name = "http-body-util" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0475f8b2ac86659c21b64320d5d653f9efe42acd2a4e560073ec61a155a34f1d" +checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" dependencies = [ "bytes", - "futures-core", + "futures-util", "http 1.1.0", - "http-body 1.0.0", + "http-body 1.0.1", "pin-project-lite", ] @@ -3801,9 +3836,9 @@ dependencies = [ [[package]] name = "httparse" -version = "1.8.0" +version = "1.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" +checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" [[package]] name = "httpdate" @@ -3819,9 +3854,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "0.14.28" +version = "0.14.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" +checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9" dependencies = [ "bytes", "futures-channel", @@ -3843,15 +3878,15 @@ dependencies = [ [[package]] name = "hyper" -version = "1.3.1" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe575dd17d0862a9a33781c8c4696a55c320909004a67a00fb286ba8b1bc496d" +checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05" dependencies = [ "bytes", "futures-channel", "futures-util", "http 1.1.0", - "http-body 1.0.0", + "http-body 1.0.1", "httparse", "httpdate", "itoa", @@ -3868,7 +3903,7 @@ checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" dependencies = [ "futures-util", "http 0.2.12", - "hyper 0.14.28", + "hyper 0.14.30", "rustls 0.21.12", "tokio", "tokio-rustls 0.24.1", @@ -3881,7 +3916,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" dependencies = [ "bytes", - "hyper 0.14.28", + "hyper 0.14.30", "native-tls", "tokio", "tokio-native-tls", @@ -3889,15 +3924,15 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b875924a60b96e5d7b9ae7b066540b1dd1cbd90d1828f54c92e02a283351c56" +checksum = "3ab92f4f49ee4fb4f997c784b7a2e0fa70050211e0b6a287f898c3c9785ca956" dependencies = [ "bytes", "futures-util", "http 1.1.0", - "http-body 1.0.0", - "hyper 1.3.1", + "http-body 1.0.1", + "hyper 1.4.1", "pin-project-lite", "tokio", ] @@ -3991,7 +4026,7 @@ dependencies = [ "bytes", "futures", "http 0.2.12", - "hyper 0.14.28", + "hyper 0.14.30", "log", "rand", "tokio", @@ -4175,6 +4210,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.11" @@ -4214,9 +4258,9 @@ dependencies = [ [[package]] name = "jobserver" -version = "0.1.31" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" dependencies = [ "libc", ] @@ -4318,11 +4362,11 @@ dependencies = [ [[package]] name = "lazy_static" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" dependencies = [ - "spin 0.5.2", + "spin 0.9.8", ] [[package]] @@ -4421,12 +4465,12 @@ dependencies = [ [[package]] name = "libloading" -version = "0.8.3" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19" +checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" dependencies = [ "cfg-if", - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] @@ -4509,15 +4553,14 @@ dependencies = [ [[package]] name = "libp2p-core" -version = "0.41.2" +version = "0.41.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8130a8269e65a2554d55131c770bdf4bcd94d2b8d4efb24ca23699be65066c05" +checksum = "a5a8920cbd8540059a01950c1e5c96ea8d89eb50c51cd366fc18bdf540a6e48f" dependencies = [ "either", "fnv", "futures", "futures-timer", - "instant", "libp2p-identity", "multiaddr", "multihash", @@ -4533,6 +4576,7 @@ dependencies = [ "tracing", "unsigned-varint 0.8.0", "void", + "web-time", ] [[package]] @@ -4576,9 +4620,9 @@ dependencies = [ [[package]] name = "libp2p-identity" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "999ec70441b2fb35355076726a6bc466c932e9bdc66f6a11c6c0aa17c7ab9be0" +checksum = "55cca1eb2bc1fd29f099f3daaab7effd01e1a54b7c577d0ed082521034d912e8" dependencies = [ "asn1_der", "bs58 0.5.1", @@ -4712,7 +4756,7 @@ dependencies = [ "quinn", "rand", "ring 0.17.8", - "rustls 0.23.8", + "rustls 0.23.12", "socket2 0.5.7", "thiserror", "tokio", @@ -4752,7 +4796,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.72", ] [[package]] @@ -4774,9 +4818,9 @@ dependencies = [ [[package]] name = "libp2p-tls" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "251b17aebdd29df7e8f80e4d94b782fae42e934c49086e1a81ba23b60a8314f2" +checksum = "72b7b831e55ce2aa6c354e6861a85fdd4dd0a2b97d5e276fabac0e4810a71776" dependencies = [ "futures", "futures-rustls", @@ -4784,7 +4828,7 @@ dependencies = [ "libp2p-identity", "rcgen", "ring 0.17.8", - "rustls 0.23.8", + "rustls 0.23.12", "rustls-webpki 0.101.7", "thiserror", "x509-parser", @@ -4819,7 +4863,7 @@ dependencies = [ "thiserror", "tracing", "yamux 0.12.1", - "yamux 0.13.2", + "yamux 0.13.3", ] [[package]] @@ -4828,7 +4872,7 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "libc", ] @@ -4969,6 +5013,7 @@ dependencies = [ "futures", "gossipsub", "hex", + "itertools 0.10.5", "lazy_static", "libp2p", "libp2p-mplex", @@ -5073,9 +5118,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.21" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "logging" @@ -5208,9 +5253,9 @@ checksum = "8878cd8d1b3c8c8ae4b2ba0a36652b7cf192f618a599a7fbdfa25cffd4ea72dd" [[package]] name = "memchr" -version = "2.7.2" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "memoffset" @@ -5235,21 +5280,21 @@ dependencies = [ [[package]] name = "metastruct" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccfbb8826226b09b05bb62a0937cf6abb16f1f7d4b746eb95a83db14aec60f06" +checksum = "f00a5ba4a0f3453c31c397b214e1675d95b697c33763aa58add57ea833424384" dependencies = [ "metastruct_macro", ] [[package]] name = "metastruct_macro" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37cb4045d5677b7da537f8cb5d0730d5b6414e3cc81c61e4b50e1f0cbdc73909" +checksum = "7c3a991d4536c933306e52f0e8ab303757185ec13a09d1f3e1cbde5a0d8410bf" dependencies = [ - "darling", - "itertools", + "darling 0.13.4", + "itertools 0.10.5", "proc-macro2", "quote", "smallvec", @@ -5258,19 +5303,19 @@ dependencies = [ [[package]] name = "migrations_internals" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f23f71580015254b020e856feac3df5878c2c7a8812297edd6c0a485ac9dada" +checksum = "fd01039851e82f8799046eabbb354056283fb265c8ec0996af940f4e85a380ff" dependencies = [ "serde", - "toml 0.7.8", + "toml 0.8.15", ] [[package]] name = "migrations_macros" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cce3325ac70e67bbab5bd837a31cae01f1a6db64e0e744a33cb03a543469ef08" +checksum = "ffb161cc72176cb37aa47f1fc520d3ef02263d67d661f44f05d05a079e1237fd" dependencies = [ "migrations_internals", "proc-macro2", @@ -5289,7 +5334,7 @@ dependencies = [ "ethereum_hashing", "ethereum_ssz", "ethereum_ssz_derive", - "itertools", + "itertools 0.10.5", "parking_lot 0.12.3", "rayon", "serde", @@ -5308,9 +5353,9 @@ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "mime_guess" -version = "2.0.4" +version = "2.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" +checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" dependencies = [ "mime", "unicase", @@ -5324,22 +5369,23 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87dfd01fe195c66b572b37921ad8803d010623c0aca821bea2302239d155cdae" +checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" dependencies = [ "adler", ] [[package]] name = "mio" -version = "0.8.11" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +checksum = "4569e456d394deccd22ce1c1913e6ea0e54519f577285001215d33557431afe4" dependencies = [ + "hermit-abi 0.3.9", "libc", "wasi", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -5530,7 +5576,7 @@ dependencies = [ "gossipsub", "hex", "igd-next", - "itertools", + "itertools 0.10.5", "lazy_static", "lighthouse_metrics", "lighthouse_network", @@ -5573,7 +5619,7 @@ version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "cfg-if", "cfg_aliases", "libc", @@ -5632,9 +5678,9 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c165a9ab64cf766f73521c0dd2cfdff64f488b8f0b3e621face3462d3db536d7" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" dependencies = [ "num-integer", "num-traits", @@ -5706,9 +5752,9 @@ dependencies = [ [[package]] name = "object" -version = "0.35.0" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8ec7ab813848ba4522158d5517a6093db1ded27575b070f4177b8d12b41db5e" +checksum = "081b846d1d56ddfc18fdf1a922e4f6e07a11768ea1b92dec44e42b72712ccfce" dependencies = [ "memchr", ] @@ -5737,9 +5783,9 @@ dependencies = [ [[package]] name = "oorandom" -version = "11.1.3" +version = "11.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" +checksum = "b410bbe7e14ab526a0e86877eb47c6996a2bd7746f027ba551028c925390e4e9" [[package]] name = "opaque-debug" @@ -5778,7 +5824,7 @@ version = "0.10.66" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "cfg-if", "foreign-types", "libc", @@ -5795,7 +5841,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.72", ] [[package]] @@ -5806,9 +5852,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-src" -version = "300.3.0+3.3.0" +version = "300.3.1+3.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eba8804a1c5765b18c4b3f907e6897ebabeedebc9830e1a0046c4a4cf44663e1" +checksum = "7259953d42a81bf137fbbd73bd30a8e1914d6dce43c2b90ed575783a22608b91" dependencies = [ "cc", ] @@ -5835,7 +5881,7 @@ dependencies = [ "derivative", "ethereum_ssz", "ethereum_ssz_derive", - "itertools", + "itertools 0.10.5", "lazy_static", "lighthouse_metrics", "maplit", @@ -5968,9 +6014,9 @@ checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.5.1", + "redox_syscall 0.5.3", "smallvec", - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] @@ -6047,9 +6093,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.10" +version = "2.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "560131c633294438da9f7c4b08189194b20946c8274c6b9e38881a7874dc8ee8" +checksum = "cd53dff83f26735fdc1ca837098ccf133605d794cdae66acfc2bfac3ec809d95" dependencies = [ "memchr", "thiserror", @@ -6101,7 +6147,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.72", ] [[package]] @@ -6178,13 +6224,13 @@ dependencies = [ [[package]] name = "polling" -version = "3.7.0" +version = "3.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645493cf344456ef24219d02a768cf1fb92ddf8c92161679ae3d91b91a637be3" +checksum = "a3ed00ed3fbf728b5816498ecd316d1716eecaced9c0c8d2c5a6740ca214985b" dependencies = [ "cfg-if", "concurrent-queue", - "hermit-abi 0.3.9", + "hermit-abi 0.4.0", "pin-project-lite", "rustix 0.38.34", "tracing", @@ -6228,11 +6274,11 @@ dependencies = [ [[package]] name = "postgres-protocol" -version = "0.6.6" +version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49b6c5ef183cd3ab4ba005f1ca64c21e8bd97ce4699cfea9e8d9a2c4958ca520" +checksum = "acda0ebdebc28befa84bee35e651e4c5f09073d668c7aed4cf7e23c3cda84b23" dependencies = [ - "base64 0.21.7", + "base64 0.22.1", "byteorder", "bytes", "fallible-iterator", @@ -6246,9 +6292,9 @@ dependencies = [ [[package]] name = "postgres-types" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d2234cdee9408b523530a9b6d2d6b373d1db34f6a8e51dc03ded1828d7fb67c" +checksum = "02048d9e032fb3cc3413bbf7b83a15d84a5d419778e2628751896d856498eee9" dependencies = [ "bytes", "fallible-iterator", @@ -6269,9 +6315,9 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "pq-sys" -version = "0.4.8" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31c0052426df997c0cbd30789eb44ca097e3541717a7b8fa36b1c464ee7edebd" +checksum = "a24ff9e4cf6945c988f0db7005d87747bf72864965c3529d259ad155ac41d584" dependencies = [ "vcpkg", ] @@ -6341,9 +6387,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.84" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec96c6a92621310b51366f1e28d05ef11489516e93be030060e5fc12024a49d6" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] @@ -6380,9 +6426,9 @@ dependencies = [ [[package]] name = "prometheus-client" -version = "0.22.2" +version = "0.22.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1ca959da22a332509f2a73ae9e5f23f9dcfc31fd3a54d71f159495bd5909baa" +checksum = "504ee9ff529add891127c4827eb481bd69dc0ebc72e9a682e187db4caa60c3ca" dependencies = [ "dtoa", "itoa", @@ -6398,24 +6444,24 @@ checksum = "440f724eba9f6996b75d63681b0a92b06947f1457076d503a4d2e2c8f56442b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.72", ] [[package]] name = "proptest" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31b476131c3c86cb68032fdc5cb6d5a1045e3e42d96b69fa599fd77701e1f5bf" +checksum = "b4c2511913b88df1637da85cc8d96ec8e43a3f8bb8ccb71ee1ac240d6f3df58d" dependencies = [ "bit-set", "bit-vec", - "bitflags 2.5.0", + "bitflags 2.6.0", "lazy_static", "num-traits", "rand", "rand_chacha", "rand_xorshift", - "regex-syntax 0.8.3", + "regex-syntax 0.8.4", "rusty-fork", "tempfile", "unarray", @@ -6524,9 +6570,9 @@ dependencies = [ [[package]] name = "quinn" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "904e3d3ba178131798c6d9375db2b13b34337d489b089fc5ba0825a2ff1bee73" +checksum = "e4ceeeeabace7857413798eb1ffa1e9c905a9946a57d81fb69b4b71c4d8eb3ad" dependencies = [ "bytes", "futures-io", @@ -6534,7 +6580,7 @@ dependencies = [ "quinn-proto", "quinn-udp", "rustc-hash", - "rustls 0.23.8", + "rustls 0.23.12", "thiserror", "tokio", "tracing", @@ -6542,15 +6588,15 @@ dependencies = [ [[package]] name = "quinn-proto" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e974563a4b1c2206bbc61191ca4da9c22e4308b4c455e8906751cc7828393f08" +checksum = "ddf517c03a109db8100448a4be38d498df8a210a99fe0e1b9eaf39e78c640efe" dependencies = [ "bytes", "rand", "ring 0.17.8", "rustc-hash", - "rustls 0.23.8", + "rustls 0.23.12", "slab", "thiserror", "tinyvec", @@ -6559,14 +6605,13 @@ dependencies = [ [[package]] name = "quinn-udp" -version = "0.5.1" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4f0def2590301f4f667db5a77f9694fb004f82796dc1a8b1508fafa3d0e8b72" +checksum = "8bffec3605b73c6f1754535084a85229fa8a30f86014e6c81aeec4abb68b0285" dependencies = [ "libc", "once_cell", "socket2 0.5.7", - "tracing", "windows-sys 0.52.0", ] @@ -6685,9 +6730,9 @@ dependencies = [ [[package]] name = "redb" -version = "2.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed7508e692a49b6b2290b56540384ccae9b1fb4d77065640b165835b56ffe3bb" +checksum = "a6dd20d3cdeb9c7d2366a0b16b93b35b75aec15309fbeb7ce477138c9f68c8c0" dependencies = [ "libc", ] @@ -6712,11 +6757,11 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.1" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e" +checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", ] [[package]] @@ -6732,14 +6777,14 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.4" +version = "1.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.6", - "regex-syntax 0.8.3", + "regex-automata 0.4.7", + "regex-syntax 0.8.4", ] [[package]] @@ -6753,13 +6798,13 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.3", + "regex-syntax 0.8.4", ] [[package]] @@ -6770,9 +6815,9 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" [[package]] name = "reqwest" @@ -6788,7 +6833,7 @@ dependencies = [ "h2", "http 0.2.12", "http-body 0.4.6", - "hyper 0.14.28", + "hyper 0.14.30", "hyper-rustls", "hyper-tls", "ipnet", @@ -6944,9 +6989,9 @@ dependencies = [ [[package]] name = "ruint" -version = "1.12.1" +version = "1.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f308135fef9fc398342da5472ce7c484529df23743fb7c734e0f3d472971e62" +checksum = "2c3cc4c2511671f327125da14133d0c5c5d137f006a1017a16f557bc85b16286" dependencies = [ "alloy-rlp", "ark-ff 0.3.0", @@ -6968,9 +7013,9 @@ dependencies = [ [[package]] name = "ruint-macro" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f86854cf50259291520509879a5c294c3c9a4c334e9ff65071c51e42ef1e2343" +checksum = "48fd7bd8a6377e15ad9d42a8ec25371b94ddc67abe7c8b9127bec79bebaaae18" [[package]] name = "rusqlite" @@ -7051,7 +7096,7 @@ version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "errno", "libc", "linux-raw-sys 0.4.14", @@ -7079,21 +7124,21 @@ dependencies = [ "log", "ring 0.17.8", "rustls-pki-types", - "rustls-webpki 0.102.4", + "rustls-webpki 0.102.6", "subtle", "zeroize", ] [[package]] name = "rustls" -version = "0.23.8" +version = "0.23.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79adb16721f56eb2d843e67676896a61ce7a0fa622dc18d3e372477a029d2740" +checksum = "c58f8c84392efc0a126acce10fa59ff7b3d2ac06ab451a33f2741989b806b044" dependencies = [ "once_cell", "ring 0.17.8", "rustls-pki-types", - "rustls-webpki 0.102.4", + "rustls-webpki 0.102.6", "subtle", "zeroize", ] @@ -7135,9 +7180,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.102.4" +version = "0.102.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff448f7e92e913c4b7d4c6d8e4540a1724b319b4152b8aef6d4cf8339712b33e" +checksum = "8e6b52d4fda176fd835fdc55a835d4a89b8499cad995885a21149d5ad62f852e" dependencies = [ "ring 0.17.8", "rustls-pki-types", @@ -7307,11 +7352,11 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.11.0" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c627723fd09706bacdb5cf41499e95098555af3c3c29d014dc3c458ef6be11c0" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "core-foundation", "core-foundation-sys", "libc", @@ -7320,9 +7365,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.11.0" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "317936bbbd05227752583946b9e66d7ce3b489f84e11a94a510b4437fef407d7" +checksum = "75da29fe9b9b08fe9d6b22b5b4bcbc75d8db3aa31e639aa56bb62e9d46bfceaf" dependencies = [ "core-foundation-sys", "libc", @@ -7371,9 +7416,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.203" +version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" +checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" dependencies = [ "serde_derive", ] @@ -7390,20 +7435,20 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.203" +version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" +checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.72", ] [[package]] name = "serde_json" -version = "1.0.117" +version = "1.0.120" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" +checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5" dependencies = [ "itoa", "ryu", @@ -7428,7 +7473,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.72", ] [[package]] @@ -7468,7 +7513,7 @@ version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e182d6ec6f05393cc0e5ed1bf81ad6db3a8feedf8ee515ecdd369809bcce8082" dependencies = [ - "darling", + "darling 0.13.4", "proc-macro2", "quote", "syn 1.0.109", @@ -7918,7 +7963,7 @@ dependencies = [ "derivative", "ethereum_serde_utils", "ethereum_ssz", - "itertools", + "itertools 0.10.5", "serde", "serde_derive", "smallvec", @@ -7946,7 +7991,7 @@ dependencies = [ "ethereum_ssz_derive", "int_to_bytes", "integer-sqrt", - "itertools", + "itertools 0.10.5", "lazy_static", "lighthouse_metrics", "merkle_proof", @@ -7988,7 +8033,7 @@ dependencies = [ "directory", "ethereum_ssz", "ethereum_ssz_derive", - "itertools", + "itertools 0.10.5", "lazy_static", "leveldb", "lighthouse_metrics", @@ -8050,9 +8095,9 @@ dependencies = [ [[package]] name = "subtle" -version = "2.5.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "superstruct" @@ -8060,8 +8105,8 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf0f31f730ad9e579364950e10d6172b4a9bd04b447edf5988b066a860cc340e" dependencies = [ - "darling", - "itertools", + "darling 0.13.4", + "itertools 0.10.5", "proc-macro2", "quote", "smallvec", @@ -8090,9 +8135,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.66" +version = "2.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" +checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af" dependencies = [ "proc-macro2", "quote", @@ -8119,7 +8164,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.72", ] [[package]] @@ -8285,22 +8330,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.61" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" +checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.61" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" +checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.72", ] [[package]] @@ -8404,9 +8449,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.6.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" dependencies = [ "tinyvec_macros", ] @@ -8419,20 +8464,19 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.37.0" +version = "1.39.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" +checksum = "d040ac2b29ab03b09d4129c2f5bbd012a3ac2f79d38ff506a4bf8dd34b0eac8a" dependencies = [ "backtrace", "bytes", "libc", "mio", - "num_cpus", "pin-project-lite", "signal-hook-registry", "socket2 0.5.7", "tokio-macros", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -8447,13 +8491,13 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.2.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.72", ] [[package]] @@ -8468,9 +8512,9 @@ dependencies = [ [[package]] name = "tokio-postgres" -version = "0.7.10" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d340244b32d920260ae7448cb72b6e238bddc3d4f7603394e7dd46ed8e48f5b8" +checksum = "03adcf0147e203b6032c0b2d30be1415ba03bc348901f3ff1cc0df6a733e60c3" dependencies = [ "async-trait", "byteorder", @@ -8551,14 +8595,14 @@ dependencies = [ [[package]] name = "toml" -version = "0.7.8" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257" +checksum = "ac2caab0bf757388c6c0ae23b3293fdb463fee59434529014f85e3263b995c28" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.19.15", + "toml_edit 0.22.16", ] [[package]] @@ -8577,10 +8621,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ "indexmap 2.2.6", - "serde", - "serde_spanned", "toml_datetime", - "winnow", + "winnow 0.5.40", ] [[package]] @@ -8591,7 +8633,20 @@ checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" dependencies = [ "indexmap 2.2.6", "toml_datetime", - "winnow", + "winnow 0.5.40", +] + +[[package]] +name = "toml_edit" +version = "0.22.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "278f3d518e152219c994ce877758516bca5e118eaed6996192a774fb9fbf0788" +dependencies = [ + "indexmap 2.2.6", + "serde", + "serde_spanned", + "toml_datetime", + "winnow 0.6.15", ] [[package]] @@ -8654,7 +8709,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.72", ] [[package]] @@ -8742,7 +8797,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ce7bccc538359a213436af7bc95804bdbf1c2a21d80e22953cbe9e096837ff1" dependencies = [ - "darling", + "darling 0.13.4", "quote", "syn 1.0.109", ] @@ -8759,9 +8814,9 @@ dependencies = [ [[package]] name = "triomphe" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b2cb4fbb9995eeb36ac86fadf24031ccd58f99d6b4b2d7b911db70bddb80d90" +checksum = "e6631e42e10b40c0690bf92f404ebcfe6e1fdb480391d15f17cc8e96eeed5369" dependencies = [ "serde", "stable_deref_trait", @@ -8783,6 +8838,8 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" name = "types" version = "0.2.1" dependencies = [ + "alloy-primitives", + "alloy-rlp", "arbitrary", "beacon_chain", "bls", @@ -8798,7 +8855,7 @@ dependencies = [ "ethereum_ssz_derive", "hex", "int_to_bytes", - "itertools", + "itertools 0.10.5", "kzg", "lazy_static", "log", @@ -8973,9 +9030,9 @@ dependencies = [ [[package]] name = "url" -version = "2.5.0" +version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" dependencies = [ "form_urlencoded", "idna 0.5.0", @@ -8984,9 +9041,9 @@ dependencies = [ [[package]] name = "utf8parse" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" @@ -9018,8 +9075,8 @@ dependencies = [ "filesystem", "futures", "hex", - "hyper 1.3.1", - "itertools", + "hyper 1.4.1", + "itertools 0.10.5", "lazy_static", "libsecp256k1", "lighthouse_metrics", @@ -9164,7 +9221,7 @@ dependencies = [ "futures-util", "headers", "http 0.2.12", - "hyper 0.14.28", + "hyper 0.14.30", "log", "mime", "mime_guess", @@ -9235,7 +9292,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.72", "wasm-bindgen-shared", ] @@ -9269,7 +9326,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.72", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -9323,7 +9380,7 @@ dependencies = [ "env_logger 0.9.3", "eth2", "http_api", - "hyper 1.3.1", + "hyper 1.4.1", "log", "logging", "network", @@ -9485,7 +9542,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] @@ -9512,7 +9569,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] @@ -9547,18 +9604,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.5", - "windows_aarch64_msvc 0.52.5", - "windows_i686_gnu 0.52.5", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", "windows_i686_gnullvm", - "windows_i686_msvc 0.52.5", - "windows_x86_64_gnu 0.52.5", - "windows_x86_64_gnullvm 0.52.5", - "windows_x86_64_msvc 0.52.5", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] @@ -9575,9 +9632,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" @@ -9593,9 +9650,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" @@ -9611,15 +9668,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" @@ -9635,9 +9692,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" @@ -9653,9 +9710,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" @@ -9671,9 +9728,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" @@ -9689,9 +9746,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" @@ -9702,6 +9759,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "winnow" +version = "0.6.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "557404e450152cd6795bb558bca69e43c585055f4606e3bcae5894fc6dac9ba0" +dependencies = [ + "memchr", +] + [[package]] name = "winreg" version = "0.50.0" @@ -9792,9 +9858,9 @@ dependencies = [ [[package]] name = "yaml-rust2" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "498f4d102a79ea1c9d4dd27573c0fc96ad74c023e8da38484e47883076da25fb" +checksum = "8902160c4e6f2fb145dbe9d6760a75e3c9522d8bf796ed7047c85919ac7115f8" dependencies = [ "arraydeque", "encoding_rs", @@ -9818,18 +9884,18 @@ dependencies = [ [[package]] name = "yamux" -version = "0.13.2" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f97202f6b125031b95d83e01dc57292b529384f80bfae4677e4bbc10178cf72" +checksum = "a31b5e376a8b012bee9c423acdbb835fc34d45001cfa3106236a624e4b738028" dependencies = [ "futures", - "instant", "log", "nohash-hasher", "parking_lot 0.12.3", "pin-project", "rand", "static_assertions", + "web-time", ] [[package]] @@ -9843,22 +9909,22 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.7.34" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.34" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.72", ] [[package]] @@ -9878,7 +9944,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.72", ] [[package]] @@ -9922,9 +9988,9 @@ dependencies = [ [[package]] name = "zstd-sys" -version = "2.0.10+zstd.1.5.6" +version = "2.0.12+zstd.1.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c253a4914af5bafc8fa8c86ee400827e83cf6ec01195ec1f1ed8441bf00d65aa" +checksum = "0a4e40c320c3cb459d9a9ff6de98cff88f4751ee9275d140e2be94a2b74e4c13" dependencies = [ "cc", "pkg-config", diff --git a/Cargo.toml b/Cargo.toml index d13f4f7a76..b2957842d5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -94,6 +94,9 @@ resolver = "2" edition = "2021" [workspace.dependencies] +alloy-primitives = "0.7.7" +alloy-rlp = "0.3.4" +alloy-consensus = "0.2.0" anyhow = "1" arbitrary = { version = "1", features = ["derive"] } async-channel = "1.9.0" diff --git a/account_manager/src/validator/recover.rs b/account_manager/src/validator/recover.rs index 4677db18df..b36b10ab00 100644 --- a/account_manager/src/validator/recover.rs +++ b/account_manager/src/validator/recover.rs @@ -147,8 +147,8 @@ pub fn cli_run(matches: &ArgMatches, validator_dir: PathBuf) -> Result<(), Strin println!( "{}/{}\tIndex: {}\t0x{}", - index - first_index, - count - first_index, + index - first_index + 1, + count, index, voting_pubkey ); diff --git a/beacon_node/beacon_chain/src/beacon_chain.rs b/beacon_node/beacon_chain/src/beacon_chain.rs index 7ebd011cf4..1fa77a2043 100644 --- a/beacon_node/beacon_chain/src/beacon_chain.rs +++ b/beacon_node/beacon_chain/src/beacon_chain.rs @@ -23,6 +23,7 @@ use crate::chain_config::ChainConfig; use crate::data_availability_checker::{ Availability, AvailabilityCheckError, AvailableBlock, DataAvailabilityChecker, }; +use crate::data_column_verification::{GossipDataColumnError, GossipVerifiedDataColumn}; use crate::early_attester_cache::EarlyAttesterCache; use crate::errors::{BeaconChainError as Error, BlockProductionError}; use crate::eth1_chain::{Eth1Chain, Eth1ChainBackend}; @@ -2118,6 +2119,19 @@ impl BeaconChain { }) } + pub fn verify_data_column_sidecar_for_gossip( + self: &Arc, + data_column_sidecar: Arc>, + subnet_id: u64, + ) -> Result, GossipDataColumnError> { + metrics::inc_counter(&metrics::DATA_COLUMN_SIDECAR_PROCESSING_REQUESTS); + let _timer = metrics::start_timer(&metrics::DATA_COLUMN_SIDECAR_GOSSIP_VERIFICATION_TIMES); + GossipVerifiedDataColumn::new(data_column_sidecar, subnet_id, self).map(|v| { + metrics::inc_counter(&metrics::DATA_COLUMN_SIDECAR_PROCESSING_SUCCESSES); + v + }) + } + pub fn verify_blob_sidecar_for_gossip( self: &Arc, blob_sidecar: Arc>, @@ -2964,6 +2978,39 @@ impl BeaconChain { self.remove_notified(&block_root, r) } + /// Cache the data columns in the processing cache, process it, then evict it from the cache if it was + /// imported or errors. + pub async fn process_gossip_data_columns( + self: &Arc, + data_columns: Vec>, + ) -> Result> { + let Ok(block_root) = data_columns + .iter() + .map(|c| c.block_root()) + .unique() + .exactly_one() + else { + return Err(BlockError::InternalError( + "Columns should be from the same block".to_string(), + )); + }; + + // If this block has already been imported to forkchoice it must have been available, so + // we don't need to process its samples again. + if self + .canonical_head + .fork_choice_read_lock() + .contains_block(&block_root) + { + return Err(BlockError::BlockIsAlreadyKnown(block_root)); + } + + let r = self + .check_gossip_data_columns_availability_and_import(data_columns) + .await; + self.remove_notified_custody_columns(&block_root, r) + } + /// Cache the blobs in the processing cache, process it, then evict it from the cache if it was /// imported or errors. pub async fn process_rpc_blobs( @@ -3013,6 +3060,21 @@ impl BeaconChain { r } + /// Remove any block components from the *processing cache* if we no longer require them. If the + /// block was imported full or erred, we no longer require them. + fn remove_notified_custody_columns( + &self, + block_root: &Hash256, + r: Result>, + ) -> Result> { + let has_missing_components = + matches!(r, Ok(AvailabilityProcessingStatus::MissingComponents(_, _))); + if !has_missing_components { + self.reqresp_pre_import_cache.write().remove(block_root); + } + r + } + /// Wraps `process_block` in logic to cache the block's commitments in the processing cache /// and evict if the block was imported or errored. pub async fn process_block_with_early_caching>( @@ -3257,6 +3319,31 @@ impl BeaconChain { self.process_availability(slot, availability).await } + /// Checks if the provided data column can make any cached blocks available, and imports immediately + /// if so, otherwise caches the data column in the data availability checker. + async fn check_gossip_data_columns_availability_and_import( + self: &Arc, + data_columns: Vec>, + ) -> Result> { + if let Some(slasher) = self.slasher.as_ref() { + for data_colum in &data_columns { + slasher.accept_block_header(data_colum.signed_block_header()); + } + } + + let Ok(slot) = data_columns.iter().map(|c| c.slot()).unique().exactly_one() else { + return Err(BlockError::InternalError( + "Columns for the same block should have matching slot".to_string(), + )); + }; + + let availability = self + .data_availability_checker + .put_gossip_data_columns(data_columns)?; + + self.process_availability(slot, availability).await + } + /// Checks if the provided blobs can make any cached blocks available, and imports immediately /// if so, otherwise caches the blob in the data availability checker. async fn check_rpc_blob_availability_and_import( diff --git a/beacon_node/beacon_chain/src/block_verification.rs b/beacon_node/beacon_chain/src/block_verification.rs index d906518ff5..5ae98cefbe 100644 --- a/beacon_node/beacon_chain/src/block_verification.rs +++ b/beacon_node/beacon_chain/src/block_verification.rs @@ -54,6 +54,7 @@ use crate::block_verification_types::{ AsBlock, BlockContentsError, BlockImportData, GossipVerifiedBlockContents, RpcBlock, }; use crate::data_availability_checker::{AvailabilityCheckError, MaybeAvailableBlock}; +use crate::data_column_verification::GossipDataColumnError; use crate::eth1_finalization_cache::Eth1FinalizationData; use crate::execution_payload::{ is_optimistic_candidate_block, validate_execution_payload_for_gossip, validate_merge_block, @@ -303,6 +304,13 @@ pub enum BlockError { /// TODO: We may need to penalize the peer that gave us a potentially invalid rpc blob. /// https://github.com/sigp/lighthouse/issues/4546 AvailabilityCheck(AvailabilityCheckError), + /// An internal error has occurred when processing the block or sidecars. + /// + /// ## Peer scoring + /// + /// We were unable to process this block due to an internal error. It's unclear if the block is + /// valid. + InternalError(String), } impl From for BlockError { @@ -523,6 +531,20 @@ impl BlockSlashInfo> { } } +impl BlockSlashInfo { + pub fn from_early_error_data_column( + header: SignedBeaconBlockHeader, + e: GossipDataColumnError, + ) -> Self { + match e { + GossipDataColumnError::ProposalSignatureInvalid => BlockSlashInfo::SignatureInvalid(e), + // `InvalidSignature` could indicate any signature in the block, so we want + // to recheck the proposer signature alone. + _ => BlockSlashInfo::SignatureNotChecked(header, e), + } + } +} + /// Process invalid blocks to see if they are suitable for the slasher. /// /// If no slasher is configured, this is a no-op. @@ -2007,6 +2029,23 @@ impl BlockBlobError for GossipBlobError { } } +impl BlockBlobError for GossipDataColumnError { + fn not_later_than_parent_error(data_column_slot: Slot, parent_slot: Slot) -> Self { + GossipDataColumnError::IsNotLaterThanParent { + data_column_slot, + parent_slot, + } + } + + fn unknown_validator_error(validator_index: u64) -> Self { + GossipDataColumnError::UnknownValidator(validator_index) + } + + fn proposer_signature_invalid() -> Self { + GossipDataColumnError::ProposalSignatureInvalid + } +} + /// Performs a cheap (time-efficient) state advancement so the committees and proposer shuffling for /// `slot` can be obtained from `state`. /// diff --git a/beacon_node/beacon_chain/src/data_availability_checker.rs b/beacon_node/beacon_chain/src/data_availability_checker.rs index 90d4b6081e..fdba60a69a 100644 --- a/beacon_node/beacon_chain/src/data_availability_checker.rs +++ b/beacon_node/beacon_chain/src/data_availability_checker.rs @@ -20,6 +20,7 @@ mod error; mod overflow_lru_cache; mod state_lru_cache; +use crate::data_column_verification::GossipVerifiedDataColumn; pub use error::{Error as AvailabilityCheckError, ErrorCategory as AvailabilityCheckErrorCategory}; use types::non_zero_usize::new_non_zero_usize; @@ -188,6 +189,14 @@ impl DataAvailabilityChecker { ) } + pub fn put_gossip_data_columns( + &self, + _gossip_data_columns: Vec>, + ) -> Result, AvailabilityCheckError> { + // TODO(das) to be implemented + Err(AvailabilityCheckError::Unexpected) + } + /// Check if we have all the blobs for a block. Returns `Availability` which has information /// about whether all components have been received or more are required. pub fn put_pending_executed_block( diff --git a/beacon_node/beacon_chain/src/data_column_verification.rs b/beacon_node/beacon_chain/src/data_column_verification.rs index da848ccc47..2e88da8f6a 100644 --- a/beacon_node/beacon_chain/src/data_column_verification.rs +++ b/beacon_node/beacon_chain/src/data_column_verification.rs @@ -1,8 +1,144 @@ +use crate::block_verification::{process_block_slash_info, BlockSlashInfo}; +use crate::{BeaconChain, BeaconChainError, BeaconChainTypes}; use derivative::Derivative; +use kzg::{Error as KzgError, Kzg}; use ssz_derive::{Decode, Encode}; use std::sync::Arc; -use types::data_column_sidecar::{ColumnIndex, DataColumnSidecar}; -use types::EthSpec; +use types::data_column_sidecar::{ColumnIndex, DataColumnIdentifier}; +use types::{ + BeaconStateError, DataColumnSidecar, EthSpec, Hash256, RuntimeVariableList, + SignedBeaconBlockHeader, Slot, +}; + +/// An error occurred while validating a gossip data column. +#[derive(Debug)] +pub enum GossipDataColumnError { + /// There was an error whilst processing the data column. It is not known if it is + /// valid or invalid. + /// + /// ## Peer scoring + /// + /// We were unable to process this data column due to an internal error. It's + /// unclear if the data column is valid. + BeaconChainError(BeaconChainError), + /// The proposal signature in invalid. + /// + /// ## Peer scoring + /// + /// The data column is invalid and the peer is faulty. + ProposalSignatureInvalid, + /// The proposal_index corresponding to data column.beacon_block_root is not known. + /// + /// ## Peer scoring + /// + /// The data column is invalid and the peer is faulty. + UnknownValidator(u64), + /// The provided data column is not from a later slot than its parent. + /// + /// ## Peer scoring + /// + /// The data column is invalid and the peer is faulty. + IsNotLaterThanParent { + data_column_slot: Slot, + parent_slot: Slot, + }, + /// `Kzg` struct hasn't been initialized. This is an internal error. + /// + /// ## Peer scoring + /// + /// The peer isn't faulty, This is an internal error. + KzgNotInitialized, + /// The kzg verification failed. + /// + /// ## Peer scoring + /// + /// The data column sidecar is invalid and the peer is faulty. + InvalidKzgProof(kzg::Error), +} + +impl From for GossipDataColumnError { + fn from(e: BeaconChainError) -> Self { + GossipDataColumnError::BeaconChainError(e) + } +} + +impl From for GossipDataColumnError { + fn from(e: BeaconStateError) -> Self { + GossipDataColumnError::BeaconChainError(BeaconChainError::BeaconStateError(e)) + } +} + +pub type GossipVerifiedDataColumnList = RuntimeVariableList>; + +/// A wrapper around a `DataColumnSidecar` that indicates it has been approved for re-gossiping on +/// the p2p network. +#[derive(Debug)] +pub struct GossipVerifiedDataColumn { + block_root: Hash256, + data_column: KzgVerifiedDataColumn, +} + +impl GossipVerifiedDataColumn { + pub fn new( + column_sidecar: Arc>, + subnet_id: u64, + chain: &BeaconChain, + ) -> Result { + let header = column_sidecar.signed_block_header.clone(); + // We only process slashing info if the gossip verification failed + // since we do not process the data column any further in that case. + validate_data_column_sidecar_for_gossip(column_sidecar, subnet_id, chain).map_err(|e| { + process_block_slash_info::<_, GossipDataColumnError>( + chain, + BlockSlashInfo::from_early_error_data_column(header, e), + ) + }) + } + + pub fn id(&self) -> DataColumnIdentifier { + DataColumnIdentifier { + block_root: self.block_root, + index: self.data_column.data_column_index(), + } + } + + pub fn block_root(&self) -> Hash256 { + self.block_root + } + + pub fn slot(&self) -> Slot { + self.data_column.data.slot() + } + + pub fn signed_block_header(&self) -> SignedBeaconBlockHeader { + self.data_column.data.signed_block_header.clone() + } +} + +/// Wrapper over a `DataColumnSidecar` for which we have completed kzg verification. +#[derive(Debug, Derivative, Clone, Encode, Decode)] +#[derivative(PartialEq, Eq)] +#[ssz(struct_behaviour = "transparent")] +pub struct KzgVerifiedDataColumn { + data: Arc>, +} + +impl KzgVerifiedDataColumn { + pub fn new(data_column: Arc>, kzg: &Kzg) -> Result { + verify_kzg_for_data_column(data_column, kzg) + } + pub fn as_data_column(&self) -> &DataColumnSidecar { + &self.data + } + /// This is cheap as we're calling clone on an Arc + pub fn clone_data_column(&self) -> Arc> { + self.data.clone() + } + + pub fn data_column_index(&self) -> u64 { + self.data.index + } +} /// Data column that we must custody and has completed kzg verification #[derive(Debug, Derivative, Clone, Encode, Decode)] @@ -17,3 +153,48 @@ impl KzgVerifiedCustodyDataColumn { self.data.index } } + +/// Complete kzg verification for a `DataColumnSidecar`. +/// +/// Returns an error if the kzg verification check fails. +pub fn verify_kzg_for_data_column( + data_column: Arc>, + _kzg: &Kzg, +) -> Result, KzgError> { + // TODO(das): KZG verification to be implemented + Ok(KzgVerifiedDataColumn { data: data_column }) +} + +/// Complete kzg verification for a list of `DataColumnSidecar`s. +/// Returns an error if any of the `DataColumnSidecar`s fails kzg verification. +/// +/// Note: This function should be preferred over calling `verify_kzg_for_data_column` +/// in a loop since this function kzg verifies a list of data columns more efficiently. +pub fn verify_kzg_for_data_column_list<'a, E: EthSpec, I>( + _data_column_iter: I, + _kzg: &'a Kzg, +) -> Result<(), KzgError> +where + I: Iterator>> + Clone, +{ + // TODO(das): implement KZG verification + Ok(()) +} + +pub fn validate_data_column_sidecar_for_gossip( + data_column: Arc>, + _subnet: u64, + chain: &BeaconChain, +) -> Result, GossipDataColumnError> { + // TODO(das): implement gossip verification + let kzg = chain + .kzg + .clone() + .ok_or(GossipDataColumnError::KzgNotInitialized)?; + let kzg_verified_data_column = verify_kzg_for_data_column(data_column.clone(), &kzg) + .map_err(GossipDataColumnError::InvalidKzgProof)?; + Ok(GossipVerifiedDataColumn { + block_root: data_column.block_root(), + data_column: kzg_verified_data_column, + }) +} diff --git a/beacon_node/beacon_chain/src/lib.rs b/beacon_node/beacon_chain/src/lib.rs index 0fd000ff00..e1d0f61c58 100644 --- a/beacon_node/beacon_chain/src/lib.rs +++ b/beacon_node/beacon_chain/src/lib.rs @@ -19,7 +19,7 @@ pub mod canonical_head; pub mod capella_readiness; pub mod chain_config; pub mod data_availability_checker; -mod data_column_verification; +pub mod data_column_verification; pub mod deneb_readiness; mod early_attester_cache; pub mod electra_readiness; diff --git a/beacon_node/beacon_chain/src/metrics.rs b/beacon_node/beacon_chain/src/metrics.rs index 064b2b199f..ab547cb600 100644 --- a/beacon_node/beacon_chain/src/metrics.rs +++ b/beacon_node/beacon_chain/src/metrics.rs @@ -1048,6 +1048,18 @@ lazy_static! { "blob_sidecar_inclusion_proof_computation_seconds", "Time taken to compute blob sidecar inclusion proof" ); + pub static ref DATA_COLUMN_SIDECAR_PROCESSING_REQUESTS: Result = try_create_int_counter( + "beacon_data_column_sidecar_processing_requests_total", + "Count of all data column sidecars submitted for processing" + ); + pub static ref DATA_COLUMN_SIDECAR_PROCESSING_SUCCESSES: Result = try_create_int_counter( + "beacon_data_column_sidecar_processing_successes_total", + "Number of data column sidecars verified for gossip" + ); + pub static ref DATA_COLUMN_SIDECAR_GOSSIP_VERIFICATION_TIMES: Result = try_create_histogram( + "beacon_data_column_sidecar_gossip_verification_seconds", + "Full runtime of data column sidecars gossip verification" + ); } // Fifth lazy-static block is used to account for macro recursion limit. diff --git a/beacon_node/beacon_processor/src/lib.rs b/beacon_node/beacon_processor/src/lib.rs index 5bf13d82b7..f491dc7ffb 100644 --- a/beacon_node/beacon_processor/src/lib.rs +++ b/beacon_node/beacon_processor/src/lib.rs @@ -112,6 +112,7 @@ pub struct BeaconProcessorQueueLengths { backfill_chain_segment: usize, gossip_block_queue: usize, gossip_blob_queue: usize, + gossip_data_column_queue: usize, delayed_block_queue: usize, status_queue: usize, bbrange_queue: usize, @@ -164,6 +165,7 @@ impl BeaconProcessorQueueLengths { backfill_chain_segment: 64, gossip_block_queue: 1024, gossip_blob_queue: 1024, + gossip_data_column_queue: 1024, delayed_block_queue: 1024, status_queue: 1024, bbrange_queue: 1024, @@ -209,6 +211,7 @@ pub const GOSSIP_AGGREGATE: &str = "gossip_aggregate"; pub const GOSSIP_AGGREGATE_BATCH: &str = "gossip_aggregate_batch"; pub const GOSSIP_BLOCK: &str = "gossip_block"; pub const GOSSIP_BLOBS_SIDECAR: &str = "gossip_blobs_sidecar"; +pub const GOSSIP_BLOBS_COLUMN_SIDECAR: &str = "gossip_blobs_column_sidecar"; pub const DELAYED_IMPORT_BLOCK: &str = "delayed_import_block"; pub const GOSSIP_VOLUNTARY_EXIT: &str = "gossip_voluntary_exit"; pub const GOSSIP_PROPOSER_SLASHING: &str = "gossip_proposer_slashing"; @@ -577,6 +580,7 @@ pub enum Work { }, GossipBlock(AsyncFn), GossipBlobSidecar(AsyncFn), + GossipDataColumnSidecar(AsyncFn), DelayedImportBlock { beacon_block_slot: Slot, beacon_block_root: Hash256, @@ -629,6 +633,7 @@ impl Work { Work::GossipAggregateBatch { .. } => GOSSIP_AGGREGATE_BATCH, Work::GossipBlock(_) => GOSSIP_BLOCK, Work::GossipBlobSidecar(_) => GOSSIP_BLOBS_SIDECAR, + Work::GossipDataColumnSidecar(_) => GOSSIP_BLOBS_COLUMN_SIDECAR, Work::DelayedImportBlock { .. } => DELAYED_IMPORT_BLOCK, Work::GossipVoluntaryExit(_) => GOSSIP_VOLUNTARY_EXIT, Work::GossipProposerSlashing(_) => GOSSIP_PROPOSER_SLASHING, @@ -803,6 +808,7 @@ impl BeaconProcessor { let mut backfill_chain_segment = FifoQueue::new(queue_lengths.backfill_chain_segment); let mut gossip_block_queue = FifoQueue::new(queue_lengths.gossip_block_queue); let mut gossip_blob_queue = FifoQueue::new(queue_lengths.gossip_blob_queue); + let mut gossip_data_column_queue = FifoQueue::new(queue_lengths.gossip_data_column_queue); let mut delayed_block_queue = FifoQueue::new(queue_lengths.delayed_block_queue); let mut status_queue = FifoQueue::new(queue_lengths.status_queue); @@ -961,6 +967,8 @@ impl BeaconProcessor { self.spawn_worker(item, idle_tx); } else if let Some(item) = gossip_blob_queue.pop() { self.spawn_worker(item, idle_tx); + } else if let Some(item) = gossip_data_column_queue.pop() { + self.spawn_worker(item, idle_tx); // Check the priority 0 API requests after blocks and blobs, but before attestations. } else if let Some(item) = api_request_p0_queue.pop() { self.spawn_worker(item, idle_tx); @@ -1208,6 +1216,9 @@ impl BeaconProcessor { Work::GossipBlobSidecar { .. } => { gossip_blob_queue.push(work, work_id, &self.log) } + Work::GossipDataColumnSidecar { .. } => { + gossip_data_column_queue.push(work, work_id, &self.log) + } Work::DelayedImportBlock { .. } => { delayed_block_queue.push(work, work_id, &self.log) } @@ -1312,6 +1323,10 @@ impl BeaconProcessor { &metrics::BEACON_PROCESSOR_GOSSIP_BLOB_QUEUE_TOTAL, gossip_blob_queue.len() as i64, ); + metrics::set_gauge( + &metrics::BEACON_PROCESSOR_GOSSIP_DATA_COLUMN_QUEUE_TOTAL, + gossip_data_column_queue.len() as i64, + ); metrics::set_gauge( &metrics::BEACON_PROCESSOR_RPC_BLOCK_QUEUE_TOTAL, rpc_block_queue.len() as i64, @@ -1463,11 +1478,11 @@ impl BeaconProcessor { task_spawner.spawn_async(process_fn) } Work::IgnoredRpcBlock { process_fn } => task_spawner.spawn_blocking(process_fn), - Work::GossipBlock(work) | Work::GossipBlobSidecar(work) => { - task_spawner.spawn_async(async move { - work.await; - }) - } + Work::GossipBlock(work) + | Work::GossipBlobSidecar(work) + | Work::GossipDataColumnSidecar(work) => task_spawner.spawn_async(async move { + work.await; + }), Work::BlobsByRangeRequest(process_fn) | Work::BlobsByRootsRequest(process_fn) => { task_spawner.spawn_blocking(process_fn) } diff --git a/beacon_node/beacon_processor/src/metrics.rs b/beacon_node/beacon_processor/src/metrics.rs index fa7d7d7b9a..bcd422b357 100644 --- a/beacon_node/beacon_processor/src/metrics.rs +++ b/beacon_node/beacon_processor/src/metrics.rs @@ -51,6 +51,11 @@ lazy_static::lazy_static! { "beacon_processor_gossip_blob_queue_total", "Count of blobs from gossip waiting to be verified." ); + // Gossip data column sidecars. + pub static ref BEACON_PROCESSOR_GOSSIP_DATA_COLUMN_QUEUE_TOTAL: Result = try_create_int_gauge( + "beacon_processor_gossip_data_column_queue_total", + "Count of data column sidecars from gossip waiting to be verified." + ); // Gossip Exits. pub static ref BEACON_PROCESSOR_EXIT_QUEUE_TOTAL: Result = try_create_int_gauge( "beacon_processor_exit_queue_total", diff --git a/beacon_node/execution_layer/Cargo.toml b/beacon_node/execution_layer/Cargo.toml index ff147ad3b4..f9f599c769 100644 --- a/beacon_node/execution_layer/Cargo.toml +++ b/beacon_node/execution_layer/Cargo.toml @@ -6,6 +6,7 @@ edition = { workspace = true } # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +alloy-primitives = { workspace = true } types = { workspace = true } tokio = { workspace = true } slog = { workspace = true } @@ -48,6 +49,6 @@ hash-db = "0.15.2" pretty_reqwest_error = { workspace = true } arc-swap = "1.6.0" eth2_network_config = { workspace = true } -alloy-rlp = "0.3" -alloy-consensus = { git = "https://github.com/alloy-rs/alloy.git", rev = "974d488bab5e21e9f17452a39a4bfa56677367b2" } +alloy-rlp = { workspace = true } +alloy-consensus = { workspace = true } lighthouse_version = { workspace = true } diff --git a/beacon_node/execution_layer/src/block_hash.rs b/beacon_node/execution_layer/src/block_hash.rs index 0d0cfaf352..10edb7b2fd 100644 --- a/beacon_node/execution_layer/src/block_hash.rs +++ b/beacon_node/execution_layer/src/block_hash.rs @@ -1,13 +1,13 @@ use crate::{ - json_structures::JsonWithdrawal, + json_structures::{EncodableJsonWithdrawal, JsonWithdrawal}, keccak::{keccak256, KeccakHasher}, }; -use ethers_core::utils::rlp::RlpStream; +use alloy_rlp::Encodable; use keccak_hash::KECCAK_EMPTY_LIST_RLP; use triehash::ordered_trie_root; use types::{ - map_execution_block_header_fields_base, Address, EthSpec, ExecutionBlockHash, - ExecutionBlockHeader, ExecutionPayloadRef, Hash256, Hash64, Uint256, + EncodableExecutionBlockHeader, EthSpec, ExecutionBlockHash, ExecutionBlockHeader, + ExecutionPayloadRef, Hash256, }; /// Calculate the block hash of an execution block. @@ -60,36 +60,16 @@ pub fn calculate_execution_block_hash( /// RLP encode a withdrawal. pub fn rlp_encode_withdrawal(withdrawal: &JsonWithdrawal) -> Vec { - let mut rlp_stream = RlpStream::new(); - rlp_stream.begin_list(4); - rlp_stream.append(&withdrawal.index); - rlp_stream.append(&withdrawal.validator_index); - rlp_stream.append(&withdrawal.address); - rlp_stream.append(&withdrawal.amount); - rlp_stream.out().into() + let mut out: Vec = vec![]; + EncodableJsonWithdrawal::from(withdrawal).encode(&mut out); + out } /// RLP encode an execution block header. pub fn rlp_encode_block_header(header: &ExecutionBlockHeader) -> Vec { - let mut rlp_header_stream = RlpStream::new(); - rlp_header_stream.begin_unbounded_list(); - map_execution_block_header_fields_base!(&header, |_, field| { - rlp_header_stream.append(field); - }); - if let Some(withdrawals_root) = &header.withdrawals_root { - rlp_header_stream.append(withdrawals_root); - } - if let Some(blob_gas_used) = &header.blob_gas_used { - rlp_header_stream.append(blob_gas_used); - } - if let Some(excess_blob_gas) = &header.excess_blob_gas { - rlp_header_stream.append(excess_blob_gas); - } - if let Some(parent_beacon_block_root) = &header.parent_beacon_block_root { - rlp_header_stream.append(parent_beacon_block_root); - } - rlp_header_stream.finalize_unbounded_list(); - rlp_header_stream.out().into() + let mut out: Vec = vec![]; + EncodableExecutionBlockHeader::from(header).encode(&mut out); + out } #[cfg(test)] @@ -97,6 +77,7 @@ mod test { use super::*; use hex::FromHex; use std::str::FromStr; + use types::{Address, Hash256, Hash64}; fn test_rlp_encoding( header: &ExecutionBlockHeader, diff --git a/beacon_node/execution_layer/src/engine_api/json_structures.rs b/beacon_node/execution_layer/src/engine_api/json_structures.rs index fbffc47e29..f654ba4a0e 100644 --- a/beacon_node/execution_layer/src/engine_api/json_structures.rs +++ b/beacon_node/execution_layer/src/engine_api/json_structures.rs @@ -1,4 +1,5 @@ use super::*; +use alloy_rlp::RlpEncodable; use serde::{Deserialize, Serialize}; use strum::EnumString; use superstruct::superstruct; @@ -463,6 +464,24 @@ impl From for Withdrawal { } } } +#[derive(Debug, PartialEq, Clone, RlpEncodable)] +pub struct EncodableJsonWithdrawal<'a> { + pub index: u64, + pub validator_index: u64, + pub address: &'a [u8], + pub amount: u64, +} + +impl<'a> From<&'a JsonWithdrawal> for EncodableJsonWithdrawal<'a> { + fn from(json_withdrawal: &'a JsonWithdrawal) -> Self { + Self { + index: json_withdrawal.index, + validator_index: json_withdrawal.validator_index, + address: json_withdrawal.address.as_bytes(), + amount: json_withdrawal.amount, + } + } +} #[superstruct( variants(V1, V2, V3), diff --git a/beacon_node/execution_layer/src/keccak.rs b/beacon_node/execution_layer/src/keccak.rs index c4c9689272..62e354d503 100644 --- a/beacon_node/execution_layer/src/keccak.rs +++ b/beacon_node/execution_layer/src/keccak.rs @@ -16,7 +16,7 @@ use hash_db::Hasher; use types::Hash256; pub fn keccak256(bytes: &[u8]) -> Hash256 { - Hash256::from(ethers_core::utils::keccak256(bytes)) + Hash256::from(alloy_primitives::utils::keccak256(bytes).as_ref()) } /// Keccak hasher. diff --git a/beacon_node/execution_layer/src/versioned_hashes.rs b/beacon_node/execution_layer/src/versioned_hashes.rs index 9bf87596b4..97c3100de9 100644 --- a/beacon_node/execution_layer/src/versioned_hashes.rs +++ b/beacon_node/execution_layer/src/versioned_hashes.rs @@ -42,22 +42,17 @@ pub fn extract_versioned_hashes_from_transactions( let mut versioned_hashes = Vec::new(); for tx in transactions { - match beacon_tx_to_tx_envelope(tx)? { - TxEnvelope::Eip4844(signed_tx_eip4844) => { - versioned_hashes.extend( - signed_tx_eip4844 - .tx() - .blob_versioned_hashes - .iter() - .map(|fb| Hash256::from(fb.0)), - ); - } - // enumerating all variants explicitly to make pattern irrefutable - // in case new types are added in the future which also have blobs - TxEnvelope::Legacy(_) - | TxEnvelope::TaggedLegacy(_) - | TxEnvelope::Eip2930(_) - | TxEnvelope::Eip1559(_) => {} + // TxEnvelope is non-exhaustive so unforunately we can (no longer) write an exhaustive + // match here. + if let TxEnvelope::Eip4844(signed_tx_eip4844) = beacon_tx_to_tx_envelope(tx)? { + versioned_hashes.extend( + signed_tx_eip4844 + .tx() + .tx() + .blob_versioned_hashes + .iter() + .map(|fb| Hash256::from(fb.0)), + ); } } @@ -76,7 +71,8 @@ pub fn beacon_tx_to_tx_envelope( mod test { use super::*; use crate::test_utils::static_valid_tx; - use alloy_consensus::{TxKind, TxLegacy}; + use alloy_consensus::TxLegacy; + use alloy_primitives::TxKind; type E = types::MainnetEthSpec; diff --git a/beacon_node/http_api/src/lib.rs b/beacon_node/http_api/src/lib.rs index cec5ff621c..ce62ed63f2 100644 --- a/beacon_node/http_api/src/lib.rs +++ b/beacon_node/http_api/src/lib.rs @@ -2889,8 +2889,8 @@ pub fn serve( let syncing_data = api_types::SyncingData { is_syncing: !network_globals.sync_state.read().is_synced(), - is_optimistic: Some(is_optimistic), - el_offline: Some(el_offline), + is_optimistic, + el_offline, head_slot, sync_distance, }; diff --git a/beacon_node/http_api/tests/status_tests.rs b/beacon_node/http_api/tests/status_tests.rs index d37026d406..801cd44074 100644 --- a/beacon_node/http_api/tests/status_tests.rs +++ b/beacon_node/http_api/tests/status_tests.rs @@ -56,8 +56,8 @@ async fn el_syncing_then_synced() { mock_el.el.upcheck().await; let api_response = tester.client.get_node_syncing().await.unwrap().data; - assert_eq!(api_response.el_offline, Some(false)); - assert_eq!(api_response.is_optimistic, Some(false)); + assert_eq!(api_response.el_offline, false); + assert_eq!(api_response.is_optimistic, false); assert_eq!(api_response.is_syncing, false); // EL synced @@ -65,8 +65,8 @@ async fn el_syncing_then_synced() { mock_el.el.upcheck().await; let api_response = tester.client.get_node_syncing().await.unwrap().data; - assert_eq!(api_response.el_offline, Some(false)); - assert_eq!(api_response.is_optimistic, Some(false)); + assert_eq!(api_response.el_offline, false); + assert_eq!(api_response.is_optimistic, false); assert_eq!(api_response.is_syncing, false); } @@ -84,8 +84,8 @@ async fn el_offline() { mock_el.el.upcheck().await; let api_response = tester.client.get_node_syncing().await.unwrap().data; - assert_eq!(api_response.el_offline, Some(true)); - assert_eq!(api_response.is_optimistic, Some(false)); + assert_eq!(api_response.el_offline, true); + assert_eq!(api_response.is_optimistic, false); assert_eq!(api_response.is_syncing, false); } @@ -127,8 +127,8 @@ async fn el_error_on_new_payload() { // The EL should now be *offline* according to the API. let api_response = tester.client.get_node_syncing().await.unwrap().data; - assert_eq!(api_response.el_offline, Some(true)); - assert_eq!(api_response.is_optimistic, Some(false)); + assert_eq!(api_response.el_offline, true); + assert_eq!(api_response.is_optimistic, false); assert_eq!(api_response.is_syncing, false); // Processing a block successfully should remove the status. @@ -143,8 +143,8 @@ async fn el_error_on_new_payload() { harness.process_block_result((block, blobs)).await.unwrap(); let api_response = tester.client.get_node_syncing().await.unwrap().data; - assert_eq!(api_response.el_offline, Some(false)); - assert_eq!(api_response.is_optimistic, Some(false)); + assert_eq!(api_response.el_offline, false); + assert_eq!(api_response.is_optimistic, false); assert_eq!(api_response.is_syncing, false); } diff --git a/beacon_node/http_api/tests/tests.rs b/beacon_node/http_api/tests/tests.rs index 0733b60f7d..d51799b866 100644 --- a/beacon_node/http_api/tests/tests.rs +++ b/beacon_node/http_api/tests/tests.rs @@ -2159,9 +2159,9 @@ impl ApiTester { let expected = SyncingData { is_syncing: false, - is_optimistic: Some(false), + is_optimistic: false, // these tests run without the Bellatrix fork enabled - el_offline: Some(true), + el_offline: true, head_slot, sync_distance, }; diff --git a/beacon_node/lighthouse_network/Cargo.toml b/beacon_node/lighthouse_network/Cargo.toml index 56a8fe99c7..3dfa24d467 100644 --- a/beacon_node/lighthouse_network/Cargo.toml +++ b/beacon_node/lighthouse_network/Cargo.toml @@ -43,6 +43,7 @@ unused_port = { workspace = true } delay_map = { workspace = true } bytes = { workspace = true } either = { workspace = true } +itertools = { workspace = true } # Local dependencies void = "1.0.2" diff --git a/beacon_node/lighthouse_network/src/discovery/mod.rs b/beacon_node/lighthouse_network/src/discovery/mod.rs index 73f51c001a..017db26049 100644 --- a/beacon_node/lighthouse_network/src/discovery/mod.rs +++ b/beacon_node/lighthouse_network/src/discovery/mod.rs @@ -43,7 +43,7 @@ use std::{ time::{Duration, Instant}, }; use tokio::sync::mpsc; -use types::{EnrForkId, EthSpec}; +use types::{ChainSpec, EnrForkId, EthSpec}; mod subnet_predicate; pub use subnet_predicate::subnet_predicate; @@ -192,6 +192,7 @@ pub struct Discovery { /// Logger for the discovery behaviour. log: slog::Logger, + spec: Arc, } impl Discovery { @@ -201,6 +202,7 @@ impl Discovery { config: &NetworkConfig, network_globals: Arc>, log: &slog::Logger, + spec: &ChainSpec, ) -> error::Result { let log = log.clone(); @@ -325,6 +327,7 @@ impl Discovery { update_ports, log, enr_dir, + spec: Arc::new(spec.clone()), }) } @@ -548,6 +551,8 @@ impl Discovery { ) .map_err(|e| format!("{:?}", e))?; } + // Data column subnets are computed from node ID. No subnet bitfield in the ENR. + Subnet::DataColumn(_) => return Ok(()), } // replace the global version @@ -753,7 +758,8 @@ impl Discovery { // Only start a discovery query if we have a subnet to look for. if !filtered_subnet_queries.is_empty() { // build the subnet predicate as a combination of the eth2_fork_predicate and the subnet predicate - let subnet_predicate = subnet_predicate::(filtered_subnets, &self.log); + let subnet_predicate = + subnet_predicate::(filtered_subnets, &self.log, self.spec.clone()); debug!( self.log, @@ -867,6 +873,7 @@ impl Discovery { let query_str = match query.subnet { Subnet::Attestation(_) => "attestation", Subnet::SyncCommittee(_) => "sync_committee", + Subnet::DataColumn(_) => "data_column", }; if let Some(v) = metrics::get_int_counter( @@ -879,8 +886,11 @@ impl Discovery { self.add_subnet_query(query.subnet, query.min_ttl, query.retries + 1); // Check the specific subnet against the enr - let subnet_predicate = - subnet_predicate::(vec![query.subnet], &self.log); + let subnet_predicate = subnet_predicate::( + vec![query.subnet], + &self.log, + self.spec.clone(), + ); r.clone() .into_iter() @@ -1194,6 +1204,7 @@ mod tests { } async fn build_discovery() -> Discovery { + let spec = ChainSpec::default(); let keypair = secp256k1::Keypair::generate(); let mut config = NetworkConfig::default(); config.set_listening_addr(crate::ListenAddress::unused_v4_ports()); @@ -1212,7 +1223,7 @@ mod tests { &log, ); let keypair = keypair.into(); - Discovery::new(keypair, &config, Arc::new(globals), &log) + Discovery::new(keypair, &config, Arc::new(globals), &log, &spec) .await .unwrap() } diff --git a/beacon_node/lighthouse_network/src/discovery/subnet_predicate.rs b/beacon_node/lighthouse_network/src/discovery/subnet_predicate.rs index 1aabf12b72..b53afe556d 100644 --- a/beacon_node/lighthouse_network/src/discovery/subnet_predicate.rs +++ b/beacon_node/lighthouse_network/src/discovery/subnet_predicate.rs @@ -1,11 +1,17 @@ //! The subnet predicate used for searching for a particular subnet. use super::*; use crate::types::{EnrAttestationBitfield, EnrSyncCommitteeBitfield}; +use itertools::Itertools; use slog::trace; use std::ops::Deref; +use types::{ChainSpec, DataColumnSubnetId}; /// Returns the predicate for a given subnet. -pub fn subnet_predicate(subnets: Vec, log: &slog::Logger) -> impl Fn(&Enr) -> bool + Send +pub fn subnet_predicate( + subnets: Vec, + log: &slog::Logger, + spec: Arc, +) -> impl Fn(&Enr) -> bool + Send where E: EthSpec, { @@ -19,10 +25,13 @@ where }; // Pre-fork/fork-boundary enrs may not contain a syncnets field. - // Don't return early here + // Don't return early here. let sync_committee_bitfield: Result, _> = enr.sync_committee_bitfield::(); + // TODO(das): compute from enr + let custody_subnet_count = spec.custody_requirement; + let predicate = subnets.iter().any(|subnet| match subnet { Subnet::Attestation(s) => attestation_bitfield .get(*s.deref() as usize) @@ -30,6 +39,14 @@ where Subnet::SyncCommittee(s) => sync_committee_bitfield .as_ref() .map_or(false, |b| b.get(*s.deref() as usize).unwrap_or(false)), + Subnet::DataColumn(s) => { + let mut subnets = DataColumnSubnetId::compute_custody_subnets::( + enr.node_id().raw().into(), + custody_subnet_count, + &spec, + ); + subnets.contains(s) + } }); if !predicate { diff --git a/beacon_node/lighthouse_network/src/peer_manager/mod.rs b/beacon_node/lighthouse_network/src/peer_manager/mod.rs index 0d9a7c60dd..c86c2098d6 100644 --- a/beacon_node/lighthouse_network/src/peer_manager/mod.rs +++ b/beacon_node/lighthouse_network/src/peer_manager/mod.rs @@ -1027,6 +1027,10 @@ impl PeerManager { .or_default() .insert(id); } + // TODO(das) to be implemented. We're not pruning data column peers yet + // because data column topics are subscribed as core topics until we + // implement recomputing data column subnets. + Subnet::DataColumn(_) => {} } } } diff --git a/beacon_node/lighthouse_network/src/peer_manager/peerdb/peer_info.rs b/beacon_node/lighthouse_network/src/peer_manager/peerdb/peer_info.rs index ab113a1a04..0745cc2600 100644 --- a/beacon_node/lighthouse_network/src/peer_manager/peerdb/peer_info.rs +++ b/beacon_node/lighthouse_network/src/peer_manager/peerdb/peer_info.rs @@ -94,6 +94,15 @@ impl PeerInfo { .syncnets() .map_or(false, |s| s.get(**id as usize).unwrap_or(false)) } + Subnet::DataColumn(_) => { + // TODO(das): Pending spec PR https://github.com/ethereum/consensus-specs/pull/3821 + // We should use MetaDataV3 for peer selection rather than + // looking at subscribed peers (current behavior). Until MetaDataV3 is + // implemented, this is the perhaps the only viable option on the current devnet + // as the peer count is low and it's important to identify supernodes to get a + // good distribution of peers across subnets. + return true; + } } } false diff --git a/beacon_node/lighthouse_network/src/service/gossip_cache.rs b/beacon_node/lighthouse_network/src/service/gossip_cache.rs index 158c7a994a..0ad31ff2e8 100644 --- a/beacon_node/lighthouse_network/src/service/gossip_cache.rs +++ b/beacon_node/lighthouse_network/src/service/gossip_cache.rs @@ -22,6 +22,8 @@ pub struct GossipCache { beacon_block: Option, /// Timeout for blobs. blob_sidecar: Option, + /// Timeout for data columns. + data_column_sidecar: Option, /// Timeout for aggregate attestations. aggregates: Option, /// Timeout for attestations. @@ -51,6 +53,8 @@ pub struct GossipCacheBuilder { beacon_block: Option, /// Timeout for blob sidecars. blob_sidecar: Option, + /// Timeout for data column sidecars. + data_column_sidecar: Option, /// Timeout for aggregate attestations. aggregates: Option, /// Timeout for attestations. @@ -152,6 +156,7 @@ impl GossipCacheBuilder { default_timeout, beacon_block, blob_sidecar, + data_column_sidecar, aggregates, attestation, voluntary_exit, @@ -168,6 +173,7 @@ impl GossipCacheBuilder { topic_msgs: HashMap::default(), beacon_block: beacon_block.or(default_timeout), blob_sidecar: blob_sidecar.or(default_timeout), + data_column_sidecar: data_column_sidecar.or(default_timeout), aggregates: aggregates.or(default_timeout), attestation: attestation.or(default_timeout), voluntary_exit: voluntary_exit.or(default_timeout), @@ -194,6 +200,7 @@ impl GossipCache { let expire_timeout = match topic.kind() { GossipKind::BeaconBlock => self.beacon_block, GossipKind::BlobSidecar(_) => self.blob_sidecar, + GossipKind::DataColumnSidecar(_) => self.data_column_sidecar, GossipKind::BeaconAggregateAndProof => self.aggregates, GossipKind::Attestation(_) => self.attestation, GossipKind::VoluntaryExit => self.voluntary_exit, diff --git a/beacon_node/lighthouse_network/src/service/mod.rs b/beacon_node/lighthouse_network/src/service/mod.rs index 3d502e6fdc..aaf9dda523 100644 --- a/beacon_node/lighthouse_network/src/service/mod.rs +++ b/beacon_node/lighthouse_network/src/service/mod.rs @@ -39,10 +39,10 @@ use std::{ sync::Arc, task::{Context, Poll}, }; -use types::ForkName; use types::{ consts::altair::SYNC_COMMITTEE_SUBNET_COUNT, EnrForkId, EthSpec, ForkContext, Slot, SubnetId, }; +use types::{ChainSpec, ForkName}; use utils::{build_transport, strip_peer_id, Context as ServiceContext, MAX_CONNECTIONS_PER_PEER}; pub mod api_types; @@ -327,6 +327,7 @@ impl Network { &config, network_globals.clone(), &log, + ctx.chain_spec, ) .await?; // start searching for peers @@ -385,7 +386,7 @@ impl Network { let upnp = Toggle::from( config .upnp_enabled - .then_some(libp2p::upnp::tokio::Behaviour::default()), + .then(libp2p::upnp::tokio::Behaviour::default), ); let behaviour = { Behaviour { @@ -1018,6 +1019,7 @@ impl Network { return; } + let spec = Arc::new(self.fork_context.spec.clone()); let filtered: Vec = subnets_to_discover .into_iter() .filter(|s| { @@ -1053,7 +1055,7 @@ impl Network { // If we connect to the cached peers before the discovery query starts, then we potentially // save a costly discovery query. } else { - self.dial_cached_enrs_in_subnet(s.subnet); + self.dial_cached_enrs_in_subnet(s.subnet, spec.clone()); true } }) @@ -1217,8 +1219,8 @@ impl Network { /// Dial cached Enrs in discovery service that are in the given `subnet_id` and aren't /// in Connected, Dialing or Banned state. - fn dial_cached_enrs_in_subnet(&mut self, subnet: Subnet) { - let predicate = subnet_predicate::(vec![subnet], &self.log); + fn dial_cached_enrs_in_subnet(&mut self, subnet: Subnet, spec: Arc) { + let predicate = subnet_predicate::(vec![subnet], &self.log, spec); let peers_to_dial: Vec = self .discovery() .cached_enrs() diff --git a/beacon_node/lighthouse_network/src/types/pubsub.rs b/beacon_node/lighthouse_network/src/types/pubsub.rs index b443ecd1b9..1bc99f9a6c 100644 --- a/beacon_node/lighthouse_network/src/types/pubsub.rs +++ b/beacon_node/lighthouse_network/src/types/pubsub.rs @@ -8,13 +8,13 @@ use std::io::{Error, ErrorKind}; use std::sync::Arc; use types::{ Attestation, AttestationBase, AttestationElectra, AttesterSlashing, AttesterSlashingBase, - AttesterSlashingElectra, BlobSidecar, EthSpec, ForkContext, ForkName, - LightClientFinalityUpdate, LightClientOptimisticUpdate, ProposerSlashing, - SignedAggregateAndProof, SignedAggregateAndProofBase, SignedAggregateAndProofElectra, - SignedBeaconBlock, SignedBeaconBlockAltair, SignedBeaconBlockBase, SignedBeaconBlockBellatrix, - SignedBeaconBlockCapella, SignedBeaconBlockDeneb, SignedBeaconBlockElectra, - SignedBlsToExecutionChange, SignedContributionAndProof, SignedVoluntaryExit, SubnetId, - SyncCommitteeMessage, SyncSubnetId, + AttesterSlashingElectra, BlobSidecar, DataColumnSidecar, DataColumnSubnetId, EthSpec, + ForkContext, ForkName, LightClientFinalityUpdate, LightClientOptimisticUpdate, + ProposerSlashing, SignedAggregateAndProof, SignedAggregateAndProofBase, + SignedAggregateAndProofElectra, SignedBeaconBlock, SignedBeaconBlockAltair, + SignedBeaconBlockBase, SignedBeaconBlockBellatrix, SignedBeaconBlockCapella, + SignedBeaconBlockDeneb, SignedBeaconBlockElectra, SignedBlsToExecutionChange, + SignedContributionAndProof, SignedVoluntaryExit, SubnetId, SyncCommitteeMessage, SyncSubnetId, }; #[derive(Debug, Clone, PartialEq)] @@ -23,6 +23,8 @@ pub enum PubsubMessage { BeaconBlock(Arc>), /// Gossipsub message providing notification of a [`BlobSidecar`] along with the subnet id where it was received. BlobSidecar(Box<(u64, Arc>)>), + /// Gossipsub message providing notification of a [`DataColumnSidecar`] along with the subnet id where it was received. + DataColumnSidecar(Box<(DataColumnSubnetId, Arc>)>), /// Gossipsub message providing notification of a Aggregate attestation and associated proof. AggregateAndProofAttestation(Box>), /// Gossipsub message providing notification of a raw un-aggregated attestation with its shard id. @@ -119,6 +121,9 @@ impl PubsubMessage { PubsubMessage::BlobSidecar(blob_sidecar_data) => { GossipKind::BlobSidecar(blob_sidecar_data.0) } + PubsubMessage::DataColumnSidecar(column_sidecar_data) => { + GossipKind::DataColumnSidecar(column_sidecar_data.0) + } PubsubMessage::AggregateAndProofAttestation(_) => GossipKind::BeaconAggregateAndProof, PubsubMessage::Attestation(attestation_data) => { GossipKind::Attestation(attestation_data.0) @@ -270,6 +275,36 @@ impl PubsubMessage { )), } } + GossipKind::DataColumnSidecar(subnet_id) => { + match fork_context.from_context_bytes(gossip_topic.fork_digest) { + // TODO(das): Remove Deneb fork + Some(fork) if fork.deneb_enabled() => { + let col_sidecar = Arc::new( + DataColumnSidecar::from_ssz_bytes(data) + .map_err(|e| format!("{:?}", e))?, + ); + let peer_das_enabled = + fork_context.spec.is_peer_das_enabled_for_epoch( + col_sidecar.slot().epoch(E::slots_per_epoch()), + ); + if peer_das_enabled { + Ok(PubsubMessage::DataColumnSidecar(Box::new(( + *subnet_id, + col_sidecar, + )))) + } else { + Err(format!( + "data_column_sidecar topic invalid for given fork digest {:?}", + gossip_topic.fork_digest + )) + } + } + Some(_) | None => Err(format!( + "data_column_sidecar topic invalid for given fork digest {:?}", + gossip_topic.fork_digest + )), + } + } GossipKind::VoluntaryExit => { let voluntary_exit = SignedVoluntaryExit::from_ssz_bytes(data) .map_err(|e| format!("{:?}", e))?; @@ -373,6 +408,7 @@ impl PubsubMessage { match &self { PubsubMessage::BeaconBlock(data) => data.as_ssz_bytes(), PubsubMessage::BlobSidecar(data) => data.1.as_ssz_bytes(), + PubsubMessage::DataColumnSidecar(data) => data.1.as_ssz_bytes(), PubsubMessage::AggregateAndProofAttestation(data) => data.as_ssz_bytes(), PubsubMessage::VoluntaryExit(data) => data.as_ssz_bytes(), PubsubMessage::ProposerSlashing(data) => data.as_ssz_bytes(), @@ -402,6 +438,12 @@ impl std::fmt::Display for PubsubMessage { data.1.slot(), data.1.index, ), + PubsubMessage::DataColumnSidecar(data) => write!( + f, + "DataColumnSidecar: slot: {}, column index: {}", + data.1.slot(), + data.1.index, + ), PubsubMessage::AggregateAndProofAttestation(att) => write!( f, "Aggregate and Proof: slot: {}, index: {:?}, aggregator_index: {}", diff --git a/beacon_node/lighthouse_network/src/types/subnet.rs b/beacon_node/lighthouse_network/src/types/subnet.rs index 50d28542be..1892dcc83a 100644 --- a/beacon_node/lighthouse_network/src/types/subnet.rs +++ b/beacon_node/lighthouse_network/src/types/subnet.rs @@ -1,6 +1,6 @@ use serde::Serialize; use std::time::Instant; -use types::{SubnetId, SyncSubnetId}; +use types::{DataColumnSubnetId, SubnetId, SyncSubnetId}; /// Represents a subnet on an attestation or sync committee `SubnetId`. /// @@ -12,6 +12,8 @@ pub enum Subnet { Attestation(SubnetId), /// Represents a gossipsub sync committee subnet and the metadata `syncnets` field. SyncCommittee(SyncSubnetId), + /// Represents a gossipsub data column subnet. + DataColumn(DataColumnSubnetId), } /// A subnet to discover peers on along with the instant after which it's no longer useful. diff --git a/beacon_node/lighthouse_network/src/types/topics.rs b/beacon_node/lighthouse_network/src/types/topics.rs index c5f4b0c9eb..174787f999 100644 --- a/beacon_node/lighthouse_network/src/types/topics.rs +++ b/beacon_node/lighthouse_network/src/types/topics.rs @@ -1,7 +1,7 @@ use gossipsub::{IdentTopic as Topic, TopicHash}; use serde::{Deserialize, Serialize}; use strum::AsRefStr; -use types::{ChainSpec, EthSpec, ForkName, SubnetId, SyncSubnetId, Unsigned}; +use types::{ChainSpec, DataColumnSubnetId, EthSpec, ForkName, SubnetId, SyncSubnetId, Unsigned}; use crate::Subnet; @@ -14,6 +14,7 @@ pub const BEACON_BLOCK_TOPIC: &str = "beacon_block"; pub const BEACON_AGGREGATE_AND_PROOF_TOPIC: &str = "beacon_aggregate_and_proof"; pub const BEACON_ATTESTATION_PREFIX: &str = "beacon_attestation_"; pub const BLOB_SIDECAR_PREFIX: &str = "blob_sidecar_"; +pub const DATA_COLUMN_SIDECAR_PREFIX: &str = "data_column_sidecar_"; pub const VOLUNTARY_EXIT_TOPIC: &str = "voluntary_exit"; pub const PROPOSER_SLASHING_TOPIC: &str = "proposer_slashing"; pub const ATTESTER_SLASHING_TOPIC: &str = "attester_slashing"; @@ -112,6 +113,8 @@ pub enum GossipKind { BeaconAggregateAndProof, /// Topic for publishing BlobSidecars. BlobSidecar(u64), + /// Topic for publishing DataColumnSidecars. + DataColumnSidecar(DataColumnSubnetId), /// Topic for publishing raw attestations on a particular subnet. #[strum(serialize = "beacon_attestation")] Attestation(SubnetId), @@ -144,6 +147,9 @@ impl std::fmt::Display for GossipKind { GossipKind::BlobSidecar(blob_index) => { write!(f, "{}{}", BLOB_SIDECAR_PREFIX, blob_index) } + GossipKind::DataColumnSidecar(column_index) => { + write!(f, "{}{}", DATA_COLUMN_SIDECAR_PREFIX, **column_index) + } x => f.write_str(x.as_ref()), } } @@ -231,6 +237,7 @@ impl GossipTopic { match self.kind() { GossipKind::Attestation(subnet_id) => Some(Subnet::Attestation(*subnet_id)), GossipKind::SyncCommitteeMessage(subnet_id) => Some(Subnet::SyncCommittee(*subnet_id)), + GossipKind::DataColumnSidecar(subnet_id) => Some(Subnet::DataColumn(*subnet_id)), _ => None, } } @@ -269,6 +276,9 @@ impl std::fmt::Display for GossipTopic { GossipKind::BlobSidecar(blob_index) => { format!("{}{}", BLOB_SIDECAR_PREFIX, blob_index) } + GossipKind::DataColumnSidecar(index) => { + format!("{}{}", DATA_COLUMN_SIDECAR_PREFIX, *index) + } GossipKind::BlsToExecutionChange => BLS_TO_EXECUTION_CHANGE_TOPIC.into(), GossipKind::LightClientFinalityUpdate => LIGHT_CLIENT_FINALITY_UPDATE.into(), GossipKind::LightClientOptimisticUpdate => LIGHT_CLIENT_OPTIMISTIC_UPDATE.into(), @@ -289,6 +299,7 @@ impl From for GossipKind { match subnet_id { Subnet::Attestation(s) => GossipKind::Attestation(s), Subnet::SyncCommittee(s) => GossipKind::SyncCommitteeMessage(s), + Subnet::DataColumn(s) => GossipKind::DataColumnSidecar(s), } } } @@ -312,6 +323,10 @@ fn subnet_topic_index(topic: &str) -> Option { ))); } else if let Some(index) = topic.strip_prefix(BLOB_SIDECAR_PREFIX) { return Some(GossipKind::BlobSidecar(index.parse::().ok()?)); + } else if let Some(index) = topic.strip_prefix(DATA_COLUMN_SIDECAR_PREFIX) { + return Some(GossipKind::DataColumnSidecar(DataColumnSubnetId::new( + index.parse::().ok()?, + ))); } None } diff --git a/beacon_node/network/src/metrics.rs b/beacon_node/network/src/metrics.rs index f0dba8d965..0fadb51edb 100644 --- a/beacon_node/network/src/metrics.rs +++ b/beacon_node/network/src/metrics.rs @@ -72,6 +72,10 @@ lazy_static! { "beacon_processor_gossip_blob_verified_total", "Total number of gossip blob verified for propagation." ); + pub static ref BEACON_PROCESSOR_GOSSIP_DATA_COLUMN_SIDECAR_VERIFIED_TOTAL: Result = try_create_int_counter( + "beacon_processor_gossip_data_column_verified_total", + "Total number of gossip data column sidecar verified for propagation." + ); // Gossip Exits. pub static ref BEACON_PROCESSOR_EXIT_VERIFIED_TOTAL: Result = try_create_int_counter( "beacon_processor_exit_verified_total", @@ -357,6 +361,22 @@ lazy_static! { "Count of times when a gossip blob arrived from the network later than the attestation deadline.", ); + pub static ref BEACON_DATA_COLUMN_DELAY_GOSSIP: Result = try_create_int_gauge( + "beacon_data_column_delay_gossip_last_delay", + "The first time we see this data column as a delay from the start of the slot" + ); + + pub static ref BEACON_DATA_COLUMN_DELAY_GOSSIP_VERIFICATION: Result = try_create_int_gauge( + "beacon_data_column_delay_gossip_verification", + "Keeps track of the time delay from the start of the slot to the point we propagate the data column" + ); + + pub static ref BEACON_DATA_COLUMN_DELAY_FULL_VERIFICATION: Result = try_create_int_gauge( + "beacon_data_column_last_full_verification_delay", + "The time it takes to verify a beacon data column" + ); + + /* * Light client update reprocessing queue metrics. */ diff --git a/beacon_node/network/src/network_beacon_processor/gossip_methods.rs b/beacon_node/network/src/network_beacon_processor/gossip_methods.rs index ab25053258..781c447f81 100644 --- a/beacon_node/network/src/network_beacon_processor/gossip_methods.rs +++ b/beacon_node/network/src/network_beacon_processor/gossip_methods.rs @@ -6,6 +6,7 @@ use crate::{ }; use beacon_chain::blob_verification::{GossipBlobError, GossipVerifiedBlob}; use beacon_chain::block_verification_types::AsBlock; +use beacon_chain::data_column_verification::GossipVerifiedDataColumn; use beacon_chain::store::Error; use beacon_chain::{ attestation_verification::{self, Error as AttnError, VerifiedAttestation}, @@ -32,8 +33,9 @@ use store::hot_cold_store::HotColdDBError; use tokio::sync::mpsc; use types::{ beacon_block::BlockImportSource, Attestation, AttestationRef, AttesterSlashing, BlobSidecar, - EthSpec, Hash256, IndexedAttestation, LightClientFinalityUpdate, LightClientOptimisticUpdate, - ProposerSlashing, SignedAggregateAndProof, SignedBeaconBlock, SignedBlsToExecutionChange, + DataColumnSidecar, DataColumnSubnetId, EthSpec, Hash256, IndexedAttestation, + LightClientFinalityUpdate, LightClientOptimisticUpdate, ProposerSlashing, + SignedAggregateAndProof, SignedBeaconBlock, SignedBlsToExecutionChange, SignedContributionAndProof, SignedVoluntaryExit, Slot, SubnetId, SyncCommitteeMessage, SyncSubnetId, }; @@ -599,6 +601,67 @@ impl NetworkBeaconProcessor { } } + pub async fn process_gossip_data_column_sidecar( + self: &Arc, + message_id: MessageId, + peer_id: PeerId, + _peer_client: Client, + subnet_id: DataColumnSubnetId, + column_sidecar: Arc>, + seen_duration: Duration, + ) { + let slot = column_sidecar.slot(); + let block_root = column_sidecar.block_root(); + let index = column_sidecar.index; + let delay = get_slot_delay_ms(seen_duration, slot, &self.chain.slot_clock); + // Log metrics to track delay from other nodes on the network. + metrics::set_gauge( + &metrics::BEACON_DATA_COLUMN_DELAY_GOSSIP, + delay.as_millis() as i64, + ); + match self + .chain + .verify_data_column_sidecar_for_gossip(column_sidecar, *subnet_id) + { + Ok(gossip_verified_data_column) => { + metrics::inc_counter( + &metrics::BEACON_PROCESSOR_GOSSIP_DATA_COLUMN_SIDECAR_VERIFIED_TOTAL, + ); + + debug!( + self.log, + "Successfully verified gossip data column sidecar"; + "slot" => %slot, + "block_root" => %block_root, + "index" => %index, + ); + + self.propagate_validation_result(message_id, peer_id, MessageAcceptance::Accept); + + // Log metrics to keep track of propagation delay times. + if let Some(duration) = SystemTime::now() + .duration_since(UNIX_EPOCH) + .ok() + .and_then(|now| now.checked_sub(seen_duration)) + { + metrics::set_gauge( + &metrics::BEACON_DATA_COLUMN_DELAY_GOSSIP_VERIFICATION, + duration.as_millis() as i64, + ); + } + self.process_gossip_verified_data_column( + peer_id, + gossip_verified_data_column, + seen_duration, + ) + .await + } + Err(_) => { + // TODO(das) implement gossip error handling + } + } + } + #[allow(clippy::too_many_arguments)] pub async fn process_gossip_blob( self: &Arc, @@ -837,6 +900,81 @@ impl NetworkBeaconProcessor { } } + pub async fn process_gossip_verified_data_column( + self: &Arc, + peer_id: PeerId, + verified_data_column: GossipVerifiedDataColumn, + // This value is not used presently, but it might come in handy for debugging. + _seen_duration: Duration, + ) { + let processing_start_time = Instant::now(); + let block_root = verified_data_column.block_root(); + let data_column_slot = verified_data_column.slot(); + let data_column_index = verified_data_column.id().index; + + match self + .chain + .process_gossip_data_columns(vec![verified_data_column]) + .await + { + Ok(availability) => { + match availability { + AvailabilityProcessingStatus::Imported(block_root) => { + // Note: Reusing block imported metric here + metrics::inc_counter( + &metrics::BEACON_PROCESSOR_GOSSIP_BLOCK_IMPORTED_TOTAL, + ); + info!( + self.log, + "Gossipsub data column processed, imported fully available block"; + "block_root" => %block_root + ); + self.chain.recompute_head_at_current_slot().await; + + metrics::set_gauge( + &metrics::BEACON_BLOB_DELAY_FULL_VERIFICATION, + processing_start_time.elapsed().as_millis() as i64, + ); + } + AvailabilityProcessingStatus::MissingComponents(slot, block_root) => { + trace!( + self.log, + "Processed data column, waiting for other components"; + "slot" => %slot, + "data_column_index" => %data_column_index, + "block_root" => %block_root, + ); + + // Potentially trigger reconstruction + } + } + } + Err(BlockError::BlockIsAlreadyKnown(_)) => { + debug!( + self.log, + "Ignoring gossip column already imported"; + "block_root" => ?block_root, + "data_column_index" => data_column_index, + ); + } + Err(err) => { + debug!( + self.log, + "Invalid gossip data column"; + "outcome" => ?err, + "block root" => ?block_root, + "block slot" => data_column_slot, + "data column index" => data_column_index, + ); + self.gossip_penalize_peer( + peer_id, + PeerAction::MidToleranceError, + "bad_gossip_data_column_ssz", + ); + } + } + } + /// Process the beacon block received from the gossip network and: /// /// - If it passes gossip propagation criteria, tell the network thread to forward it. @@ -1086,6 +1224,12 @@ impl NetworkBeaconProcessor { ); return None; } + Err(e @ BlockError::InternalError(_)) => { + error!(self.log, "Internal block gossip validation error"; + "error" => %e + ); + return None; + } }; metrics::inc_counter(&metrics::BEACON_PROCESSOR_GOSSIP_BLOCK_VERIFIED_TOTAL); diff --git a/beacon_node/network/src/network_beacon_processor/mod.rs b/beacon_node/network/src/network_beacon_processor/mod.rs index ccdbb10720..ffb01a99ef 100644 --- a/beacon_node/network/src/network_beacon_processor/mod.rs +++ b/beacon_node/network/src/network_beacon_processor/mod.rs @@ -223,6 +223,36 @@ impl NetworkBeaconProcessor { }) } + /// Create a new `Work` event for some data column sidecar. + pub fn send_gossip_data_column_sidecar( + self: &Arc, + message_id: MessageId, + peer_id: PeerId, + peer_client: Client, + subnet_id: DataColumnSubnetId, + column_sidecar: Arc>, + seen_timestamp: Duration, + ) -> Result<(), Error> { + let processor = self.clone(); + let process_fn = async move { + processor + .process_gossip_data_column_sidecar( + message_id, + peer_id, + peer_client, + subnet_id, + column_sidecar, + seen_timestamp, + ) + .await + }; + + self.try_send(BeaconWorkEvent { + drop_during_sync: false, + work: Work::GossipDataColumnSidecar(Box::pin(process_fn)), + }) + } + /// Create a new `Work` event for some sync committee signature. pub fn send_gossip_sync_signature( self: &Arc, diff --git a/beacon_node/network/src/router.rs b/beacon_node/network/src/router.rs index e125c13f4c..c162d52d02 100644 --- a/beacon_node/network/src/router.rs +++ b/beacon_node/network/src/router.rs @@ -319,6 +319,20 @@ impl Router { ), ) } + PubsubMessage::DataColumnSidecar(data) => { + let (subnet_id, column_sidecar) = *data; + self.handle_beacon_processor_send_result( + self.network_beacon_processor + .send_gossip_data_column_sidecar( + message_id, + peer_id, + self.network_globals.client(&peer_id), + subnet_id, + column_sidecar, + timestamp_now(), + ), + ) + } PubsubMessage::VoluntaryExit(exit) => { debug!(self.log, "Received a voluntary exit"; "peer_id" => %peer_id); self.handle_beacon_processor_send_result( diff --git a/beacon_node/network/src/sync/manager.rs b/beacon_node/network/src/sync/manager.rs index dd4fa56d53..c9894c8b24 100644 --- a/beacon_node/network/src/sync/manager.rs +++ b/beacon_node/network/src/sync/manager.rs @@ -63,7 +63,7 @@ use std::ops::Sub; use std::sync::Arc; use std::time::Duration; use tokio::sync::mpsc; -use types::{BlobSidecar, EthSpec, Hash256, SignedBeaconBlock, Slot}; +use types::{BlobSidecar, DataColumnSidecar, EthSpec, Hash256, SignedBeaconBlock, Slot}; /// The number of slots ahead of us that is allowed before requesting a long-range (batch) Sync /// from a peer. If a peer is within this tolerance (forwards or backwards), it is treated as a @@ -107,6 +107,9 @@ pub enum SyncMessage { /// A blob with an unknown parent has been received. UnknownParentBlob(PeerId, Arc>), + /// A data column with an unknown parent has been received. + UnknownParentDataColumn(PeerId, Arc>), + /// A peer has sent an attestation that references a block that is unknown. This triggers the /// manager to attempt to find the block matching the unknown hash. UnknownBlockHashFromAttestation(PeerId, Hash256), @@ -646,6 +649,9 @@ impl SyncManager { }), ); } + SyncMessage::UnknownParentDataColumn(_peer_id, _data_column) => { + // TODO(das): data column parent lookup to be implemented + } SyncMessage::UnknownBlockHashFromAttestation(peer_id, block_root) => { if !self.notified_unknown_roots.contains(&(peer_id, block_root)) { self.notified_unknown_roots.insert((peer_id, block_root)); diff --git a/book/src/imgs/ui-auth.png b/book/src/imgs/ui-auth.png new file mode 100644 index 0000000000..624ae88436 Binary files /dev/null and b/book/src/imgs/ui-auth.png differ diff --git a/book/src/imgs/ui-bls-modal.png b/book/src/imgs/ui-bls-modal.png new file mode 100644 index 0000000000..64377e45a5 Binary files /dev/null and b/book/src/imgs/ui-bls-modal.png differ diff --git a/book/src/imgs/ui-bls-required.png b/book/src/imgs/ui-bls-required.png new file mode 100644 index 0000000000..fe61fb3f93 Binary files /dev/null and b/book/src/imgs/ui-bls-required.png differ diff --git a/book/src/imgs/ui-session.png b/book/src/imgs/ui-session.png new file mode 100644 index 0000000000..b950e164f7 Binary files /dev/null and b/book/src/imgs/ui-session.png differ diff --git a/book/src/imgs/ui-settings.png b/book/src/imgs/ui-settings.png index da9cbca9fa..cc6316854f 100644 Binary files a/book/src/imgs/ui-settings.png and b/book/src/imgs/ui-settings.png differ diff --git a/book/src/imgs/ui-val-edit.png b/book/src/imgs/ui-val-edit.png new file mode 100644 index 0000000000..927a2b29a7 Binary files /dev/null and b/book/src/imgs/ui-val-edit.png differ diff --git a/book/src/imgs/ui-val-exit.png b/book/src/imgs/ui-val-exit.png new file mode 100644 index 0000000000..363e910b35 Binary files /dev/null and b/book/src/imgs/ui-val-exit.png differ diff --git a/book/src/imgs/ui-val-modal.png b/book/src/imgs/ui-val-modal.png new file mode 100644 index 0000000000..09c2287591 Binary files /dev/null and b/book/src/imgs/ui-val-modal.png differ diff --git a/book/src/ui-authentication.md b/book/src/ui-authentication.md index 8d457c8f68..9e3a94db78 100644 --- a/book/src/ui-authentication.md +++ b/book/src/ui-authentication.md @@ -1,31 +1,13 @@ # Authentication -To enhance the security of your account, we offer the option to set a session password. This allows the user to avoid re-entering the api-token when performing critical mutating operations on the validator. Instead a user can simply enter their session password. In the absence of a session password, Siren will revert to the api-token specified in your configuration settings as the default security measure. +## Siren Session -> This does not protect your validators from unauthorized device access. +For enhanced security, Siren will require users to authenticate with their session password to access the dashboard. This is crucial because Siren now includes features that can permanently alter the status of user validators. The session password must be set during the [installation](./ui-installation.md) process before running the Docker or local build, either in an `.env` file or via Docker flags. -![authentication](imgs/ui-session-auth.png) - -Session passwords must contain at least: - -- 12 characters -- 1 lowercase letter -- 1 uppercase letter -- 1 number -- 1 special character +![exit](imgs/ui-session.png) ## Protected Actions -Prior to executing any sensitive validator action, Siren will request authentication of the session password or api-token. +Prior to executing any sensitive validator action, Siren will request authentication of the session password. If you wish to update your password please refer to the Siren [installation process](./ui-installation.md). -![exit](imgs/ui-exit.png) - -In the event of three consecutive failed attempts, Siren will initiate a security measure by locking all actions and prompting for configuration settings to be renewed to regain access to these features. - -![fail-authentication](imgs/ui-fail-auth.png) - -## Auto Connect - -In the event that auto-connect is enabled, refreshing the Siren application will result in a prompt to authenticate the session password or api-token. If three consecutive authentication attempts fail, Siren will activate a security measure by locking the session and prompting for configuration settings to be reset to regain access. - -![autoconnect](imgs/ui-autoconnect-auth.png) +![exit](imgs/ui-auth.png) diff --git a/book/src/ui-configuration.md b/book/src/ui-configuration.md index f5e4bed34a..eeb2c9a51c 100644 --- a/book/src/ui-configuration.md +++ b/book/src/ui-configuration.md @@ -1,15 +1,12 @@ # Configuration -Siren requires a connection to both a Lighthouse Validator Client -and a Lighthouse Beacon Node. Upon running you will first be greeted by the -following configuration screen. - -![ui-configuration](./imgs/ui-configuration.png) +Siren requires a connection to both a Lighthouse Validator Client and a Lighthouse Beacon Node. +To enable connection, you must generate .env file based on the provided .env.example ## Connecting to the Clients -Both the Beacon node and the Validator client need to have their HTTP APIs enabled. These ports should be accessible from the computer running Siren. This allows you to enter the address and ports of the associated Lighthouse -Beacon node and Lighthouse Validator client. +Both the Beacon node and the Validator client need to have their HTTP APIs enabled. +These ports should be accessible from Siren. To enable the HTTP API for the beacon node, utilize the `--gui` CLI flag. This action ensures that the HTTP API can be accessed by other software on the same machine. @@ -21,10 +18,7 @@ If you require accessibility from another machine within the network, configure In a similar manner, the validator client requires activation of the `--http` flag, along with the optional consideration of configuring the `--http-address` flag. If `--http-address` flag is set on the Validator Client, then the `--unencrypted-http-transport` flag is required as well. These settings will ensure compatibility with Siren's connectivity requirements. -If you run Siren in the browser (by entering `localhost` in the browser), you will need to allow CORS in the HTTP API. This can be done by adding the flag `--http-allow-origin "*"` for both beacon node and validator client. - -A green tick will appear once Siren is able to connect to both clients. You -can specify different ports for each client by clicking on the advanced tab. +If you run the Docker container, it will fail to startup if your BN/VC are not accessible, or if you provided a wrong API token. ## API Token @@ -41,13 +35,3 @@ client. The default path is The contents of this file for the desired validator client needs to be entered. - -## Name - -This is your name, it can be modified and is solely used for aesthetics. - -## Device - -This is a name that can be associated with the validator client/beacon -node pair. Multiple such pairs can be remembered for quick swapping between -them. diff --git a/book/src/ui-faqs.md b/book/src/ui-faqs.md index 4e4de225af..efa6d3d4ab 100644 --- a/book/src/ui-faqs.md +++ b/book/src/ui-faqs.md @@ -14,53 +14,17 @@ If you receive a red notification with a BEACON or VALIDATOR NODE NETWORK ERROR ## 4. How do I connect Siren to Lighthouse from a different computer on the same network? -The most effective approach to enable access for a local network computer to Lighthouse's HTTP API ports is by configuring the `--http-address` to match the local LAN IP of the system running the beacon node and validator client. For instance, if the said node operates at `192.168.0.200`, this IP can be specified using the `--http-address` parameter as `--http-address 192.168.0.200`. When this is set, the validator client requires the flag `--beacon-nodes http://192.168.0.200:5052` to connect to the beacon node. -Subsequently, by designating the host as `192.168.0.200`, you can seamlessly connect Siren to this specific beacon node and validator client pair from any computer situated within the same network. +Siren is a webapp, you can access it like any other website. We don't recommend exposing it to the internet; if you require remote access a VPN or (authenticated) reverse proxy is highly recommended. ## 5. How can I use Siren to monitor my validators remotely when I am not at home? -There are two primary methods to access your Beacon Node and Validator Client remotely: setting up a VPN or utilizing SSH-reverse tunneling. - Most contemporary home routers provide options for VPN access in various ways. A VPN permits a remote computer to establish a connection with internal computers within a home network. With a VPN configuration in place, connecting to the VPN enables you to treat your computer as if it is part of your local home network. The connection process involves following the setup steps for connecting via another machine on the same network on the Siren configuration page and [`connecting to clients section`](./ui-configuration.md#connecting-to-the-clients). -In the absence of a VPN, an alternative approach involves utilizing an SSH tunnel. To achieve this, you need remote SSH access to the computer hosting the Beacon Node and Validator Client pair (which necessitates a port forward in your router). In this context, while it is not obligatory to set a `--http-address` flag on the Beacon Node and Validator Client, you can configure an SSH tunnel to the local ports on the node and establish a connection through the tunnel. For instructions on setting up an SSH tunnel, refer to [`Connecting Siren via SSH tunnel`](./ui-faqs.md#6-how-do-i-connect-siren-to-lighthouse-via-a-ssh-tunnel) for detailed guidance. +## 6. Does Siren support reverse proxy or DNS named addresses? -## 6. How do I connect Siren to Lighthouse via a ssh tunnel? +Yes, if you need to access your beacon or validator from an address such as `https://merp-server:9909/eth2-vc` you should configure Siren as follows: +`VALIDATOR_URL=https://merp-server:9909/eth2-vc` -If you would like to access Siren beyond the local network (i.e across the internet), we recommend using an SSH tunnel. This requires a tunnel for 3 ports: `80` (assuming the port is unchanged as per the [installation guide](./ui-installation.md#docker-recommended)), `5052` (for beacon node) and `5062` (for validator client). You can use the command below to perform SSH tunneling: - -```bash - -ssh -N -L 80:127.0.0.1:80 -L 5052:127.0.0.1:5052 -L 5062:127.0.0.1:5062 username@local_ip - -``` - -Where `username` is the username of the server and `local_ip` is the local IP address of the server. Note that with the `-N` option in an SSH session, you will not be able to execute commands in the CLI to avoid confusion with ordinary shell sessions. The connection will appear to be "hung" upon a successful connection, but that is normal. Once you have successfully connected to the server via SSH tunneling, you should be able to access Siren by entering `localhost` in a web browser. - -You can also access Siren using the app downloaded in the [Siren release page](https://github.com/sigp/siren/releases). To access Siren beyond the local computer, you can use SSH tunneling for ports `5052` and `5062` using the command: - -```bash - -ssh -N -L 5052:127.0.0.1:5052 -L 5062:127.0.0.1:5062 username@local_ip - -``` - -## 7. Does Siren support reverse proxy or DNS named addresses? - -Yes, if you need to access your beacon or validator from an address such as `https://merp-server:9909/eth2-vc` you should follow the following steps for configuration: - -1. Toggle `https` as your protocol -2. Add your address as `merp-server/eth2-vc` -3. Add your Beacon and Validator ports as `9909` - -If you have configured it correctly you should see a green checkmark indicating Siren is now connected to your Validator Client and Beacon Node. - -If you have separate address setups for your Validator Client and Beacon Node respectively you should access the `Advance Settings` on the configuration and repeat the steps above for each address. - -## 8. How do I change my Beacon or Validator address after logging in? - -Once you have successfully arrived to the main dashboard, use the sidebar to access the settings view. In the top right-hand corner there is a `Configuration` action button that will redirect you back to the configuration screen where you can make appropriate changes. - -## 9. Why doesn't my validator balance graph show any data? +## 7. Why doesn't my validator balance graph show any data? If your graph is not showing data, it usually means your validator node is still caching data. The application must wait at least 3 epochs before it can render any graphical visualizations. This could take up to 20min. diff --git a/book/src/ui-installation.md b/book/src/ui-installation.md index 4f7df4e8ff..1444c0d633 100644 --- a/book/src/ui-installation.md +++ b/book/src/ui-installation.md @@ -1,113 +1,73 @@ # 📦 Installation -Siren runs on Linux, MacOS and Windows. +Siren supports any operating system that supports container runtimes and/or NodeJS 18, this includes Linux, MacOS, and Windows. The recommended way of running Siren is by launching the [docker container](https://hub.docker.com/r/sigp/siren) , but running the application directly is also possible. ## Version Requirement -The Siren app requires Lighthouse v3.5.1 or higher to function properly. These versions can be found on the [releases](https://github.com/sigp/lighthouse/releases) page of the Lighthouse repository. +To ensure proper functionality, the Siren app requires Lighthouse v4.3.0 or higher. You can find these versions on the [releases](https://github.com/sigp/lighthouse/releases) page of the Lighthouse repository. -## Pre-Built Electron Packages +## Running the Docker container (Recommended) -There are pre-compiled electron packages for each operating systems which can -be downloaded and executed. These can be found on the -[releases](https://github.com/sigp/siren/releases) page of the -Siren repository. +The most convenient way to run Siren is to use the Docker images built and published by Sigma Prime. -Simply download the package specific to your operating system and run it. + They can be found on [Docker hub](https://hub.docker.com/r/sigp/siren/tags), or pulled directly with `docker pull sigp/siren` -## Building From Source - -### Requirements - -Building from source requires `Node v18` and `yarn`. - -### Building From Source - -The electron app can be built from source by first cloning the repository and -entering the directory: - -``` -git clone https://github.com/sigp/siren.git -cd siren -``` - -Once cloned, the electron app can be built and ran via the Makefile by: - -``` -make -``` - -alternatively it can be built via: - -``` -yarn -``` - -Once completed successfully the electron app can be run via: - -``` -yarn dev -``` - -### Running In The Browser - -#### Docker (Recommended) - -Docker is the recommended way to run a webserver that hosts Siren and can be -connected to via a web browser. We recommend this method as it establishes a -production-grade web-server to host the application. - -`docker` is required to be installed with the service running. - -The docker image can be built and run via the Makefile by running: - -``` -make docker -``` - -Alternatively, to run with Docker, the image needs to be built. From the repository directory -run: - -``` -docker build -t siren . -``` +Configuration is done through environment variables, the easiest way to get started is by copying `.env.example` to `.env` and editing the relevant sections (typically, this would at least include adding `BEACON_URL`, `VALIDATOR_URL`, `API_TOKEN` and `SESSION_PASSWORD`) Then to run the image: -``` -docker run --rm -ti --name siren -p 80:80 siren -``` +`docker compose up` +or +`docker run --rm -ti --name siren -p 4443:443 --env-file $PWD/.env sigp/siren` -This will open port 80 and allow your browser to connect. You can choose -another local port by modifying the command. For example `-p 8000:80` will open -port 8000. +This command will open port 4443, allowing your browser to connect. -To view Siren, simply go to `http://localhost` in your web browser. +To start Siren, visit `https://localhost:4443` in your web browser. -#### Development Server +Advanced users can mount their own certificates, see the `SSL Certificates` section below -A development server can also be built which will expose a local port 3000 via: +## Building From Source -``` -yarn start -``` +### Docker -Once executed, you can direct your web browser to the following URL to interact -with the app: +The docker image can be built with the following command: +`docker build -f Dockerfile -t siren .` -``` -http://localhost:3000 -``` +### Building locally -A production version of the app can be built via +To build from source, ensure that your system has `Node v18.18` and `yarn` installed. -``` -yarn build -``` +#### Build and run the backend -and then further hosted via a production web server. +Navigate to the backend directory `cd backend`. Install all required Node packages by running `yarn`. Once the installation is complete, compile the backend with `yarn build`. Deploy the backend in a production environment, `yarn start:production`. This ensures optimal performance. -### Known Issues +#### Build and run the frontend -If you experience any issues in running the UI please create an issue on the -[Lighthouse UI](https://github.com/sigp/lighthouse-ui) repository. +After initializing the backend, return to the root directory. Install all frontend dependencies by executing `yarn`. Build the frontend using `yarn build`. Start the frontend production server with `yarn start`. + +This will allow you to access siren at `http://localhost:3000` by default. + +## Advanced configuration + +### About self-signed SSL certificates + +By default, Siren will generate and use a self-signed certificate on startup. +This will generate a security warning when you try to access the interface. +We recommend to only disable SSL if you would access Siren over a local LAN or otherwise highly trusted or encrypted network (i.e. VPN). + +#### Generating persistent SSL certificates and installing them to your system + +[mkcert](https://github.com/FiloSottile/mkcert) is a tool that makes it super easy to generate a self-signed certificate that is trusted by your browser. + +To use it for `siren`, install it following the instructions. Then, run `mkdir certs; mkcert -cert-file certs/cert.pem -key-file certs/key.pem 127.0.0.1 localhost` (add or replace any IP or hostname that you would use to access it at the end of this command) + +The nginx SSL config inside Siren's container expects 3 files: `/certs/cert.pem` `/certs/key.pem` `/certs/key.pass`. If `/certs/cert.pem` does not exist, it will generate a self-signed certificate as mentioned above. If `/certs/cert.pem` does exist, it will attempt to use your provided or persisted certificates. + +### Configuration through environment variables + +For those who prefer to use environment variables to configure Siren instead of using an `.env` file, this is fully supported. In some cases this may even be preferred. + +#### Docker installed through `snap` + +If you installed Docker through a snap (i.e. on Ubuntu), Docker will have trouble accessing the `.env` file. In this case it is highly recommended to pass the config to the container with environment variables. +Note that the defaults in `.env.example` will be used as fallback, if no other value is provided. diff --git a/book/src/ui-usage.md b/book/src/ui-usage.md index eddee311fd..f52a655c4e 100644 --- a/book/src/ui-usage.md +++ b/book/src/ui-usage.md @@ -1,38 +1,42 @@ # Usage +Siren offers many features ranging from diagnostics, logs, validator management including graffiti and exiting. Below we will describe all major features and how to take advantage of Siren to the fullest. + ## Dashboard Siren's dashboard view provides a summary of all performance and key validator metrics. Sync statuses, uptimes, accumulated rewards, hardware and network metrics are all consolidated on the dashboard for evaluation. ![dashboard](imgs/ui-dashboard.png) -## Account Earnings +### Account Earnings The account earnings component accumulates reward data from all registered validators providing a summation of total rewards earned while staking. Given current conversion rates, this component also converts your balance into your selected fiat currency. Below in the earning section, you can also view your total earnings or click the adjacent buttons to view your estimated earnings given a specific time frame based on current device and network conditions. +Keep in mind, if validators have updated (`0x01`) withdrawal credentials, this balance will only reflect the balance before the accumulated rewards are paid out and will subsequently be reset to a zero balance and start accumulating rewards until the next reward payout. + ![earning](imgs/ui-account-earnings.png) -## Validator Table +### Validator Table The validator table component is a list of all registered validators, which includes data such as name, index, total balance, earned rewards and current status. Each validator row also contains a link to a detailed data modal and additional data provided by [Beaconcha.in](https://beaconcha.in). ![validator-table](imgs/ui-validator-table.png) -## Validator Balance Chart +### Validator Balance Chart The validator balance component is a graphical representation of each validator balance over the latest 10 epochs. Take note that only active validators are rendered in the chart visualization. ![validator-balance](imgs/ui-validator-balance1.png) -By clicking on the chart component you can filter selected validators in the render. This call allow for greater resolution in the rendered visualization. +By clicking on the chart component you can filter selected validators in the render. This will allow for greater resolution in the rendered visualization. balance-modal -validator-balance2 +validator-balance2 -## Hardware Usage and Device Diagnostics +### Hardware Usage and Device Diagnostics The hardware usage component gathers information about the device the Beacon Node is currently running. It displays the Disk usage, CPU metrics and memory usage of the Beacon Node device. The device diagnostics component provides the sync status of the execution client and beacon node. @@ -40,11 +44,13 @@ The hardware usage component gathers information about the device the Beacon Nod device -## Log Statistics +### Log Statistics -The log statistics present an hourly combined rate of critical, warning, and error logs from the validator client and beacon node. This analysis enables informed decision-making, troubleshooting, and proactive maintenance for optimal system performance. +The log statistics present an hourly combined rate of critical, warning, and error logs from the validator client and beacon node. This analysis enables informed decision-making, troubleshooting, and proactive maintenance for optimal system performance. You can view the full log outputs in the logs page by clicking `view all` at the top of the component. -log +log + +________________________________________________________________________________________________________________________________ ## Validator Management @@ -52,17 +58,36 @@ Siren's validator management view provides a detailed overview of all validators ![validator-management](imgs/ui-validator-management.png) -## Validator Modal +### Validator Modal Clicking the validator icon activates a detailed validator modal component. This component also allows users to trigger validator actions and as well to view and update validator graffiti. Each modal contains the validator total income with hourly, daily and weekly earnings estimates. -ui-validator-modal +ui-validator-modal -## Settings +### Validator BLS Withdrawal Credentials -Siren's settings view provides access to the application theme, version, name, device name and important external links. From the settings page users can also access the configuration screen to adjust any beacon or validator node parameters. +When Siren detects that your validator is using outdated BLS withdrawal credentials, it will temporarily block any further actions by the validator. You can identify if your validator does not meet this requirement by an `exclamation mark` on the validator icon or a message in the validator modal that provides instructions for updating the credentials. -![settings](imgs/ui-settings.png) +![bls-notice](imgs/ui-bls-required.png) + +If you wish to convert your withdrawal address, Siren will prompt you to provide a valid `BLS Change JSON`. This JSON can include a single validator or multiple validators for your convenience. Upon validation, the process will initiate, during which your validator will enter a processing state. Once the process is complete, you will regain access to all other validator actions. + +![bls-execution](imgs/ui-bls-modal.png) + +### Validator Edit + +Siren makes it possible to edit your validator's display name by clicking the edit icon in the validator table. Note: This does not change the validator name, but gives it an alias you can use to identify each validator easily. +These settings are stored in your browser's `localStorage` + +![edit](imgs/ui-val-edit.png) + +### Validator Exit + +Siren provides the ability to exit/withdraw your validators via the validator management page. In the validator modal, click the validator action `withdraw validator`. Siren will then prompt you with additional information before requiring you to validate your session password. Remember, this action is irreversible and will lock your validator into an exiting state. Please take extra caution. + +![exit](imgs/ui-val-exit.png) + +________________________________________________________________________________________________________________________________ ## Validator and Beacon Logs @@ -71,3 +96,11 @@ The logs page provides users with the functionality to access and review recorde Additionally, users can obtain log statistics, which are also available on the main dashboard, thereby facilitating a comprehensive overview of the system's log data. Please note that Siren is limited to storing and displaying only the previous 1000 log messages. This also means the text search is limited to the logs that are currently stored within Siren's limit. ![logs](imgs/ui-logs.png) + +________________________________________________________________________________________________________________________________ + +## Settings + +Siren's settings view provides access to the application theme, version, display name, and important external links. If you experience any problems or have feature request, please follow the github and or discord links to get in touch. + +![settings](imgs/ui-settings.png) diff --git a/common/eth2/src/types.rs b/common/eth2/src/types.rs index bbcbda3ae5..fa5fb654b7 100644 --- a/common/eth2/src/types.rs +++ b/common/eth2/src/types.rs @@ -599,8 +599,8 @@ pub struct VersionData { #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub struct SyncingData { pub is_syncing: bool, - pub is_optimistic: Option, - pub el_offline: Option, + pub is_optimistic: bool, + pub el_offline: bool, pub head_slot: Slot, pub sync_distance: Slot, } diff --git a/consensus/types/Cargo.toml b/consensus/types/Cargo.toml index 28207f828a..f623f3d101 100644 --- a/consensus/types/Cargo.toml +++ b/consensus/types/Cargo.toml @@ -9,6 +9,7 @@ name = "benches" harness = false [dependencies] +alloy-primitives = { workspace = true, features = ["rlp"] } merkle_proof = { workspace = true } bls = { workspace = true, features = ["arbitrary"] } kzg = { workspace = true } @@ -50,6 +51,7 @@ metastruct = "0.1.0" serde_json = { workspace = true } smallvec = { workspace = true } maplit = { workspace = true } +alloy-rlp = { version = "0.3.4", features = ["derive"] } milhouse = { workspace = true } rpds = { workspace = true } diff --git a/consensus/types/src/data_column_subnet_id.rs b/consensus/types/src/data_column_subnet_id.rs new file mode 100644 index 0000000000..dd58c6c36b --- /dev/null +++ b/consensus/types/src/data_column_subnet_id.rs @@ -0,0 +1,198 @@ +//! Identifies each data column subnet by an integer identifier. +use crate::data_column_sidecar::ColumnIndex; +use crate::{ChainSpec, EthSpec}; +use ethereum_types::U256; +use itertools::Itertools; +use safe_arith::{ArithError, SafeArith}; +use serde::{Deserialize, Serialize}; +use std::collections::HashSet; +use std::fmt::{self, Display}; +use std::ops::{Deref, DerefMut}; + +#[derive(arbitrary::Arbitrary, Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[serde(transparent)] +pub struct DataColumnSubnetId(#[serde(with = "serde_utils::quoted_u64")] u64); + +impl DataColumnSubnetId { + pub fn new(id: u64) -> Self { + id.into() + } + + pub fn from_column_index(column_index: usize, spec: &ChainSpec) -> Self { + (column_index + .safe_rem(spec.data_column_sidecar_subnet_count as usize) + .expect( + "data_column_sidecar_subnet_count should never be zero if this function is called", + ) as u64) + .into() + } + + #[allow(clippy::arithmetic_side_effects)] + pub fn columns(&self, spec: &ChainSpec) -> impl Iterator { + let subnet = self.0; + let data_column_sidecar_subnet = spec.data_column_sidecar_subnet_count; + let columns_per_subnet = spec.data_columns_per_subnet() as u64; + (0..columns_per_subnet).map(move |i| data_column_sidecar_subnet * i + subnet) + } + + /// Compute required subnets to subscribe to given the node id. + #[allow(clippy::arithmetic_side_effects)] + pub fn compute_custody_subnets( + node_id: U256, + custody_subnet_count: u64, + spec: &ChainSpec, + ) -> impl Iterator { + // TODO(das): we could perform check on `custody_subnet_count` here to ensure that it is a valid + // value, but here we assume it is valid. + + let mut subnets: HashSet = HashSet::new(); + let mut current_id = node_id; + while (subnets.len() as u64) < custody_subnet_count { + let mut node_id_bytes = [0u8; 32]; + current_id.to_little_endian(&mut node_id_bytes); + let hash = ethereum_hashing::hash_fixed(&node_id_bytes); + let hash_prefix: [u8; 8] = hash[0..8] + .try_into() + .expect("hash_fixed produces a 32 byte array"); + let hash_prefix_u64 = u64::from_le_bytes(hash_prefix); + let subnet = hash_prefix_u64 % spec.data_column_sidecar_subnet_count; + + if !subnets.contains(&subnet) { + subnets.insert(subnet); + } + + if current_id == U256::MAX { + current_id = U256::zero() + } + current_id += U256::one() + } + subnets.into_iter().map(DataColumnSubnetId::new) + } + + pub fn compute_custody_columns( + node_id: U256, + custody_subnet_count: u64, + spec: &ChainSpec, + ) -> impl Iterator { + Self::compute_custody_subnets::(node_id, custody_subnet_count, spec) + .flat_map(|subnet| subnet.columns::(spec)) + .sorted() + } +} + +impl Display for DataColumnSubnetId { + fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { + write!(f, "{}", self.0) + } +} + +impl Deref for DataColumnSubnetId { + type Target = u64; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl DerefMut for DataColumnSubnetId { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +impl From for DataColumnSubnetId { + fn from(x: u64) -> Self { + Self(x) + } +} + +impl From for u64 { + fn from(val: DataColumnSubnetId) -> Self { + val.0 + } +} + +impl From<&DataColumnSubnetId> for u64 { + fn from(val: &DataColumnSubnetId) -> Self { + val.0 + } +} + +#[derive(Debug)] +pub enum Error { + ArithError(ArithError), +} + +impl From for Error { + fn from(e: ArithError) -> Self { + Error::ArithError(e) + } +} + +#[cfg(test)] +mod test { + use crate::data_column_subnet_id::DataColumnSubnetId; + use crate::EthSpec; + use crate::MainnetEthSpec; + + type E = MainnetEthSpec; + + #[test] + fn test_compute_subnets_for_data_column() { + let spec = E::default_spec(); + let node_ids = [ + "0", + "88752428858350697756262172400162263450541348766581994718383409852729519486397", + "18732750322395381632951253735273868184515463718109267674920115648614659369468", + "27726842142488109545414954493849224833670205008410190955613662332153332462900", + "39755236029158558527862903296867805548949739810920318269566095185775868999998", + "31899136003441886988955119620035330314647133604576220223892254902004850516297", + "58579998103852084482416614330746509727562027284701078483890722833654510444626", + "28248042035542126088870192155378394518950310811868093527036637864276176517397", + "60930578857433095740782970114409273483106482059893286066493409689627770333527", + "103822458477361691467064888613019442068586830412598673713899771287914656699997", + ] + .into_iter() + .map(|v| ethereum_types::U256::from_dec_str(v).unwrap()) + .collect::>(); + + let custody_requirement = 4; + for node_id in node_ids { + let computed_subnets = DataColumnSubnetId::compute_custody_subnets::( + node_id, + custody_requirement, + &spec, + ); + let computed_subnets: Vec<_> = computed_subnets.collect(); + + // the number of subnets is equal to the custody requirement + assert_eq!(computed_subnets.len() as u64, custody_requirement); + + let subnet_count = spec.data_column_sidecar_subnet_count; + for subnet in computed_subnets { + let columns: Vec<_> = subnet.columns::(&spec).collect(); + // the number of columns is equal to the specified number of columns per subnet + assert_eq!(columns.len(), spec.data_columns_per_subnet()); + + for pair in columns.windows(2) { + // each successive column index is offset by the number of subnets + assert_eq!(pair[1] - pair[0], subnet_count); + } + } + } + } + + #[test] + fn test_columns_subnet_conversion() { + let spec = E::default_spec(); + for subnet in 0..spec.data_column_sidecar_subnet_count { + let subnet_id = DataColumnSubnetId::new(subnet); + for column_index in subnet_id.columns::(&spec) { + assert_eq!( + subnet_id, + DataColumnSubnetId::from_column_index::(column_index as usize, &spec) + ); + } + } + } +} diff --git a/consensus/types/src/execution_block_header.rs b/consensus/types/src/execution_block_header.rs index 945222a925..2e5a498214 100644 --- a/consensus/types/src/execution_block_header.rs +++ b/consensus/types/src/execution_block_header.rs @@ -18,6 +18,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. use crate::{Address, EthSpec, ExecutionPayloadRef, Hash256, Hash64, Uint256}; +use alloy_rlp::RlpEncodable; use metastruct::metastruct; /// Execution block header as used for RLP encoding and Keccak hashing. @@ -89,3 +90,74 @@ impl ExecutionBlockHeader { } } } + +#[derive(Debug, Clone, PartialEq, Eq, RlpEncodable)] +#[rlp(trailing)] +pub struct EncodableExecutionBlockHeader<'a> { + pub parent_hash: &'a [u8], + pub ommers_hash: &'a [u8], + pub beneficiary: &'a [u8], + pub state_root: &'a [u8], + pub transactions_root: &'a [u8], + pub receipts_root: &'a [u8], + pub logs_bloom: &'a [u8], + pub difficulty: alloy_primitives::U256, + pub number: alloy_primitives::U256, + pub gas_limit: alloy_primitives::U256, + pub gas_used: alloy_primitives::U256, + pub timestamp: u64, + pub extra_data: &'a [u8], + pub mix_hash: &'a [u8], + pub nonce: &'a [u8], + pub base_fee_per_gas: alloy_primitives::U256, + pub withdrawals_root: Option<&'a [u8]>, + pub blob_gas_used: Option, + pub excess_blob_gas: Option, + pub parent_beacon_block_root: Option<&'a [u8]>, +} + +impl<'a> From<&'a ExecutionBlockHeader> for EncodableExecutionBlockHeader<'a> { + fn from(header: &'a ExecutionBlockHeader) -> Self { + let mut encodable = Self { + parent_hash: header.parent_hash.as_bytes(), + ommers_hash: header.ommers_hash.as_bytes(), + beneficiary: header.beneficiary.as_bytes(), + state_root: header.state_root.as_bytes(), + transactions_root: header.transactions_root.as_bytes(), + receipts_root: header.receipts_root.as_bytes(), + logs_bloom: header.logs_bloom.as_slice(), + difficulty: U256Shim(header.difficulty).into(), + number: U256Shim(header.number).into(), + gas_limit: U256Shim(header.gas_limit).into(), + gas_used: U256Shim(header.gas_used).into(), + timestamp: header.timestamp, + extra_data: header.extra_data.as_slice(), + mix_hash: header.mix_hash.as_bytes(), + nonce: header.nonce.as_bytes(), + base_fee_per_gas: U256Shim(header.base_fee_per_gas).into(), + withdrawals_root: None, + blob_gas_used: header.blob_gas_used, + excess_blob_gas: header.excess_blob_gas, + parent_beacon_block_root: None, + }; + if let Some(withdrawals_root) = &header.withdrawals_root { + encodable.withdrawals_root = Some(withdrawals_root.as_bytes()); + } + if let Some(parent_beacon_block_root) = &header.parent_beacon_block_root { + encodable.parent_beacon_block_root = Some(parent_beacon_block_root.as_bytes()) + } + encodable + } +} + +// TODO(alloy) this shim can be removed once we fully migrate +// from ethereum types to alloy primitives +struct U256Shim(Uint256); + +impl From for alloy_primitives::U256 { + fn from(value: U256Shim) -> Self { + let mut buffer: [u8; 32] = [0; 32]; + value.0.to_little_endian(&mut buffer); + Self::from_le_slice(&buffer) + } +} diff --git a/consensus/types/src/lib.rs b/consensus/types/src/lib.rs index b5c500f0b2..2afd726110 100644 --- a/consensus/types/src/lib.rs +++ b/consensus/types/src/lib.rs @@ -105,6 +105,7 @@ pub mod sqlite; pub mod blob_sidecar; pub mod data_column_sidecar; +pub mod data_column_subnet_id; pub mod light_client_header; pub mod non_zero_usize; pub mod runtime_var_list; @@ -147,6 +148,10 @@ pub use crate::config_and_preset::{ }; pub use crate::consolidation::Consolidation; pub use crate::contribution_and_proof::ContributionAndProof; +pub use crate::data_column_sidecar::{ + ColumnIndex, DataColumnIdentifier, DataColumnSidecar, DataColumnSidecarList, +}; +pub use crate::data_column_subnet_id::DataColumnSubnetId; pub use crate::deposit::{Deposit, DEPOSIT_TREE_DEPTH}; pub use crate::deposit_data::DepositData; pub use crate::deposit_message::DepositMessage; @@ -157,7 +162,7 @@ pub use crate::epoch_cache::{EpochCache, EpochCacheError, EpochCacheKey}; pub use crate::eth1_data::Eth1Data; pub use crate::eth_spec::EthSpecId; pub use crate::execution_block_hash::ExecutionBlockHash; -pub use crate::execution_block_header::ExecutionBlockHeader; +pub use crate::execution_block_header::{EncodableExecutionBlockHeader, ExecutionBlockHeader}; pub use crate::execution_layer_withdrawal_request::ExecutionLayerWithdrawalRequest; pub use crate::execution_payload::{ ExecutionPayload, ExecutionPayloadBellatrix, ExecutionPayloadCapella, ExecutionPayloadDeneb, diff --git a/lighthouse/Cargo.toml b/lighthouse/Cargo.toml index 912602776a..b9d3eaf894 100644 --- a/lighthouse/Cargo.toml +++ b/lighthouse/Cargo.toml @@ -4,7 +4,7 @@ version = "5.2.1" authors = ["Sigma Prime "] edition = { workspace = true } autotests = false -rust-version = "1.77.0" +rust-version = "1.78.0" [features] default = ["slasher-lmdb"] diff --git a/scripts/local_testnet/start_local_testnet.sh b/scripts/local_testnet/start_local_testnet.sh index 433e6280c2..330df76d81 100755 --- a/scripts/local_testnet/start_local_testnet.sh +++ b/scripts/local_testnet/start_local_testnet.sh @@ -75,14 +75,11 @@ else echo "Not rebuilding Lighthouse Docker image." fi -IMAGE_DOWNLOAD_FLAG="" - if [ "$KEEP_ENCLAVE" = false ]; then # Stop local testnet kurtosis enclave rm -f $ENCLAVE_NAME 2>/dev/null || true - IMAGE_DOWNLOAD_FLAG="--image-download always" fi -kurtosis run --enclave $ENCLAVE_NAME github.com/ethpandaops/ethereum-package $IMAGE_DOWNLOAD_FLAG --args-file $NETWORK_PARAMS_FILE +kurtosis run --enclave $ENCLAVE_NAME github.com/ethpandaops/ethereum-package --args-file $NETWORK_PARAMS_FILE echo "Started!" diff --git a/validator_client/src/check_synced.rs b/validator_client/src/check_synced.rs index a7b81df9d8..2e9a62ff65 100644 --- a/validator_client/src/check_synced.rs +++ b/validator_client/src/check_synced.rs @@ -21,9 +21,7 @@ pub async fn check_node_health( Ok(( resp.data.head_slot, - // Note that optimistic and EL status will both default to their healthy variants which may - // be undesirable. - resp.data.is_optimistic.unwrap_or(false), - resp.data.el_offline.unwrap_or(false), + resp.data.is_optimistic, + resp.data.el_offline, )) }