diff --git a/Cargo.lock b/Cargo.lock index 60a19e63c..b081afc33 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,25 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "account_utils" +version = "0.1.0" +source = "git+https://github.com/sigp/lighthouse?rev=f1056d9c#f1056d9c19a699c1cb0215dae416aef41fdd29b8" +dependencies = [ + "eth2_keystore", + "eth2_wallet", + "filesystem", + "rand 0.8.5", + "regex", + "rpassword", + "serde", + "serde_yaml", + "tracing", + "types", + "validator_dir", + "zeroize", +] + [[package]] name = "addr2line" version = "0.24.2" @@ -98,10 +117,10 @@ version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b4ae82946772d69f868b9ef81fc66acb1b149ef9b4601849bec4bcf5da6552e" dependencies = [ - "alloy-consensus", + "alloy-consensus 0.12.6", "alloy-contract", "alloy-core", - "alloy-eips", + "alloy-eips 0.12.6", "alloy-genesis", "alloy-network", "alloy-provider", @@ -127,13 +146,25 @@ dependencies = [ "strum 0.27.1", ] +[[package]] +name = "alloy-consensus" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "629b62e38d471cc15fea534eb7283d2f8a4e8bdb1811bcc5d66dda6cfce6fae1" +dependencies = [ + "alloy-eips 0.3.6", + "alloy-primitives", + "alloy-rlp", + "c-kzg", +] + [[package]] name = "alloy-consensus" version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6fbf458101ed6c389e9bb70a34ebc56039868ad10472540614816cdedc8f5265" dependencies = [ - "alloy-eips", + "alloy-eips 0.12.6", "alloy-primitives", "alloy-rlp", "alloy-serde", @@ -142,7 +173,7 @@ dependencies = [ "c-kzg", "derive_more 2.0.1", "either", - "k256", + "k256 0.13.4", "once_cell", "rand 0.8.5", "serde", @@ -156,8 +187,8 @@ version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc982af629e511292310fe85b433427fd38cb3105147632b574abc997db44c91" dependencies = [ - "alloy-consensus", - "alloy-eips", + "alloy-consensus 0.12.6", + "alloy-eips 0.12.6", "alloy-primitives", "alloy-rlp", "alloy-serde", @@ -170,7 +201,7 @@ version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd0a0c1ddee20ecc14308aae21c2438c994df7b39010c26d70f86e1d8fdb8db0" dependencies = [ - "alloy-consensus", + "alloy-consensus 0.12.6", "alloy-dyn-abi", "alloy-json-abi", "alloy-network", @@ -213,7 +244,7 @@ dependencies = [ "itoa", "serde", "serde_json", - "winnow", + "winnow 0.7.6", ] [[package]] @@ -240,6 +271,16 @@ dependencies = [ "serde", ] +[[package]] +name = "alloy-eip7702" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea59dc42102bc9a1905dc57901edc6dd48b9f38115df86c7d252acba70d71d04" +dependencies = [ + "alloy-primitives", + "alloy-rlp", +] + [[package]] name = "alloy-eip7702" version = "0.5.1" @@ -252,6 +293,23 @@ dependencies = [ "thiserror 2.0.12", ] +[[package]] +name = "alloy-eips" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f923dd5fca5f67a43d81ed3ebad0880bd41f6dd0ada930030353ac356c54cd0f" +dependencies = [ + "alloy-eip2930", + "alloy-eip7702 0.1.1", + "alloy-primitives", + "alloy-rlp", + "c-kzg", + "derive_more 1.0.0", + "once_cell", + "serde", + "sha2 0.10.8", +] + [[package]] name = "alloy-eips" version = "0.12.6" @@ -260,7 +318,7 @@ checksum = "6e86967eb559920e4b9102e4cb825fe30f2e9467988353ce4809f0d3f2c90cd4" dependencies = [ "alloy-eip2124", "alloy-eip2930", - "alloy-eip7702", + "alloy-eip7702 0.5.1", "alloy-primitives", "alloy-rlp", "alloy-serde", @@ -279,7 +337,7 @@ version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a40de6f5b53ecf5fd7756072942f41335426d9a3704cd961f77d854739933bcf" dependencies = [ - "alloy-eips", + "alloy-eips 0.12.6", "alloy-primitives", "alloy-serde", "alloy-trie", @@ -318,9 +376,9 @@ version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26a33a38c7486b1945f8d093ff027add2f3a8f83c7300dbad6165cc49150085e" dependencies = [ - "alloy-consensus", + "alloy-consensus 0.12.6", "alloy-consensus-any", - "alloy-eips", + "alloy-eips 0.12.6", "alloy-json-rpc", "alloy-network-primitives", "alloy-primitives", @@ -344,8 +402,8 @@ version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db973a7a23cbe96f2958e5687c51ce2d304b5c6d0dc5ccb3de8667ad8476f50b" dependencies = [ - "alloy-consensus", - "alloy-eips", + "alloy-consensus 0.12.6", + "alloy-eips 0.12.6", "alloy-primitives", "alloy-serde", "serde", @@ -369,16 +427,16 @@ dependencies = [ "hashbrown 0.15.2", "indexmap 2.9.0", "itoa", - "k256", + "k256 0.13.4", "keccak-asm", "paste", "proptest", "proptest-derive", "rand 0.8.5", "ruint", - "rustc-hash", + "rustc-hash 2.1.1", "serde", - "sha3", + "sha3 0.10.8", "tiny-keccak", ] @@ -389,8 +447,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b03bde77ad73feae14aa593bcabb932c8098c0f0750ead973331cfc0003a4e1" dependencies = [ "alloy-chains", - "alloy-consensus", - "alloy-eips", + "alloy-consensus 0.12.6", + "alloy-eips 0.12.6", "alloy-json-rpc", "alloy-network", "alloy-network-primitives", @@ -518,9 +576,9 @@ version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7e13d71eac04513a71af4b3df580f52f2b4dcbff9d971cc9a52519acf55514cb" dependencies = [ - "alloy-consensus", + "alloy-consensus 0.12.6", "alloy-consensus-any", - "alloy-eips", + "alloy-eips 0.12.6", "alloy-network-primitives", "alloy-primitives", "alloy-rlp", @@ -553,8 +611,8 @@ dependencies = [ "async-trait", "auto_impl", "either", - "elliptic-curve", - "k256", + "elliptic-curve 0.13.8", + "k256 0.13.4", "thiserror 2.0.12", ] @@ -564,12 +622,12 @@ version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cc6e72002cc1801d8b41e9892165e3a6551b7bd382bd9d0414b21e90c0c62551" dependencies = [ - "alloy-consensus", + "alloy-consensus 0.12.6", "alloy-network", "alloy-primitives", "alloy-signer", "async-trait", - "k256", + "k256 0.13.4", "rand 0.8.5", "thiserror 2.0.12", ] @@ -632,7 +690,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d162f8524adfdfb0e4bd0505c734c985f3e2474eb022af32eef0d52a4f3935c" dependencies = [ "serde", - "winnow", + "winnow 0.7.6", ] [[package]] @@ -726,7 +784,7 @@ dependencies = [ "async-channel 1.9.0", "bls", "clap", - "client", + "client 0.1.0", "futures", "keygen", "keysplit", @@ -739,6 +797,45 @@ dependencies = [ "types", ] +[[package]] +name = "anchor_http_api" +version = "0.1.0" +dependencies = [ + "api_types", + "axum", + "database", + "hex", + "parking_lot", + "serde", + "serde_json", + "slot_clock", + "ssv_types", + "task_executor", + "tokio", + "tracing", + "types", + "version", +] + +[[package]] +name = "anchor_http_metrics" +version = "0.1.0" +dependencies = [ + "anchor_validator_store", + "axum", + "health_metrics", + "metrics", + "parking_lot", + "serde", + "slot_clock", + "tokio", + "tower-http", + "tracing", + "types", + "validator_metrics", + "validator_services", +] + [[package]] name = "anchor_validator_store" version = "0.1.0" @@ -854,6 +951,12 @@ dependencies = [ "derive_arbitrary", ] +[[package]] +name = "arc-swap" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" + [[package]] name = "archery" version = "0.4.0" @@ -1328,6 +1431,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de45108900e1f9b9242f7f2e254aa3e2c029c921c258fe9e6b4217eeebd54288" dependencies = [ "axum-core", + "base64 0.22.1", "bytes", "form_urlencoded", "futures-util", @@ -1347,8 +1451,10 @@ dependencies = [ "serde_json", "serde_path_to_error", "serde_urlencoded", + "sha1", "sync_wrapper 1.0.2", "tokio", + "tokio-tungstenite", "tower", "tower-layer", "tower-service", @@ -1396,6 +1502,12 @@ version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4cbbc9d0964165b47557570cce6c952866c2678457aca742aafc9fb771d30270" +[[package]] +name = "base16ct" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" + [[package]] name = "base16ct" version = "0.2.0" @@ -1420,6 +1532,95 @@ version = "1.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89e25b6adfb930f02d1981565a6e5d9c547ac15a96606256d3b59040e5cd4ca3" +[[package]] +name = "beacon_chain" +version = "0.2.0" +source = "git+https://github.com/sigp/lighthouse?rev=f1056d9c#f1056d9c19a699c1cb0215dae416aef41fdd29b8" +dependencies = [ + "alloy-primitives", + "bitvec 1.0.1", + "bls", + "derivative", + "eth1", + "eth2", + "eth2_network_config", + "ethereum_hashing", + "ethereum_serde_utils", + "ethereum_ssz", + "ethereum_ssz_derive", + "execution_layer", + "fork_choice", + "futures", + "genesis", + "hex", + "int_to_bytes", + "itertools 0.10.5", + "kzg", + "lighthouse_version", + "logging", + "lru 0.12.5", + "merkle_proof", + "metrics", + "oneshot_broadcast", + "operation_pool", + "parking_lot", + "proto_array", + "rand 0.8.5", + "rayon", + "safe_arith", + "sensitive_url", + "serde", + "serde_json", + "slasher", + "slot_clock", + "smallvec", + "ssz_types", + "state_processing", + "store", + "strum 0.24.1", + "superstruct", + "task_executor", + "tempfile", + "tokio", + "tokio-stream", + "tracing", + "tree_hash", + "tree_hash_derive", + "types", +] + +[[package]] +name = "beacon_node" +version = "7.0.0-beta.5" +source = "git+https://github.com/sigp/lighthouse?rev=f1056d9c#f1056d9c19a699c1cb0215dae416aef41fdd29b8" +dependencies = [ + "account_utils", + "beacon_chain", + "clap", + "clap_utils", + "client 0.2.0", + "directory", + "dirs 3.0.2", + "environment", + "eth2_config", + "execution_layer", + "genesis", + "hex", + "http_api", + "hyper 1.6.0", + "lighthouse_network", + "monitoring_api", + "sensitive_url", + "serde_json", + "slasher", + "store", + "strum 0.24.1", + "task_executor", + "tracing", + "types", + "unused_port", +] + [[package]] name = "beacon_node_fallback" version = "0.1.0" @@ -1439,12 +1640,67 @@ dependencies = [ "validator_metrics", ] +[[package]] +name = "beacon_processor" +version = "0.1.0" +source = "git+https://github.com/sigp/lighthouse?rev=f1056d9c#f1056d9c19a699c1cb0215dae416aef41fdd29b8" +dependencies = [ + "fnv", + "futures", + "itertools 0.10.5", + "lighthouse_network", + "logging", + "metrics", + "num_cpus", + "parking_lot", + "serde", + "slot_clock", + "strum 0.24.1", + "task_executor", + "tokio", + "tokio-util", + "tracing", + "types", +] + [[package]] name = "bimap" version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "230c5f1ca6a325a32553f8640d31ac9b49f2411e901e427570154868b46da4f7" +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bindgen" +version = "0.69.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" +dependencies = [ + "bitflags 2.9.0", + "cexpr", + "clang-sys", + "itertools 0.12.1", + "lazy_static", + "lazycell", + "log", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash 1.1.0", + "shlex", + "syn 2.0.100", + "which", +] + [[package]] name = "bit-set" version = "0.8.0" @@ -1472,16 +1728,28 @@ version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" +[[package]] +name = "bitvec" +version = "0.20.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7774144344a4faa177370406a7ff5f1da24303817368584c6206c8303eb07848" +dependencies = [ + "funty 1.1.0", + "radium 0.6.2", + "tap", + "wyz 0.2.0", +] + [[package]] name = "bitvec" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" dependencies = [ - "funty", - "radium", + "funty 2.0.0", + "radium 0.7.0", "tap", - "wyz", + "wyz 0.5.1", ] [[package]] @@ -1499,6 +1767,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" dependencies = [ + "block-padding", "generic-array 0.14.7", ] @@ -1511,6 +1780,12 @@ dependencies = [ "generic-array 0.14.7", ] +[[package]] +name = "block-padding" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" + [[package]] name = "blocking" version = "1.6.1" @@ -1576,8 +1851,8 @@ checksum = "7a8a8ed6fefbeef4a8c7b460e4110e12c5e22a5b7cf32621aae6ad650c4dcf29" dependencies = [ "blst", "byte-slice-cast", - "ff", - "group", + "ff 0.13.1", + "group 0.13.0", "pairing", "rand_core 0.6.4", "serde", @@ -1591,9 +1866,9 @@ source = "git+https://github.com/dknopik/blstrs?branch=pls#e281dca0c6c5c70d5c3b7 dependencies = [ "arrayref", "blst", - "elliptic-curve", - "ff", - "group", + "elliptic-curve 0.13.8", + "ff 0.13.1", + "group 0.13.0", "pairing", "rand_core 0.6.4", "serde", @@ -1601,6 +1876,12 @@ dependencies = [ "zeroize", ] +[[package]] +name = "bs58" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" + [[package]] name = "bs58" version = "0.5.1" @@ -1610,6 +1891,20 @@ dependencies = [ "tinyvec", ] +[[package]] +name = "builder_client" +version = "0.1.0" +source = "git+https://github.com/sigp/lighthouse?rev=f1056d9c#f1056d9c19a699c1cb0215dae416aef41fdd29b8" +dependencies = [ + "eth2", + "ethereum_ssz", + "lighthouse_version", + "reqwest 0.11.27", + "sensitive_url", + "serde", + "serde_json", +] + [[package]] name = "bumpalo" version = "3.17.0" @@ -1715,6 +2010,15 @@ dependencies = [ "shlex", ] +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -1786,11 +2090,22 @@ dependencies = [ "zeroize", ] +[[package]] +name = "clang-sys" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +dependencies = [ + "glob", + "libc", + "libloading", +] + [[package]] name = "clap" -version = "4.5.36" +version = "4.5.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2df961d8c8a0d08aa9945718ccf584145eee3f3aa06cddbeac12933781102e04" +checksum = "eccb054f56cbd38340b380d4a8e69ef1f02f1af43db2f0cc817a4774d80ae071" dependencies = [ "clap_builder", "clap_derive", @@ -1798,9 +2113,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.36" +version = "4.5.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "132dbda40fb6753878316a489d5a1242a8ef2f0d9e47ba01c951ea8aa7d013a5" +checksum = "efd9466fac8543255d3b1fcad4762c5e116ffe808c8a3043d4263cd4fd4862a2" dependencies = [ "anstream", "anstyle", @@ -1848,6 +2163,8 @@ dependencies = [ name = "client" version = "0.1.0" dependencies = [ + "anchor_http_api", + "anchor_http_metrics", "anchor_validator_store", "beacon_node_fallback", "clap", @@ -1857,15 +2174,13 @@ dependencies = [ "eth2", "ethereum_hashing", "fdlimit", - "http_api", - "http_metrics", "hyper 1.6.0", "keygen", "message_receiver", "message_sender", "message_validator", "multiaddr", - "network", + "network 0.1.0", "openssl", "parking_lot", "processor", @@ -1891,11 +2206,61 @@ dependencies = [ ] [[package]] -name = "colorchoice" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" - +name = "client" +version = "0.2.0" +source = "git+https://github.com/sigp/lighthouse?rev=f1056d9c#f1056d9c19a699c1cb0215dae416aef41fdd29b8" +dependencies = [ + "beacon_chain", + "beacon_processor", + "directory", + "dirs 3.0.2", + "environment", + "eth1", + "eth2", + "eth2_config", + "ethereum_ssz", + "execution_layer", + "futures", + "genesis", + "http_api", + "http_metrics", + "kzg", + "lighthouse_network", + "logging", + "metrics", + "monitoring_api", + "network 0.2.0", + "sensitive_url", + "serde", + "serde_json", + "slasher", + "slasher_service", + "slot_clock", + "store", + "task_executor", + "time", + "timer", + "tokio", + "tracing", + "tracing-subscriber", + "types", +] + +[[package]] +name = "cmake" +version = "0.1.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7caa3f9de89ddbe2c607f4101924c5abec803763ae9534e4f4d7d8f84aa81f0" +dependencies = [ + "cc", +] + +[[package]] +name = "colorchoice" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" + [[package]] name = "compare_fields" version = "0.2.0" @@ -2018,8 +2383,8 @@ checksum = "76f9cdad245e39a3659bc4c8958e93de34bd31ba3131ead14ccfb4b2cd60e52d" dependencies = [ "blst", "blstrs", - "ff", - "group", + "ff 0.13.1", + "group 0.13.0", "pairing", "subtle", ] @@ -2126,6 +2491,18 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929" +[[package]] +name = "crypto-bigint" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" +dependencies = [ + "generic-array 0.14.7", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + [[package]] name = "crypto-bigint" version = "0.5.5" @@ -2188,6 +2565,16 @@ dependencies = [ "cipher 0.4.4", ] +[[package]] +name = "ctrlc" +version = "3.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "697b5419f348fd5ae2478e8018cb016c00a5881c7f46c717de98ffd135a5651c" +dependencies = [ + "nix 0.29.0", + "windows-sys 0.59.0", +] + [[package]] name = "curve25519-dalek" version = "4.1.3" @@ -2353,7 +2740,7 @@ dependencies = [ "openssl", "r2d2", "r2d2_sqlite", - "rand 0.9.0", + "rand 0.9.1", "rusqlite", "ssv_types", "tempfile", @@ -2362,6 +2749,12 @@ dependencies = [ "types", ] +[[package]] +name = "db-key" +version = "0.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b72465f46d518f6015d9cf07f7f3013a95dd6b9c2747c3d65ae0cce43929d14f" + [[package]] name = "delay_map" version = "0.4.1" @@ -2373,11 +2766,36 @@ dependencies = [ "tokio-util", ] +[[package]] +name = "deposit_contract" +version = "0.2.0" +source = "git+https://github.com/sigp/lighthouse?rev=f1056d9c#f1056d9c19a699c1cb0215dae416aef41fdd29b8" +dependencies = [ + "ethabi 16.0.0", + "ethereum_ssz", + "hex", + "reqwest 0.11.27", + "serde_json", + "sha2 0.9.9", + "tree_hash", + "types", +] + [[package]] name = "der" -version = "0.7.9" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" +dependencies = [ + "const-oid", + "zeroize", +] + +[[package]] +name = "der" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" +checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" dependencies = [ "const-oid", "pem-rfc7468", @@ -2599,6 +3017,24 @@ dependencies = [ "syn 2.0.100", ] +[[package]] +name = "doppelganger_service" +version = "0.1.0" +source = "git+https://github.com/sigp/lighthouse?rev=f1056d9c#f1056d9c19a699c1cb0215dae416aef41fdd29b8" +dependencies = [ + "beacon_node_fallback", + "environment", + "eth2", + "logging", + "parking_lot", + "slot_clock", + "task_executor", + "tokio", + "tracing", + "types", + "validator_store", +] + [[package]] name = "dtoa" version = "1.0.10" @@ -2611,19 +3047,31 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" +[[package]] +name = "ecdsa" +version = "0.14.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" +dependencies = [ + "der 0.6.1", + "elliptic-curve 0.12.3", + "rfc6979 0.3.1", + "signature 1.6.4", +] + [[package]] name = "ecdsa" version = "0.16.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" dependencies = [ - "der", + "der 0.7.10", "digest 0.10.7", - "elliptic-curve", - "rfc6979", + "elliptic-curve 0.13.8", + "rfc6979 0.4.0", "serdect", - "signature", - "spki", + "signature 2.2.0", + "spki 0.7.3", ] [[package]] @@ -2632,8 +3080,8 @@ version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" dependencies = [ - "pkcs8", - "signature", + "pkcs8 0.10.2", + "signature 2.2.0", ] [[package]] @@ -2672,23 +3120,42 @@ dependencies = [ "serde", ] +[[package]] +name = "elliptic-curve" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" +dependencies = [ + "base16ct 0.1.1", + "crypto-bigint 0.4.9", + "der 0.6.1", + "digest 0.10.7", + "ff 0.12.1", + "generic-array 0.14.7", + "group 0.12.1", + "rand_core 0.6.4", + "sec1 0.3.0", + "subtle", + "zeroize", +] + [[package]] name = "elliptic-curve" version = "0.13.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" dependencies = [ - "base16ct", - "crypto-bigint", + "base16ct 0.2.0", + "crypto-bigint 0.5.5", "digest 0.10.7", - "ff", + "ff 0.13.1", "generic-array 0.14.7", - "group", + "group 0.13.0", "hkdf", "pem-rfc7468", - "pkcs8", + "pkcs8 0.10.2", "rand_core 0.6.4", - "sec1", + "sec1 0.7.3", "serdect", "subtle", "tap", @@ -2701,7 +3168,7 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e48843edfbd0a370b3dd14cdbb4e446e9a8855311e6b2b57bf9a1fd1367bc317" dependencies = [ - "elliptic-curve", + "elliptic-curve 0.13.8", "heapless", "hex", "multiexp", @@ -2729,11 +3196,11 @@ dependencies = [ "bytes", "ed25519-dalek", "hex", - "k256", + "k256 0.13.4", "log", "rand 0.8.5", "serde", - "sha3", + "sha3 0.10.8", "zeroize", ] @@ -2769,6 +3236,29 @@ dependencies = [ "syn 2.0.100", ] +[[package]] +name = "environment" +version = "0.1.2" +source = "git+https://github.com/sigp/lighthouse?rev=f1056d9c#f1056d9c19a699c1cb0215dae416aef41fdd29b8" +dependencies = [ + "async-channel 1.9.0", + "clap", + "ctrlc", + "eth2_config", + "eth2_network_config", + "futures", + "logging", + "logroller", + "serde", + "task_executor", + "tokio", + "tracing", + "tracing-appender", + "tracing-log", + "tracing-subscriber", + "types", +] + [[package]] name = "equivalent" version = "1.0.2" @@ -2808,6 +3298,31 @@ dependencies = [ "types", ] +[[package]] +name = "eth1" +version = "0.2.0" +source = "git+https://github.com/sigp/lighthouse?rev=f1056d9c#f1056d9c19a699c1cb0215dae416aef41fdd29b8" +dependencies = [ + "eth2", + "ethereum_ssz", + "ethereum_ssz_derive", + "execution_layer", + "futures", + "logging", + "merkle_proof", + "metrics", + "parking_lot", + "sensitive_url", + "serde", + "state_processing", + "superstruct", + "task_executor", + "tokio", + "tracing", + "tree_hash", + "types", +] + [[package]] name = "eth2" version = "0.1.0" @@ -2914,6 +3429,111 @@ dependencies = [ "zip", ] +[[package]] +name = "eth2_wallet" +version = "0.1.0" +source = "git+https://github.com/sigp/lighthouse?rev=f1056d9c#f1056d9c19a699c1cb0215dae416aef41fdd29b8" +dependencies = [ + "eth2_key_derivation", + "eth2_keystore", + "rand 0.8.5", + "serde", + "serde_json", + "serde_repr", + "tiny-bip39", + "uuid 0.8.2", +] + +[[package]] +name = "ethabi" +version = "16.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4c98847055d934070b90e806e12d3936b787d0a115068981c1d8dfd5dfef5a5" +dependencies = [ + "ethereum-types 0.12.1", + "hex", + "serde", + "serde_json", + "sha3 0.9.1", + "thiserror 1.0.69", + "uint 0.9.5", +] + +[[package]] +name = "ethabi" +version = "18.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7413c5f74cc903ea37386a8965a936cbeb334bd270862fdece542c1b2dcbc898" +dependencies = [ + "ethereum-types 0.14.1", + "hex", + "once_cell", + "regex", + "serde", + "serde_json", + "sha3 0.10.8", + "thiserror 1.0.69", + "uint 0.9.5", +] + +[[package]] +name = "ethbloom" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfb684ac8fa8f6c5759f788862bb22ec6fe3cb392f6bfd08e3c64b603661e3f8" +dependencies = [ + "crunchy", + "fixed-hash 0.7.0", + "impl-rlp", + "impl-serde 0.3.2", + "tiny-keccak", +] + +[[package]] +name = "ethbloom" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c22d4b5885b6aa2fe5e8b9329fb8d232bf739e434e6b87347c63bdd00c120f60" +dependencies = [ + "crunchy", + "fixed-hash 0.8.0", + "impl-codec 0.6.0", + "impl-rlp", + "impl-serde 0.4.0", + "scale-info", + "tiny-keccak", +] + +[[package]] +name = "ethereum-types" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05136f7057fe789f06e6d41d07b34e6f70d8c86e5693b60f97aaa6553553bdaf" +dependencies = [ + "ethbloom 0.11.1", + "fixed-hash 0.7.0", + "impl-rlp", + "impl-serde 0.3.2", + "primitive-types 0.10.1", + "uint 0.9.5", +] + +[[package]] +name = "ethereum-types" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02d215cbf040552efcbe99a38372fe80ab9d00268e20012b79fcd0f073edd8ee" +dependencies = [ + "ethbloom 0.13.0", + "fixed-hash 0.8.0", + "impl-codec 0.6.0", + "impl-rlp", + "impl-serde 0.4.0", + "primitive-types 0.12.2", + "scale-info", + "uint 0.9.5", +] + [[package]] name = "ethereum_hashing" version = "0.7.0" @@ -2966,6 +3586,32 @@ dependencies = [ "syn 2.0.100", ] +[[package]] +name = "ethers-core" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ade3e9c97727343984e1ceada4fdab11142d2ee3472d2c67027d56b1251d4f15" +dependencies = [ + "arrayvec", + "bytes", + "chrono", + "elliptic-curve 0.12.3", + "ethabi 18.0.0", + "generic-array 0.14.7", + "hex", + "k256 0.11.6", + "open-fastrlp", + "rand 0.8.5", + "rlp", + "rlp-derive", + "serde", + "serde_json", + "strum 0.24.1", + "thiserror 1.0.69", + "tiny-keccak", + "unicode-xid", +] + [[package]] name = "event-listener" version = "2.5.3" @@ -3004,6 +3650,59 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "execution_layer" +version = "0.1.0" +source = "git+https://github.com/sigp/lighthouse?rev=f1056d9c#f1056d9c19a699c1cb0215dae416aef41fdd29b8" +dependencies = [ + "alloy-consensus 0.3.6", + "alloy-primitives", + "alloy-rlp", + "arc-swap", + "builder_client", + "bytes", + "eth2", + "ethereum_serde_utils", + "ethereum_ssz", + "ethers-core", + "fixed_bytes", + "fork_choice", + "hash-db", + "hash256-std-hasher", + "hex", + "jsonwebtoken", + "keccak-hash", + "kzg", + "lighthouse_version", + "logging", + "lru 0.12.5", + "metrics", + "parking_lot", + "pretty_reqwest_error", + "rand 0.8.5", + "reqwest 0.11.27", + "sensitive_url", + "serde", + "serde_json", + "sha2 0.9.9", + "slot_clock", + "ssz_types", + "state_processing", + "strum 0.24.1", + "superstruct", + "task_executor", + "tempfile", + "tokio", + "tokio-stream", + "tracing", + "tree_hash", + "tree_hash_derive", + "triehash", + "types", + "warp", + "zeroize", +] + [[package]] name = "fallible-iterator" version = "0.2.0" @@ -3054,17 +3753,33 @@ dependencies = [ "thiserror 1.0.69", ] +[[package]] +name = "ff" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" +dependencies = [ + "rand_core 0.6.4", + "subtle", +] + [[package]] name = "ff" version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" dependencies = [ - "bitvec", + "bitvec 1.0.1", "rand_core 0.6.4", "subtle", ] +[[package]] +name = "ffi-opaque" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec54ac60a7f2ee9a97cad9946f9bf629a3bc6a7ae59e68983dc9318f5a54b81a" + [[package]] name = "fiat-crypto" version = "0.2.9" @@ -3090,6 +3805,18 @@ dependencies = [ "windows-acl", ] +[[package]] +name = "fixed-hash" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcf0ed7fe52a17a03854ec54a9f76d6d84508d1c0e66bc1793301c73fc8493c" +dependencies = [ + "byteorder", + "rand 0.8.5", + "rustc-hex", + "static_assertions", +] + [[package]] name = "fixed-hash" version = "0.8.0" @@ -3118,6 +3845,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ced92e76e966ca2fd84c8f7aa01a4aea65b0eb6648d72f7c8f3e2764a67fece" dependencies = [ "crc32fast", + "libz-sys", "miniz_oxide", ] @@ -3148,6 +3876,21 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" +[[package]] +name = "fork_choice" +version = "0.1.0" +source = "git+https://github.com/sigp/lighthouse?rev=f1056d9c#f1056d9c19a699c1cb0215dae416aef41fdd29b8" +dependencies = [ + "ethereum_ssz", + "ethereum_ssz_derive", + "logging", + "metrics", + "proto_array", + "state_processing", + "tracing", + "types", +] + [[package]] name = "form_urlencoded" version = "1.2.1" @@ -3157,6 +3900,22 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "fs2" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "funty" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7" + [[package]] name = "funty" version = "2.0.0" @@ -3333,6 +4092,26 @@ dependencies = [ "typenum", ] +[[package]] +name = "genesis" +version = "0.2.0" +source = "git+https://github.com/sigp/lighthouse?rev=f1056d9c#f1056d9c19a699c1cb0215dae416aef41fdd29b8" +dependencies = [ + "environment", + "eth1", + "ethereum_hashing", + "ethereum_ssz", + "futures", + "int_to_bytes", + "merkle_proof", + "rayon", + "state_processing", + "tokio", + "tracing", + "tree_hash", + "types", +] + [[package]] name = "getrandom" version = "0.2.15" @@ -3425,13 +4204,24 @@ dependencies = [ "types", ] +[[package]] +name = "group" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" +dependencies = [ + "ff 0.12.1", + "rand_core 0.6.4", + "subtle", +] + [[package]] name = "group" version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ - "ff", + "ff 0.13.1", "rand 0.8.5", "rand_core 0.6.4", "rand_xorshift", @@ -3476,6 +4266,21 @@ dependencies = [ "tracing", ] +[[package]] +name = "hash-db" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d23bd4e7b5eda0d0f3a307e8b381fdc8ba9000f26fbe912250c0a4cc3956364a" + +[[package]] +name = "hash256-std-hasher" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92c171d55b98633f4ed3860808f004099b36c1cc29c42cfc53aa8591b21efcf2" +dependencies = [ + "crunchy", +] + [[package]] name = "hash32" version = "0.3.1" @@ -3531,6 +4336,30 @@ dependencies = [ "hashbrown 0.14.5", ] +[[package]] +name = "headers" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270" +dependencies = [ + "base64 0.21.7", + "bytes", + "headers-core", + "http 0.2.12", + "httpdate", + "mime", + "sha1", +] + +[[package]] +name = "headers-core" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" +dependencies = [ + "http 0.2.12", +] + [[package]] name = "health_metrics" version = "0.1.0" @@ -3608,7 +4437,7 @@ dependencies = [ "idna", "ipnet", "once_cell", - "rand 0.9.0", + "rand 0.9.1", "socket2", "thiserror 2.0.12", "tinyvec", @@ -3630,7 +4459,7 @@ dependencies = [ "moka", "once_cell", "parking_lot", - "rand 0.9.0", + "rand 0.9.1", "resolv-conf", "smallvec", "thiserror 2.0.12", @@ -3687,6 +4516,15 @@ dependencies = [ "hmac 0.8.1", ] +[[package]] +name = "home" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" +dependencies = [ + "windows-sys 0.59.0", +] + [[package]] name = "hostname" version = "0.4.1" @@ -3757,40 +4595,68 @@ dependencies = [ [[package]] name = "http_api" version = "0.1.0" +source = "git+https://github.com/sigp/lighthouse?rev=f1056d9c#f1056d9c19a699c1cb0215dae416aef41fdd29b8" dependencies = [ - "api_types", - "axum", - "database", + "beacon_chain", + "beacon_processor", + "bs58 0.4.0", + "bytes", + "directory", + "either", + "eth1", + "eth2", + "ethereum_serde_utils", + "ethereum_ssz", + "execution_layer", + "futures", + "health_metrics", "hex", + "lighthouse_network", + "lighthouse_version", + "logging", + "lru 0.12.5", + "metrics", + "network 0.2.0", + "operation_pool", "parking_lot", + "rand 0.8.5", + "safe_arith", + "sensitive_url", "serde", "serde_json", "slot_clock", - "ssv_types", + "state_processing", + "store", + "sysinfo", + "system_health", "task_executor", "tokio", + "tokio-stream", "tracing", + "tree_hash", "types", - "version", + "warp", + "warp_utils", ] [[package]] name = "http_metrics" version = "0.1.0" +source = "git+https://github.com/sigp/lighthouse?rev=f1056d9c#f1056d9c19a699c1cb0215dae416aef41fdd29b8" dependencies = [ - "anchor_validator_store", - "axum", + "beacon_chain", "health_metrics", + "lighthouse_network", + "lighthouse_version", + "logging", + "malloc_utils", "metrics", - "parking_lot", "serde", "slot_clock", - "tokio", - "tower-http", + "store", "tracing", - "types", - "validator_metrics", - "validator_services", + "warp", + "warp_utils", ] [[package]] @@ -4154,13 +5020,70 @@ dependencies = [ "xmltree", ] +[[package]] +name = "igd-next" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d06464e726471718db9ad3fefc020529fabcde03313a0fc3967510e2db5add12" +dependencies = [ + "async-trait", + "attohttpc", + "bytes", + "futures", + "http 1.3.1", + "http-body-util", + "hyper 1.6.0", + "hyper-util", + "log", + "rand 0.9.1", + "tokio", + "url", + "xmltree", +] + +[[package]] +name = "impl-codec" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "161ebdfec3c8e3b52bf61c4f3550a1eea4f9579d10dc1b936f3171ebdcd6c443" +dependencies = [ + "parity-scale-codec 2.3.1", +] + [[package]] name = "impl-codec" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" dependencies = [ - "parity-scale-codec", + "parity-scale-codec 3.7.4", +] + +[[package]] +name = "impl-rlp" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28220f89297a075ddc7245cd538076ee98b01f2a9c23a53a4f1105d5a322808" +dependencies = [ + "rlp", +] + +[[package]] +name = "impl-serde" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4551f042f3438e64dbd6226b20527fc84a6e1fe65688b58746a2f53623f25f5c" +dependencies = [ + "serde", +] + +[[package]] +name = "impl-serde" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc88fc67028ae3db0c853baa36269d398d5f45b6982f95549ff5def78c935cd" +dependencies = [ + "serde", ] [[package]] @@ -4197,6 +5120,33 @@ dependencies = [ "serde", ] +[[package]] +name = "initialized_validators" +version = "0.1.0" +source = "git+https://github.com/sigp/lighthouse?rev=f1056d9c#f1056d9c19a699c1cb0215dae416aef41fdd29b8" +dependencies = [ + "account_utils", + "bincode", + "bls", + "eth2_keystore", + "filesystem", + "lockfile", + "metrics", + "parking_lot", + "rand 0.8.5", + "reqwest 0.11.27", + "serde", + "serde_json", + "signing_method", + "tokio", + "tracing", + "types", + "url", + "validator_dir", + "validator_metrics", + "zeroize", +] + [[package]] name = "inout" version = "0.1.4" @@ -4214,6 +5164,45 @@ dependencies = [ "bytes", ] +[[package]] +name = "integer-sqrt" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "276ec31bcb4a9ee45f58bec6f9ec700ae4cf4f4f8f2fa7e06cb406bd5ffdd770" +dependencies = [ + "num-traits", +] + +[[package]] +name = "integration" +version = "0.1.0" +dependencies = [ + "axum", + "clap", + "client 0.1.0", + "discv5", + "environment", + "ethereum_serde_utils", + "execution_layer", + "futures", + "futures-util", + "kzg", + "lighthouse_network", + "logging", + "network 0.1.0", + "node_test_rig", + "parking_lot", + "sensitive_url", + "serde_json", + "ssv_network_config", + "task_executor", + "tokio", + "tokio-tungstenite", + "tracing", + "tracing-subscriber", + "types", +] + [[package]] name = "io-lifetimes" version = "1.0.11" @@ -4258,6 +5247,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 = "itertools" version = "0.13.0" @@ -4302,6 +5300,34 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "jsonwebtoken" +version = "9.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a87cc7a48537badeae96744432de36f4be2b4a34a05a5ef32e9dd8a1c169dde" +dependencies = [ + "base64 0.22.1", + "js-sys", + "pem", + "ring", + "serde", + "serde_json", + "simple_asn1", +] + +[[package]] +name = "k256" +version = "0.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" +dependencies = [ + "cfg-if", + "ecdsa 0.14.8", + "elliptic-curve 0.12.3", + "sha2 0.10.8", + "sha3 0.10.8", +] + [[package]] name = "k256" version = "0.13.4" @@ -4309,12 +5335,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b" dependencies = [ "cfg-if", - "ecdsa", - "elliptic-curve", + "ecdsa 0.16.9", + "elliptic-curve 0.13.8", "once_cell", "serdect", "sha2 0.10.8", - "signature", + "signature 2.2.0", ] [[package]] @@ -4336,6 +5362,16 @@ dependencies = [ "sha3-asm", ] +[[package]] +name = "keccak-hash" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b286e6b663fb926e1eeb68528e69cb70ed46c6d65871a21b2215ae8154c6d3c" +dependencies = [ + "primitive-types 0.12.2", + "tiny-keccak", +] + [[package]] name = "keygen" version = "0.1.0" @@ -4345,7 +5381,7 @@ dependencies = [ "clap", "openssl", "pbkdf2 0.12.2", - "rand 0.9.0", + "rand 0.9.1", "serde", "serde_json", "sha2 0.10.8", @@ -4417,17 +5453,56 @@ dependencies = [ "spin", ] +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + +[[package]] +name = "leveldb" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32651baaaa5596b3a6e0bee625e73fd0334c167db0ea5ac68750ef9a629a2d6a" +dependencies = [ + "db-key", + "leveldb-sys", + "libc", +] + +[[package]] +name = "leveldb-sys" +version = "2.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dd94a4d0242a437e5e41a27c782b69a624469ca1c4d1e5cb3c337f74a8031d4" +dependencies = [ + "cmake", + "ffi-opaque", + "libc", + "num_cpus", +] + [[package]] name = "libc" version = "0.2.172" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" +[[package]] +name = "libloading" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" +dependencies = [ + "cfg-if", + "windows-targets 0.52.6", +] + [[package]] name = "libm" -version = "0.2.11" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" +checksum = "c9627da5196e5d8ed0b0495e61e518847578da83483c37288316d9b2e03a7f72" [[package]] name = "libp2p" @@ -4585,7 +5660,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "257b5621d159b32282eac446bed6670c39c7dc68a200a992d8f056afa0066f6d" dependencies = [ "asn1_der", - "bs58", + "bs58 0.5.1", "ed25519-dalek", "hkdf", "libsecp256k1", @@ -4593,7 +5668,7 @@ dependencies = [ "p256", "quick-protobuf", "rand 0.8.5", - "sec1", + "sec1 0.7.3", "sha2 0.10.8", "thiserror 1.0.69", "tracing", @@ -4858,7 +5933,7 @@ checksum = "d457b9ecceb66e7199f049926fad447f1f17f040e8d29d690c086b4cab8ed14a" dependencies = [ "futures", "futures-timer", - "igd-next", + "igd-next 0.15.1", "libp2p-core", "libp2p-swarm", "tokio", @@ -4949,6 +6024,17 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "libz-sys" +version = "1.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b70e7a7df205e92a1a4cd9aaae7898dac0aa555503cc0a649494d0d60e7651d" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] + [[package]] name = "lighthouse_network" version = "0.2.0" @@ -5001,6 +6087,32 @@ dependencies = [ "unused_port", ] +[[package]] +name = "lighthouse_validator_store" +version = "0.1.0" +source = "git+https://github.com/sigp/lighthouse?rev=f1056d9c#f1056d9c19a699c1cb0215dae416aef41fdd29b8" +dependencies = [ + "account_utils", + "beacon_node_fallback", + "doppelganger_service", + "either", + "environment", + "eth2", + "initialized_validators", + "logging", + "parking_lot", + "serde", + "signing_method", + "slashing_protection", + "slot_clock", + "task_executor", + "tokio", + "tracing", + "types", + "validator_metrics", + "validator_store", +] + [[package]] name = "lighthouse_version" version = "0.1.0" @@ -5056,6 +6168,14 @@ dependencies = [ "scopeguard", ] +[[package]] +name = "lockfile" +version = "0.1.0" +source = "git+https://github.com/sigp/lighthouse?rev=f1056d9c#f1056d9c19a699c1cb0215dae416aef41fdd29b8" +dependencies = [ + "fs2", +] + [[package]] name = "log" version = "0.4.27" @@ -5157,6 +6277,16 @@ dependencies = [ "syn 2.0.100", ] +[[package]] +name = "malloc_utils" +version = "0.1.0" +source = "git+https://github.com/sigp/lighthouse?rev=f1056d9c#f1056d9c19a699c1cb0215dae416aef41fdd29b8" +dependencies = [ + "libc", + "metrics", + "parking_lot", +] + [[package]] name = "maplit" version = "1.0.2" @@ -5324,6 +6454,16 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +[[package]] +name = "mime_guess" +version = "2.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" +dependencies = [ + "mime", + "unicase", +] + [[package]] name = "minimal-lexical" version = "0.2.1" @@ -5369,6 +6509,26 @@ dependencies = [ "uuid 1.16.0", ] +[[package]] +name = "monitoring_api" +version = "0.1.0" +source = "git+https://github.com/sigp/lighthouse?rev=f1056d9c#f1056d9c19a699c1cb0215dae416aef41fdd29b8" +dependencies = [ + "eth2", + "health_metrics", + "lighthouse_version", + "metrics", + "regex", + "reqwest 0.11.27", + "sensitive_url", + "serde", + "serde_json", + "store", + "task_executor", + "tokio", + "tracing", +] + [[package]] name = "more-asserts" version = "0.3.1" @@ -5411,8 +6571,8 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "25a383da1ae933078ddb1e4141f1dd617b512b4183779d6977e6451b0e644806" dependencies = [ - "ff", - "group", + "ff 0.13.1", + "group 0.13.0", "rustversion", "std-shims", "zeroize", @@ -5566,7 +6726,7 @@ dependencies = [ "lighthouse_network", "message_receiver", "quick-protobuf", - "rand 0.9.0", + "rand 0.9.1", "serde", "serde_json", "ssv_types", @@ -5581,6 +6741,46 @@ dependencies = [ "version", ] +[[package]] +name = "network" +version = "0.2.0" +source = "git+https://github.com/sigp/lighthouse?rev=f1056d9c#f1056d9c19a699c1cb0215dae416aef41fdd29b8" +dependencies = [ + "alloy-primitives", + "alloy-rlp", + "anyhow", + "async-channel 1.9.0", + "beacon_chain", + "beacon_processor", + "delay_map", + "derivative", + "ethereum_ssz", + "execution_layer", + "fnv", + "futures", + "hex", + "igd-next 0.16.1", + "itertools 0.10.5", + "lighthouse_network", + "logging", + "lru_cache", + "metrics", + "operation_pool", + "parking_lot", + "rand 0.8.5", + "slot_clock", + "smallvec", + "ssz_types", + "store", + "strum 0.24.1", + "task_executor", + "tokio", + "tokio-stream", + "tracing", + "tracing-subscriber", + "types", +] + [[package]] name = "nix" version = "0.24.3" @@ -5603,6 +6803,36 @@ dependencies = [ "libc", ] +[[package]] +name = "nix" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" +dependencies = [ + "bitflags 2.9.0", + "cfg-if", + "cfg_aliases", + "libc", +] + +[[package]] +name = "node_test_rig" +version = "0.2.0" +source = "git+https://github.com/sigp/lighthouse?rev=f1056d9c#f1056d9c19a699c1cb0215dae416aef41fdd29b8" +dependencies = [ + "beacon_node", + "beacon_node_fallback", + "environment", + "eth2", + "execution_layer", + "sensitive_url", + "tempfile", + "tokio", + "types", + "validator_client", + "validator_dir", +] + [[package]] name = "nohash-hasher" version = "0.2.0" @@ -5619,6 +6849,15 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "ntapi" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4" +dependencies = [ + "winapi", +] + [[package]] name = "nu-ansi-term" version = "0.46.0" @@ -5799,12 +7038,45 @@ version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +[[package]] +name = "oneshot_broadcast" +version = "0.1.0" +source = "git+https://github.com/sigp/lighthouse?rev=f1056d9c#f1056d9c19a699c1cb0215dae416aef41fdd29b8" +dependencies = [ + "parking_lot", +] + [[package]] name = "opaque-debug" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" +[[package]] +name = "open-fastrlp" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "786393f80485445794f6043fd3138854dd109cc6c4bd1a6383db304c9ce9b9ce" +dependencies = [ + "arrayvec", + "auto_impl", + "bytes", + "ethereum-types 0.14.1", + "open-fastrlp-derive", +] + +[[package]] +name = "open-fastrlp-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "003b2be5c6c53c1cfeb0a238b8a1c3915cd410feb684457a36c10038f764bb1c" +dependencies = [ + "bytes", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "openssl" version = "0.10.72" @@ -5859,6 +7131,26 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "operation_pool" +version = "0.2.0" +source = "git+https://github.com/sigp/lighthouse?rev=f1056d9c#f1056d9c19a699c1cb0215dae416aef41fdd29b8" +dependencies = [ + "bitvec 1.0.1", + "derivative", + "ethereum_ssz", + "ethereum_ssz_derive", + "itertools 0.10.5", + "metrics", + "parking_lot", + "rand 0.8.5", + "rayon", + "serde", + "state_processing", + "store", + "types", +] + [[package]] name = "option-ext" version = "0.2.0" @@ -5877,8 +7169,8 @@ version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" dependencies = [ - "ecdsa", - "elliptic-curve", + "ecdsa 0.16.9", + "elliptic-curve 0.13.8", "primeorder", "sha2 0.10.8", ] @@ -5889,7 +7181,21 @@ version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81fec4625e73cf41ef4bb6846cafa6d44736525f442ba45e407c4a000a13996f" dependencies = [ - "group", + "group 0.13.0", +] + +[[package]] +name = "parity-scale-codec" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "373b1a4c1338d9cd3d1fa53b3a11bdab5ab6bd80a20f7f7becd76953ae2be909" +dependencies = [ + "arrayvec", + "bitvec 0.20.4", + "byte-slice-cast", + "impl-trait-for-tuples", + "parity-scale-codec-derive 2.3.1", + "serde", ] [[package]] @@ -5899,22 +7205,34 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c9fde3d0718baf5bc92f577d652001da0f8d54cd03a7974e118d04fc888dc23d" dependencies = [ "arrayvec", - "bitvec", + "bitvec 1.0.1", "byte-slice-cast", "const_format", "impl-trait-for-tuples", - "parity-scale-codec-derive", + "parity-scale-codec-derive 3.7.4", "rustversion", "serde", ] +[[package]] +name = "parity-scale-codec-derive" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1557010476e0595c9b568d16dcfb81b93cdeb157612726f5170d31aa707bed27" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "parity-scale-codec-derive" version = "3.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "581c837bb6b9541ce7faa9377c20616e4fb7650f6b0f68bc93c827ee504fb7b3" dependencies = [ - "proc-macro-crate", + "proc-macro-crate 3.3.0", "proc-macro2", "quote", "syn 2.0.100", @@ -6097,14 +7415,24 @@ dependencies = [ "futures-io", ] +[[package]] +name = "pkcs8" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" +dependencies = [ + "der 0.6.1", + "spki 0.6.0", +] + [[package]] name = "pkcs8" version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ - "der", - "spki", + "der 0.7.10", + "spki 0.7.3", ] [[package]] @@ -6187,13 +7515,36 @@ dependencies = [ "sensitive_url", ] +[[package]] +name = "prettyplease" +version = "0.2.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "664ec5419c51e34154eec046ebcba56312d5a2fc3b09a06da188e1ad21afadf6" +dependencies = [ + "proc-macro2", + "syn 2.0.100", +] + [[package]] name = "primeorder" version = "0.13.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" dependencies = [ - "elliptic-curve", + "elliptic-curve 0.13.8", +] + +[[package]] +name = "primitive-types" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05e4722c697a58a99d5d06a08c30821d7c082a4632198de1eaa5a6c22ef42373" +dependencies = [ + "fixed-hash 0.7.0", + "impl-codec 0.5.1", + "impl-rlp", + "impl-serde 0.3.2", + "uint 0.9.5", ] [[package]] @@ -6202,18 +7553,31 @@ version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b34d9fd68ae0b74a41b21c03c2f62847aa0ffea044eee893b4c140b37e244e2" dependencies = [ - "fixed-hash", - "impl-codec", + "fixed-hash 0.8.0", + "impl-codec 0.6.0", + "impl-rlp", + "impl-serde 0.4.0", + "scale-info", "uint 0.9.5", ] +[[package]] +name = "proc-macro-crate" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +dependencies = [ + "once_cell", + "toml_edit 0.19.15", +] + [[package]] name = "proc-macro-crate" version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "edce586971a4dfaa28950c6f18ed55e0406c1ab88bbce2c6f6293a7aaba73d35" dependencies = [ - "toml_edit", + "toml_edit 0.22.24", ] [[package]] @@ -6453,7 +7817,7 @@ dependencies = [ "pin-project-lite", "quinn-proto", "quinn-udp", - "rustc-hash", + "rustc-hash 2.1.1", "rustls 0.23.26", "socket2", "thiserror 2.0.12", @@ -6470,9 +7834,9 @@ checksum = "b820744eb4dc9b57a3398183639c511b5a26d2ed702cedd3febaa1393caa22cc" dependencies = [ "bytes", "getrandom 0.3.2", - "rand 0.9.0", + "rand 0.9.1", "ring", - "rustc-hash", + "rustc-hash 2.1.1", "rustls 0.23.26", "rustls-pki-types", "slab", @@ -6532,6 +7896,12 @@ dependencies = [ "rusqlite", ] +[[package]] +name = "radium" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "643f8f41a8ebc4c5dc4515c82bb8abd397b527fc20fd681b7c011c2aee5d44fb" + [[package]] name = "radium" version = "0.7.0" @@ -6552,13 +7922,12 @@ dependencies = [ [[package]] name = "rand" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94" +checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97" dependencies = [ "rand_chacha 0.9.0", "rand_core 0.9.3", - "zerocopy 0.8.24", ] [[package]] @@ -6831,6 +8200,17 @@ dependencies = [ "hostname", ] +[[package]] +name = "rfc6979" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" +dependencies = [ + "crypto-bigint 0.4.9", + "hmac 0.12.1", + "zeroize", +] + [[package]] name = "rfc6979" version = "0.4.0" @@ -6865,6 +8245,27 @@ dependencies = [ "rustc-hex", ] +[[package]] +name = "rlp-derive" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e33d7b2abe0c340d8797fe2907d3f20d3b5ea5908683618bfe80df7f621f672a" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "rpassword" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffc936cf8a7ea60c58f030fd36a612a48f440610214dc54bc36431f9ea0c3efb" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "rpds" version = "0.11.0" @@ -6909,11 +8310,11 @@ dependencies = [ "num-bigint", "num-integer", "num-traits", - "parity-scale-codec", - "primitive-types", + "parity-scale-codec 3.7.4", + "primitive-types 0.12.2", "proptest", "rand 0.8.5", - "rand 0.9.0", + "rand 0.9.1", "rlp", "ruint-macro", "serde", @@ -6961,6 +8362,12 @@ version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + [[package]] name = "rustc-hash" version = "2.1.1" @@ -7052,6 +8459,20 @@ dependencies = [ "sct", ] +[[package]] +name = "rustls" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf4ef73721ac7bcd79b2b315da7779d8fc09718c6b3d2d1b2d94850eb8c18432" +dependencies = [ + "log", + "ring", + "rustls-pki-types", + "rustls-webpki 0.102.8", + "subtle", + "zeroize", +] + [[package]] name = "rustls" version = "0.23.26" @@ -7103,6 +8524,17 @@ dependencies = [ "untrusted", ] +[[package]] +name = "rustls-webpki" +version = "0.102.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + [[package]] name = "rustls-webpki" version = "0.103.1" @@ -7172,6 +8604,30 @@ dependencies = [ "cipher 0.4.4", ] +[[package]] +name = "scale-info" +version = "2.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "346a3b32eba2640d17a9cb5927056b08f3de90f65b72fe09402c2ad07d684d0b" +dependencies = [ + "cfg-if", + "derive_more 1.0.0", + "parity-scale-codec 3.7.4", + "scale-info-derive", +] + +[[package]] +name = "scale-info-derive" +version = "2.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6630024bf739e2179b91fb424b28898baf819414262c5d376677dbff1fe7ebf" +dependencies = [ + "proc-macro-crate 3.3.0", + "proc-macro2", + "quote", + "syn 2.0.100", +] + [[package]] name = "schannel" version = "0.1.27" @@ -7236,16 +8692,30 @@ dependencies = [ "untrusted", ] +[[package]] +name = "sec1" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" +dependencies = [ + "base16ct 0.1.1", + "der 0.6.1", + "generic-array 0.14.7", + "pkcs8 0.9.0", + "subtle", + "zeroize", +] + [[package]] name = "sec1" version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" dependencies = [ - "base16ct", - "der", + "base16ct 0.2.0", + "der 0.7.10", "generic-array 0.14.7", - "pkcs8", + "pkcs8 0.10.2", "serdect", "subtle", "zeroize", @@ -7325,6 +8795,16 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "serde_array_query" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d89c6e82b1005b33d5b2bbc47096800e5ad6b67ef5636f9c13ad29a6935734a7" +dependencies = [ + "serde", + "serde_urlencoded", +] + [[package]] name = "serde_derive" version = "1.0.219" @@ -7430,7 +8910,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a84f14a19e9a014bb9f4512488d9829a68e04ecabffb0f9904cd1ace94598177" dependencies = [ - "base16ct", + "base16ct 0.2.0", "serde", ] @@ -7469,6 +8949,18 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "sha3" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809" +dependencies = [ + "block-buffer 0.9.0", + "digest 0.9.0", + "keccak", + "opaque-debug", +] + [[package]] name = "sha3" version = "0.10.8" @@ -7506,13 +8998,23 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "signal-hook-registry" -version = "1.4.2" +version = "1.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" +checksum = "9203b8055f63a2a00e2f593bb0510367fe707d7ff1e5c872de2f537b339e5410" dependencies = [ "libc", ] +[[package]] +name = "signature" +version = "1.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" +dependencies = [ + "digest 0.10.7", + "rand_core 0.6.4", +] + [[package]] name = "signature" version = "2.2.0" @@ -7539,6 +9041,35 @@ dependencies = [ "types", ] +[[package]] +name = "signing_method" +version = "0.1.0" +source = "git+https://github.com/sigp/lighthouse?rev=f1056d9c#f1056d9c19a699c1cb0215dae416aef41fdd29b8" +dependencies = [ + "eth2_keystore", + "ethereum_serde_utils", + "lockfile", + "parking_lot", + "reqwest 0.11.27", + "serde", + "task_executor", + "types", + "url", + "validator_metrics", +] + +[[package]] +name = "simple_asn1" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "297f631f50729c8c99b84667867963997ec0b50f32b2a7dbcab828ef0541e8bb" +dependencies = [ + "num-bigint", + "num-traits", + "thiserror 2.0.12", + "time", +] + [[package]] name = "slab" version = "0.4.9" @@ -7548,6 +9079,50 @@ dependencies = [ "autocfg", ] +[[package]] +name = "slasher" +version = "0.1.0" +source = "git+https://github.com/sigp/lighthouse?rev=f1056d9c#f1056d9c19a699c1cb0215dae416aef41fdd29b8" +dependencies = [ + "bincode", + "byteorder", + "derivative", + "ethereum_ssz", + "ethereum_ssz_derive", + "filesystem", + "flate2", + "lru 0.12.5", + "metrics", + "parking_lot", + "rand 0.8.5", + "safe_arith", + "serde", + "ssz_types", + "strum 0.24.1", + "tracing", + "tree_hash", + "tree_hash_derive", + "types", +] + +[[package]] +name = "slasher_service" +version = "0.1.0" +source = "git+https://github.com/sigp/lighthouse?rev=f1056d9c#f1056d9c19a699c1cb0215dae416aef41fdd29b8" +dependencies = [ + "beacon_chain", + "directory", + "lighthouse_network", + "network 0.2.0", + "slasher", + "slot_clock", + "state_processing", + "task_executor", + "tokio", + "tracing", + "types", +] + [[package]] name = "slashing_protection" version = "0.1.0" @@ -7645,6 +9220,16 @@ dependencies = [ "lock_api", ] +[[package]] +name = "spki" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" +dependencies = [ + "base64ct", + "der 0.6.1", +] + [[package]] name = "spki" version = "0.7.3" @@ -7652,7 +9237,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" dependencies = [ "base64ct", - "der", + "der 0.7.10", ] [[package]] @@ -7708,6 +9293,32 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +[[package]] +name = "state_processing" +version = "0.2.0" +source = "git+https://github.com/sigp/lighthouse?rev=f1056d9c#f1056d9c19a699c1cb0215dae416aef41fdd29b8" +dependencies = [ + "arbitrary", + "bls", + "derivative", + "ethereum_hashing", + "ethereum_ssz", + "ethereum_ssz_derive", + "int_to_bytes", + "integer-sqrt", + "itertools 0.10.5", + "merkle_proof", + "metrics", + "rand 0.8.5", + "rayon", + "safe_arith", + "smallvec", + "ssz_types", + "test_random_derive", + "tree_hash", + "types", +] + [[package]] name = "static_assertions" version = "1.1.0" @@ -7724,6 +9335,35 @@ dependencies = [ "spin", ] +[[package]] +name = "store" +version = "0.2.0" +source = "git+https://github.com/sigp/lighthouse?rev=f1056d9c#f1056d9c19a699c1cb0215dae416aef41fdd29b8" +dependencies = [ + "bls", + "db-key", + "directory", + "ethereum_ssz", + "ethereum_ssz_derive", + "itertools 0.10.5", + "leveldb", + "logging", + "lru 0.12.5", + "metrics", + "parking_lot", + "safe_arith", + "serde", + "smallvec", + "state_processing", + "strum 0.24.1", + "superstruct", + "tracing", + "tracing-subscriber", + "types", + "xdelta3", + "zstd 0.13.3", +] + [[package]] name = "strsim" version = "0.10.0" @@ -7884,6 +9524,21 @@ dependencies = [ "syn 2.0.100", ] +[[package]] +name = "sysinfo" +version = "0.26.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c18a6156d1f27a9592ee18c1a846ca8dd5c258b7179fc193ae87c74ebb666f5" +dependencies = [ + "cfg-if", + "core-foundation-sys", + "libc", + "ntapi", + "once_cell", + "rayon", + "winapi", +] + [[package]] name = "system-configuration" version = "0.5.1" @@ -7926,6 +9581,18 @@ dependencies = [ "libc", ] +[[package]] +name = "system_health" +version = "0.1.0" +source = "git+https://github.com/sigp/lighthouse?rev=f1056d9c#f1056d9c19a699c1cb0215dae416aef41fdd29b8" +dependencies = [ + "lighthouse_network", + "parking_lot", + "serde", + "sysinfo", + "types", +] + [[package]] name = "tagptr" version = "0.2.0" @@ -8078,6 +9745,37 @@ dependencies = [ "time-core", ] +[[package]] +name = "timer" +version = "0.2.0" +source = "git+https://github.com/sigp/lighthouse?rev=f1056d9c#f1056d9c19a699c1cb0215dae416aef41fdd29b8" +dependencies = [ + "beacon_chain", + "slot_clock", + "task_executor", + "tokio", + "tracing", +] + +[[package]] +name = "tiny-bip39" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62cc94d358b5a1e84a5cb9109f559aa3c4d634d2b1b4de3d0fa4adc7c78e2861" +dependencies = [ + "anyhow", + "hmac 0.12.1", + "once_cell", + "pbkdf2 0.11.0", + "rand 0.8.5", + "rustc-hash 1.1.0", + "sha2 0.10.8", + "thiserror 1.0.69", + "unicode-normalization", + "wasm-bindgen", + "zeroize", +] + [[package]] name = "tiny-keccak" version = "2.0.2" @@ -8170,6 +9868,17 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-rustls" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f" +dependencies = [ + "rustls 0.22.4", + "rustls-pki-types", + "tokio", +] + [[package]] name = "tokio-rustls" version = "0.26.2" @@ -8229,6 +9938,17 @@ version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" +[[package]] +name = "toml_edit" +version = "0.19.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +dependencies = [ + "indexmap 2.9.0", + "toml_datetime", + "winnow 0.5.40", +] + [[package]] name = "toml_edit" version = "0.22.24" @@ -8237,7 +9957,7 @@ checksum = "17b4795ff5edd201c7cd6dca065ae59972ce77d1b80fa0a84d94950ece7d1474" dependencies = [ "indexmap 2.9.0", "toml_datetime", - "winnow", + "winnow 0.7.6", ] [[package]] @@ -8406,6 +10126,16 @@ dependencies = [ "syn 2.0.100", ] +[[package]] +name = "triehash" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1631b201eb031b563d2e85ca18ec8092508e262a3196ce9bd10a67ec87b9f5c" +dependencies = [ + "hash-db", + "rlp", +] + [[package]] name = "triomphe" version = "0.1.14" @@ -8433,7 +10163,7 @@ dependencies = [ "http 1.3.1", "httparse", "log", - "rand 0.9.0", + "rand 0.9.1", "rustls 0.23.26", "rustls-pki-types", "sha1", @@ -8537,6 +10267,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccb97dac3243214f8d8507998906ca3e2e0b900bf9bf4870477f125b82e68f6e" +[[package]] +name = "unicase" +version = "2.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" + [[package]] name = "unicode-ident" version = "1.0.18" @@ -8666,6 +10402,129 @@ dependencies = [ "getrandom 0.3.2", ] +[[package]] +name = "validator_client" +version = "0.3.5" +source = "git+https://github.com/sigp/lighthouse?rev=f1056d9c#f1056d9c19a699c1cb0215dae416aef41fdd29b8" +dependencies = [ + "account_utils", + "beacon_node_fallback", + "clap", + "clap_utils", + "directory", + "dirs 3.0.2", + "doppelganger_service", + "environment", + "eth2", + "fdlimit", + "graffiti_file", + "hyper 1.6.0", + "initialized_validators", + "lighthouse_validator_store", + "metrics", + "monitoring_api", + "parking_lot", + "reqwest 0.11.27", + "sensitive_url", + "serde", + "slashing_protection", + "slot_clock", + "tokio", + "tracing", + "types", + "validator_http_api", + "validator_http_metrics", + "validator_metrics", + "validator_services", + "validator_store", +] + +[[package]] +name = "validator_dir" +version = "0.1.0" +source = "git+https://github.com/sigp/lighthouse?rev=f1056d9c#f1056d9c19a699c1cb0215dae416aef41fdd29b8" +dependencies = [ + "bls", + "deposit_contract", + "derivative", + "eth2_keystore", + "filesystem", + "hex", + "lockfile", + "rand 0.8.5", + "tree_hash", + "types", +] + +[[package]] +name = "validator_http_api" +version = "0.1.0" +source = "git+https://github.com/sigp/lighthouse?rev=f1056d9c#f1056d9c19a699c1cb0215dae416aef41fdd29b8" +dependencies = [ + "account_utils", + "beacon_node_fallback", + "bls", + "deposit_contract", + "directory", + "dirs 3.0.2", + "doppelganger_service", + "eth2", + "eth2_keystore", + "ethereum_serde_utils", + "filesystem", + "graffiti_file", + "health_metrics", + "initialized_validators", + "lighthouse_validator_store", + "lighthouse_version", + "logging", + "parking_lot", + "rand 0.8.5", + "sensitive_url", + "serde", + "serde_json", + "signing_method", + "slashing_protection", + "slot_clock", + "sysinfo", + "system_health", + "task_executor", + "tempfile", + "tokio", + "tokio-stream", + "tracing", + "types", + "url", + "validator_dir", + "validator_services", + "validator_store", + "warp", + "warp_utils", + "zeroize", +] + +[[package]] +name = "validator_http_metrics" +version = "0.1.0" +source = "git+https://github.com/sigp/lighthouse?rev=f1056d9c#f1056d9c19a699c1cb0215dae416aef41fdd29b8" +dependencies = [ + "health_metrics", + "lighthouse_validator_store", + "lighthouse_version", + "logging", + "malloc_utils", + "metrics", + "parking_lot", + "serde", + "slot_clock", + "tracing", + "types", + "validator_metrics", + "validator_services", + "warp", + "warp_utils", +] + [[package]] name = "validator_metrics" version = "0.1.0" @@ -8752,15 +10611,15 @@ version = "5.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fec4ebcc5594130c31b49594d55c0583fe80621f252f570b222ca4845cafd3cf" dependencies = [ - "crypto-bigint", - "elliptic-curve", + "crypto-bigint 0.5.5", + "elliptic-curve 0.13.8", "elliptic-curve-tools", "generic-array 1.2.0", "hex", "num", "rand_core 0.6.4", "serde", - "sha3", + "sha3 0.10.8", "subtle", "zeroize", ] @@ -8783,6 +10642,52 @@ dependencies = [ "try-lock", ] +[[package]] +name = "warp" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4378d202ff965b011c64817db11d5829506d3404edeadb61f190d111da3f231c" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "headers", + "http 0.2.12", + "hyper 0.14.32", + "log", + "mime", + "mime_guess", + "percent-encoding", + "pin-project", + "rustls-pemfile 2.2.0", + "scoped-tls", + "serde", + "serde_json", + "serde_urlencoded", + "tokio", + "tokio-rustls 0.25.0", + "tokio-util", + "tower-service", + "tracing", +] + +[[package]] +name = "warp_utils" +version = "0.1.0" +source = "git+https://github.com/sigp/lighthouse?rev=f1056d9c#f1056d9c19a699c1cb0215dae416aef41fdd29b8" +dependencies = [ + "bytes", + "eth2", + "headers", + "safe_arith", + "serde", + "serde_array_query", + "serde_json", + "tokio", + "types", + "warp", +] + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -8931,6 +10836,18 @@ dependencies = [ "rustls-pki-types", ] +[[package]] +name = "which" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +dependencies = [ + "either", + "home", + "once_cell", + "rustix 0.38.44", +] + [[package]] name = "widestring" version = "0.4.3" @@ -9427,6 +11344,15 @@ version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" +[[package]] +name = "winnow" +version = "0.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] + [[package]] name = "winnow" version = "0.7.6" @@ -9495,6 +11421,12 @@ dependencies = [ "web-sys", ] +[[package]] +name = "wyz" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214" + [[package]] name = "wyz" version = "0.5.1" @@ -9533,6 +11465,20 @@ dependencies = [ "time", ] +[[package]] +name = "xdelta3" +version = "0.1.5" +source = "git+http://github.com/sigp/xdelta3-rs?rev=4db64086bb02e9febb584ba93b9d16bb2ae3825a#4db64086bb02e9febb584ba93b9d16bb2ae3825a" +dependencies = [ + "bindgen", + "cc", + "futures-io", + "futures-util", + "libc", + "log", + "rand 0.8.5", +] + [[package]] name = "xml-rs" version = "0.8.26" @@ -9733,7 +11679,7 @@ dependencies = [ "pbkdf2 0.11.0", "sha1", "time", - "zstd", + "zstd 0.11.2+zstd.1.5.2", ] [[package]] @@ -9742,7 +11688,16 @@ version = "0.11.2+zstd.1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4" dependencies = [ - "zstd-safe", + "zstd-safe 5.0.2+zstd.1.5.2", +] + +[[package]] +name = "zstd" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a" +dependencies = [ + "zstd-safe 7.2.4", ] [[package]] @@ -9755,6 +11710,15 @@ dependencies = [ "zstd-sys", ] +[[package]] +name = "zstd-safe" +version = "7.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f49c4d5f0abb602a93fb8736af2a4f4dd9512e36f7f570d66e65ff867ed3b9d" +dependencies = [ + "zstd-sys", +] + [[package]] name = "zstd-sys" version = "2.0.15+zstd.1.5.7" diff --git a/Cargo.toml b/Cargo.toml index 972c533de..5c40b25b3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,6 +13,7 @@ members = [ "anchor/eth", "anchor/http_api", "anchor/http_metrics", + "anchor/integration", "anchor/keygen", "anchor/keysplit", "anchor/message_receiver", @@ -38,8 +39,8 @@ bls_lagrange = { path = "anchor/common/bls_lagrange" } client = { path = "anchor/client" } database = { path = "anchor/database" } eth = { path = "anchor/eth" } -http_api = { path = "anchor/http_api" } -http_metrics = { path = "anchor/http_metrics" } +http_api = { path = "anchor/http_api", package = "anchor_http_api" } +http_metrics = { path = "anchor/http_metrics", package = "anchor_http_metrics" } keygen = { path = "anchor/keygen" } keysplit = { path = "anchor/keysplit" } message_receiver = { path = "anchor/message_receiver" } @@ -57,11 +58,16 @@ version = { path = "anchor/common/version" } beacon_node_fallback = { git = "https://github.com/sigp/lighthouse", rev = "f1056d9c" } bls = { git = "https://github.com/sigp/lighthouse", rev = "f1056d9c" } +environment = { git = "https://github.com/sigp/lighthouse", rev = "f1056d9c" } eth2 = { git = "https://github.com/sigp/lighthouse", rev = "f1056d9c" } eth2_network_config = { git = "https://github.com/sigp/lighthouse", rev = "f1056d9c" } +execution_layer = { git = "https://github.com/sigp/lighthouse", rev = "f1056d9c" } health_metrics = { git = "https://github.com/sigp/lighthouse", rev = "f1056d9c" } +kzg = { git = "https://github.com/sigp/lighthouse", rev = "f1056d9c" } lighthouse_network = { git = "https://github.com/sigp/lighthouse", rev = "f1056d9c" } +logging = { git = "https://github.com/sigp/lighthouse", rev = "f1056d9c" } metrics = { git = "https://github.com/sigp/lighthouse", rev = "f1056d9c" } +node_test_rig = { git = "https://github.com/sigp/lighthouse", rev = "f1056d9c" } safe_arith = { git = "https://github.com/sigp/lighthouse", rev = "f1056d9c" } sensitive_url = { git = "https://github.com/sigp/lighthouse", rev = "f1056d9c" } slashing_protection = { git = "https://github.com/sigp/lighthouse", rev = "f1056d9c" } @@ -95,6 +101,7 @@ derive_more = { version = "2.0.1", features = ["full"] } dirs = "6.0.0" discv5 = "0.9.0" enr = "0.13.0" +ethereum_serde_utils = "0.7.0" ethereum_ssz = "0.8" ethereum_ssz_derive = "0.8" futures = "0.3.30" diff --git a/anchor/client/src/config.rs b/anchor/client/src/config.rs index 4c1d10520..15d20c465 100644 --- a/anchor/client/src/config.rs +++ b/anchor/client/src/config.rs @@ -57,6 +57,8 @@ pub struct Config { pub execution_nodes_tls_certs: Option>, /// Configuration for the processor pub processor: processor::Config, + /// If database sync should be skipped + pub skip_sync: bool, /// Password used to encrypt rsa keyfile pub password: Option, /// If slashing protection is disabled @@ -104,6 +106,7 @@ impl Config { beacon_nodes_tls_certs: None, execution_nodes_tls_certs: None, processor: <_>::default(), + skip_sync: false, password: None, disable_slashing_protection: false, impostor: None, diff --git a/anchor/client/src/lib.rs b/anchor/client/src/lib.rs index fff0cbfc5..35ca65871 100644 --- a/anchor/client/src/lib.rs +++ b/anchor/client/src/lib.rs @@ -81,7 +81,11 @@ pub struct Client {} impl Client { /// Runs the Anchor Client - pub async fn run(executor: TaskExecutor, config: Config) -> Result<(), String> { + pub async fn run( + executor: TaskExecutor, + config: Config, + spec: Option, + ) -> Result<(), String> { // Attempt to raise soft fd limit. The behavior is OS specific: // `linux` - raise soft fd limit to hard // `macos` - raise soft fd limit to `min(kernel limit, hard fd limit)` @@ -111,7 +115,11 @@ impl Client { "Starting the Anchor client" ); - let spec = Arc::new(config.ssv_network.eth2_network.chain_spec::()?); + let spec = if let Some(spec) = spec { + Arc::new(spec) + } else { + Arc::new(config.ssv_network.eth2_network.chain_spec::()?) + }; let key = read_or_generate_private_key(&config.data_dir.join("key.pem"), config.password)?; let err = |e| format!("Unable to derive public key: {e:?}"); @@ -339,9 +347,6 @@ impl Client { let proposer_nodes = Arc::new(proposer_nodes); start_fallback_updater_service::<_, E>(executor.clone(), proposer_nodes.clone())?; - // Wait until genesis has occurred. - wait_for_genesis(&beacon_nodes, genesis_time).await?; - // Start validator index syncer let index_sync_tx = start_validator_index_syncer(beacon_nodes.clone(), database.clone(), executor.clone()); @@ -375,7 +380,7 @@ impl Client { executor.spawn( async move { - if let Err(e) = syncer.sync().await { + if let Err(e) = syncer.sync(config.skip_sync).await { error!("Syncer failed: {e}"); } }, @@ -546,6 +551,9 @@ impl Client { let channel_capacity = E::slots_per_epoch() as usize; let (block_service_tx, block_service_rx) = mpsc::channel(channel_capacity); + // Wait until genesis has occurred. + wait_for_genesis(&beacon_nodes, genesis_time).await?; + duties_service::start_update_service(duties_service.clone(), block_service_tx); block_service @@ -766,18 +774,32 @@ async fn wait_for_operator_id_and_sync( ) -> Option { let sleep_duration = Duration::from_secs(spec.seconds_per_slot); let mut state = database.watch(); - let id = loop { - select! { - result = state.changed() => { - result.ok()?; - if let Some(id) = state.borrow().get_own_id() { - break id; + + // Extract the value while the borrow is active. + let maybe_id = { + let current_state = state.borrow(); + current_state.get_own_id() + }; + + // Now the borrow is dropped; match on the extracted value. + let id = match maybe_id { + Some(id) => id, + None => loop { + select! { + result = state.changed() => { + result.ok()?; + if let Some(id) = state.borrow().get_own_id() { + break id; + } } + _ = sleep(sleep_duration) => info!("Waiting for operator id"), } - _ = sleep(sleep_duration) => info!("Waiting for operator id"), - } + }, }; + info!(id = *id, "Operator found on chain"); + + // Wait for sync to finish loop { select! { result = &mut sync_notification => return result.ok().map(|_| id), diff --git a/anchor/eth/execution.rs b/anchor/eth/execution.rs new file mode 100644 index 000000000..ef2a92caa --- /dev/null +++ b/anchor/eth/execution.rs @@ -0,0 +1,64 @@ +use std::{path::Path, sync::Arc}; + +use base64::prelude::*; +use database::NetworkDatabase; +use eth::{Config, SsvEventSyncer}; +use openssl::rsa::Rsa; +use ssv_network_config::SsvNetworkConfig; +use tracing_subscriber::{fmt, prelude::*, EnvFilter}; + +// This is a test binary to execute event syncing for the SSV Network +#[tokio::main] +async fn main() { + // Setup a log filter & tracing + let filter = EnvFilter::builder() + .parse("info,hyper=off,hyper_util=off,alloy_transport_http=off,reqwest=off,alloy_rpc_client=off,alloy_transport_ws=off,alloy_pubsub=off") + .expect("filter should be valid"); + tracing_subscriber::registry() + .with(fmt::layer()) + .with(filter) + .init(); + + // Dummy configuration with endpoint and network + let rpc_endpoint = "http://127.0.0.1:8545"; + let ws_endpoint = "ws://127.0.0.1:8546"; + let beacon_endpoint = "http://127.0.0.1:5052"; + let config = Config { + http_url: String::from(rpc_endpoint), + ws_url: String::from(ws_endpoint), + beacon_url: String::from(beacon_endpoint), + network: SsvNetworkConfig::constant("holesky").unwrap().unwrap(), + historic_finished_notify: None, + }; + + // Setup mock operator data + let path = Path::new("db.sqlite"); + let pem_data = "LS0tLS1CRUdJTiBSU0EgUFVCTElDIEtFWS0tLS0tCk1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBMVg2MUFXY001QUNLaGN5MTlUaEIKby9HMWlhN1ByOVUralJ5aWY5ZjAyRG9sd091V2ZLLzdSVUlhOEhEbHBvQlVERDkwRTVQUGdJSy9sTXB4RytXbwpwQ2N5bTBpWk9UT0JzNDE5bEh3TzA4bXFja1JsZEg5WExmbmY2UThqWFR5Ym1yYzdWNmwyNVprcTl4U0owbHR1CndmTnVTSzNCZnFtNkQxOUY0aTVCbmVaSWhjRVJTYlFLWDFxbWNqYnZFL2cyQko4TzhaZUgrd0RzTHJiNnZXQVIKY3BYWG1uelE3Vlp6ZklHTGVLVU1CTTh6SW0rcXI4RGZ4SEhSeVU1QTE3cFU4cy9MNUp5RXE1RGJjc2Q2dHlnbQp5UE9BYUNzWldVREI3UGhLOHpUWU9WYi9MM1lnSTU4bjFXek5IM0s5cmFreUppTmUxTE9GVVZzQTFDUnhtQ2YzCmlRSURBUUFCCi0tLS0tRU5EIFJTQSBQVUJMSUMgS0VZLS0tLS0K"; + let pem_decoded = BASE64_STANDARD.decode(pem_data).unwrap(); + let mut pem_string = String::from_utf8(pem_decoded).unwrap(); + pem_string = pem_string + .replace( + "-----BEGIN RSA PUBLIC KEY-----", + "-----BEGIN PUBLIC KEY-----", + ) + .replace("-----END RSA PUBLIC KEY-----", "-----END PUBLIC KEY-----"); + let rsa_pubkey = Rsa::public_key_from_pem(pem_string.as_bytes()) + .map_err(|e| format!("Failed to parse RSA public key: {}", e)) + .unwrap(); + + // The event syncer is spawned into a background task since it is long running and should never + // exist. It will communicate with the rest of the system via processor channels and constantly + // keep the database up to date with new data for the rest of the system + let db = Arc::new(NetworkDatabase::new(path, &rsa_pubkey).unwrap()); + let mut event_syncer = SsvEventSyncer::new(db.clone(), config) + .await + .expect("Failed to construct event syncer"); + tokio::spawn(async move { + // this should never return, if it does we should gracefully handle it and shutdown the + // client. + event_syncer.sync(false).await + }); + loop { + let _ = tokio::time::sleep(std::time::Duration::from_secs(100)).await; + } +} diff --git a/anchor/eth/src/sync.rs b/anchor/eth/src/sync.rs index 1a6744041..4c237d366 100644 --- a/anchor/eth/src/sync.rs +++ b/anchor/eth/src/sync.rs @@ -223,7 +223,7 @@ impl SsvEventSyncer { #[instrument(skip(self))] /// Try to perform both a historical and live sync from the chain - pub async fn sync(&mut self) -> Result<(), ExecutionError> { + pub async fn sync(&mut self, skip: bool) -> Result<(), ExecutionError> { info!("Starting SSV event sync"); // Get network specific contract information let contract_address = self.network.ssv_contract; @@ -234,7 +234,10 @@ impl SsvEventSyncer { deployment_block, "Using contract configuration" ); loop { - match self.try_sync(contract_address, deployment_block).await { + match self + .try_sync(contract_address, deployment_block, skip) + .await + { Ok(_) => unreachable!("Sync should never finish successfully"), Err(e) => { error!(?e, "Sync failed, attempting recovery"); @@ -313,10 +316,13 @@ impl SsvEventSyncer { &mut self, contract_address: Address, deployment_block: u64, + skip: bool, ) -> Result<(), ExecutionError> { info!("Starting historical sync"); - self.historical_sync(contract_address, deployment_block, SSV_EVENTS.clone()) - .await?; + if !skip { + self.historical_sync(contract_address, deployment_block, SSV_EVENTS.clone()) + .await?; + } self.historic_finished_notify.take().map(|x| x.send(())); diff --git a/anchor/http_api/Cargo.toml b/anchor/http_api/Cargo.toml index e82b755f2..9848d0e4b 100644 --- a/anchor/http_api/Cargo.toml +++ b/anchor/http_api/Cargo.toml @@ -1,13 +1,9 @@ [package] -name = "http_api" +name = "anchor_http_api" version = "0.1.0" edition = { workspace = true } authors = ["Sigma Prime "] -[lib] -name = "http_api" -path = "src/lib.rs" - [dependencies] api_types = { workspace = true } axum = { workspace = true } diff --git a/anchor/http_metrics/Cargo.toml b/anchor/http_metrics/Cargo.toml index 526ace83b..4ab384efd 100644 --- a/anchor/http_metrics/Cargo.toml +++ b/anchor/http_metrics/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "http_metrics" +name = "anchor_http_metrics" version = "0.1.0" edition = "2021" diff --git a/anchor/integration/.gitignore b/anchor/integration/.gitignore new file mode 100644 index 000000000..73fbfbe07 --- /dev/null +++ b/anchor/integration/.gitignore @@ -0,0 +1,3 @@ +mock-data/operator-*/network/enr.dat +mock-data/operator-*/slashing_protection.sqlite +mock-data/operator-*/slashing_protection.sqlite-journal diff --git a/anchor/integration/Cargo.toml b/anchor/integration/Cargo.toml new file mode 100644 index 000000000..5a2a80ce7 --- /dev/null +++ b/anchor/integration/Cargo.toml @@ -0,0 +1,30 @@ +[package] +name = "integration" +version = "0.1.0" +edition = "2021" + +[dependencies] +axum = { version = "0.8.3", features = ["ws"] } +clap = { workspace = true } +client = { workspace = true } +discv5 = { workspace = true } +environment = { workspace = true } +ethereum_serde_utils = { workspace = true } +execution_layer = { workspace = true } +futures = { workspace = true } +futures-util = "0.3.31" +kzg = { workspace = true } +lighthouse_network = { workspace = true } +logging = { workspace = true } +network = { workspace = true } +node_test_rig = { workspace = true } +parking_lot = { workspace = true } +sensitive_url = { workspace = true } +serde_json = { workspace = true } +ssv_network_config = { workspace = true } +task_executor = { workspace = true } +tokio = { workspace = true } +tokio-tungstenite = "0.26.2" +tracing = { workspace = true } +tracing-subscriber = { workspace = true } +types = { workspace = true } diff --git a/anchor/integration/mock-data/operator-0/anchor_db.sqlite b/anchor/integration/mock-data/operator-0/anchor_db.sqlite new file mode 100644 index 000000000..cf72ba970 Binary files /dev/null and b/anchor/integration/mock-data/operator-0/anchor_db.sqlite differ diff --git a/anchor/integration/mock-data/operator-0/key.pem b/anchor/integration/mock-data/operator-0/key.pem new file mode 100644 index 000000000..6ce574cba --- /dev/null +++ b/anchor/integration/mock-data/operator-0/key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAhUFm5HcFcxYvJHiFS6QNFQFf4xWhvv3v+p14rgN9rIAwb4nE +nFsqcH8hzCAEFqOV8pzYRPQuE4CBAzyUI3QHuu3VT9B5U3NKZagXiNQKjlucLbq1 +I5vQFz3wt5gnsxqOj5+6vkywTKk5IbroMTHNSxsOt+96G7u0gYmmAYfp4F9BGN6Q +0QLGkRiwgsoBLlcSoI4wJCbpE2k2iMu9nDD4DiJ3wyaLIUnOh0sl2hGGXgtUWL+m +q0vZO2bNM4/4dlClix8Fr1EBi03FxzqCR75tbR1o+LLRW9lIPLOQkZ/1ba2dbU2b ++5kZbW50W0GMSlo2ShEpHkWv1gskLq4x7jUNiQIDAQABAoIBAAJeML0iFVAf0TYk +HcrujxyeseIX6LrQtI0+852fVRd15AZzYQbzQsbi0h+tuPeLBXeHzHsLM29oHZgd +toyGZmXEDgHqqeFEVPUx/mW8I4o3PAhUVJ2ISl4Ysm3yGlB/NLsozY7N+jsJLclO +PYve6e+Upey5qMaUjbxYjRaNYFKlmsgsIRzv0Qf6voTyvRrLfgOSgc0ayCuE3RP8 +B/uWbAad3gCHLyLGFueP3SQLWtGZH1WZKU9dfk51kl2ZFO+shL/ll5ws/U/kzbON +YouE5r9JxJ2zXqnPDxw0czNSgF/GSGNB5yVXsIUPhdakRmjqxt1n0+vcxa+GOir8 +UUbRAQECgYEAuQnT3HXDwoUO8ge9Ry++1YxEgBnxSHkW0WM5dGpS8rgt6kkmONfk +fTSPAR0ZCS9Am9UHkjRLWXB9fRqoNgjDDHDtO+VJsgYsEz4y7Jjs/dhJz1QGD1zj +CSHzJIlgCzdteV5mg1/Qq71szciknrH0QHTZcBqAMw7Pvlyo9n09CoECgYEAuFvH +ZRP8EapzQiqJ2Rwxu+uPtc3QTX/OxjHNbMxLUf1owcfG6X8JnPHrAy5AtkX6RZwH +TximezkyXl3eD7+vP1xSd3+1BuUTkkDWB8El+MgF8SOR117030Jqh4X2Fckl7Ztl +Z5SL8/YoGtvJ2hShI90WwD7OSbuedUoQdW0iLwkCgYEAr56VNuOKtb9FzQ7tZXf6 +XoHvrclxiMBsmLTdHhGfwoBuC7P7k+3MDc1pgLwWO/JeFsjck7YQYcXzRF6dkhNE +1DUF5FgdVtqm0GizOn12SQMUIrPzwHb/gHZ5Z47+2gZ0X8Hp9/xjd+ykLLenDnuF +f/unN8/fJxaCs4EMWE3LNoECgYADbpHzq7+RhJ7IqIoQZJn4aZYvSDmMd8idn+e3 +EsaELDd7BAEL77V6GnbJhF7oBb129kSckFTpDlOFtjGgEW1tvIY8e0AfdLw8iMBz +PIE8dFzH9GWOoNHmJhJdm3zNQwVVuwLUPsusKvTsKxNC4Adv53m48nJcpQV6IXrU +9MciIQKBgQCFs5AT7Ebcyz55yAEskhFP6QN9TQTlJWxosadeaBXCupeAsTYfR5ch +shp0XqnV0hmVmAYmzqZCuw5idfxhB8YVxdES2lwAH4uMIObBSJe6lKNwF35sNUrl +wKBYDngF5SQlJAxUBV6inKsMRY+ry5qofUC9IuaxzgsW0+3GbkSuwQ== +-----END RSA PRIVATE KEY----- diff --git a/anchor/integration/mock-data/operator-0/network/key b/anchor/integration/mock-data/operator-0/network/key new file mode 100644 index 000000000..5f12cf0c5 --- /dev/null +++ b/anchor/integration/mock-data/operator-0/network/key @@ -0,0 +1 @@ +K& ]>S&.Ƌ-4705Ռk \ No newline at end of file diff --git a/anchor/integration/mock-data/operator-1/anchor_db.sqlite b/anchor/integration/mock-data/operator-1/anchor_db.sqlite new file mode 100644 index 000000000..cf72ba970 Binary files /dev/null and b/anchor/integration/mock-data/operator-1/anchor_db.sqlite differ diff --git a/anchor/integration/mock-data/operator-1/key.pem b/anchor/integration/mock-data/operator-1/key.pem new file mode 100644 index 000000000..2d557ed84 --- /dev/null +++ b/anchor/integration/mock-data/operator-1/key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAyZrTHN8hJ2Zc6xHXnqVkxes1VEVUL7oCJe4WzRoGp6Hbymo+ +nG4DQxLZZHxWUUppXmaMNTBpv0XpKz01EHO20oCfM0pzUMDPq0gfARsMJ4BnE/6K +2lUTdRbzZ1iT7A2jH8MXPYtTI2Wc5JOAI082rKU9jeZ+C42D57Xkw45EHR3WF/W1 +0Xt2pccMjfAiU2TKySnjiJKh/Vac2QrnScHI9k7w5cZjgmbdCKrob3J5zedZjApN +xZhzdMWEFI+GZIsPfc6HVSl2xn1f5CXtB/PcEIAPW0WuR//l65M0fG/geXskbBvM +f2nbV6h+sNE3XHW/8ePzk0QBg8bVOuzMsYm2/QIDAQABAoIBAC9ysyONJzgm6REB +HMJvkjFbm2xHOdpWuJk1OSQR70WGPFyeFzjJUpa3abcy5TzSGsz3LSH6kDTObyN4 +TxQda8aMs4tGhy/XBTk+at+ffkOQvpHP212p3r+0xFoLGJtalU0NJRvcvdcrm9qX +FXYZ91f4Nu299OXiq0v+PQZCZikEuOv2lnJ+XMx12meJbQ+aslnRUOzzlaiWK4ms +rcgtst7L8fPaa/Js0HXL5NNSnbiwJEVrVg5yPYPgWGMcdXj14aICW0aONUlm7DV6 +urg+1jquuE8oGE5xZJkzzjPTE/8D1CmmqMfdcYVxS1CwF3miwhN+A61LZ7glvp08 +NrLFe/kCgYEA6XxOAsZb2nOndh4Ln0lkn0rYb16uPzhH/XaJoDfPHg/O310LUQ8K +Ot5wGoyp1/L+KHdiI5wWzOj0wLKiK68L5nQKNChzFUXgZkmYLajvTPfh++PpWj/a +jigTVqS76cwIvYnDWrwXqGwUil5SI8e+BPlUb1tzkxp+huc7UYXyzGUCgYEA3QuH +U/TdlvqZVKW+xKOf5fnEBC6H6Ic6GNViI0Sgvzcqef4AKmHbEJnl+2VkfOeUvdH0 +d34G8ZOBqAj/X5cDoCALcplN5lL60GC3rVrzVvn2lcoy9uIhd3ibJD3lVcYmj98T +GzysGHlzOGiY38sz24wTTMcyRqS1n53MdgeO2rkCgYAfgvxQWY8aC5PlWCa/Z7th +2EsftMqVk7X7mlz2t7GHYCDOepNFbF84FL9ShfuCPrRYp8wh/DYDj8lAnJtQg/56 +Kt0Zrv/hNh4UEAiu2Ob7H1VrlpXu7UFFAFmjzvXhlvzy/73S6CHVREj9Z790PsgB +idkAcnpFt0SuVlTmKsrbFQKBgQC9LpLB/j5wa0Yzti9RaKD/WQa0dYaIMsQ8YNQ/ +Twss3HAUPJmzrFCrIqw8vwiEBke9NiY+5rPWqeI8CIdYLo1BzGs/x4luaPKUyVIq +oj7F3+V1SbrYpazy7VwKZpcTFCYI2Gkn1ION5tQAITVFxEo7yuTxv0J+R5XSaGGH +WuyesQKBgEqw+pAg8HchUqUEfRyTpwR3XY/3mxujnZCPcNiXaf61DgBPLsnqICRQ +5xoQV5BnO9wV/hTfM32UT1g7mC/TEuLoKDPSlHfFW4JMpwfS1vTfHITQJxnVwT71 +qn1+dK5Zg0b0D6Vu2lPTu5rIcbkki44Pyd6k5y7HJpLiaWf8EAO2 +-----END RSA PRIVATE KEY----- diff --git a/anchor/integration/mock-data/operator-1/network/key b/anchor/integration/mock-data/operator-1/network/key new file mode 100644 index 000000000..0b3540b46 --- /dev/null +++ b/anchor/integration/mock-data/operator-1/network/key @@ -0,0 +1 @@ +G7ph®53g \ No newline at end of file diff --git a/anchor/integration/mock-data/operator-2/anchor_db.sqlite b/anchor/integration/mock-data/operator-2/anchor_db.sqlite new file mode 100644 index 000000000..cf72ba970 Binary files /dev/null and b/anchor/integration/mock-data/operator-2/anchor_db.sqlite differ diff --git a/anchor/integration/mock-data/operator-2/key.pem b/anchor/integration/mock-data/operator-2/key.pem new file mode 100644 index 000000000..0a3391141 --- /dev/null +++ b/anchor/integration/mock-data/operator-2/key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAieDAKjjoO40ifjHaO+eJKv8CVrNPagN+FKOPX3/RwDYxmMw8 +vjdlvlireS5zWPyFV7FeYL09HJfh0+KIf18aP7lEFf7TmmT1rORzJ+phqXksT46L +hk+k+OVpXJmu+Y92KONWyotnF1XooAPzQnjiWd9iRKTPiHLvVEyMyDYLsrUYxMYB +1NadopONTYWzcV13lERlyT3yC9CxVVUVFoD9SSRqMz5xH+969yAqC5ruSmtfuZ5O +DmB01zRvMat9n49W0isCQkOrgwJo0To7U5hyI0PzH87DIAXB3T5AbpeEiV7MCObe +rbaUF0B+iZyNvOCahu9LPo09srAR3CeYMeFFKwIDAQABAoIBABURC5uH7Wfn9Ry+ +Bj+/7VPt+dAAfsJOfU2u/gGT+Jr7TNGxZxiTQ071omGWKNawYrlW5vo1/+fmBwHG +a5+2ir6w0off0zoUcfs0PqobJEfuNUiEmanwcl77QoF9E+CavG2b6s9wxFQq8qu8 +XsdJzB/6QzwEyJbrJMlHFv2iUGBCFPC155NTMs47FCvmCxHQTqLCWnFPz51EnGMQ +HelqRzi2VOdnBm+lvKtoEWKFT7Iy87EwebsHYRVcJnMlMNFMhwjyywxSgTy2OR2x +tYEDbvMAHu3ZjBh0sJGrU2Xt/JjPrL+Z24nGN9WWmw4unL00mGjMv4zIb3WqQW01 +MWxtjuECgYEAwjGyE2rrpx5y1W/VePiOCzCDoCj72gM6KsAoDJkNuJtOY3Zoq6BP +j0109prvRxe/Q9GbDMUfsn7Pff7KMCJmkQMLI4TCt8Oh5lEu2Hx5OUKDWPTLG8tu +UkFaV7yi5na8uximYGMK56eYDgeV9LwCNKf1AoErySlxH3c9f8hpWiECgYEAtcKY +ZD08MaahonskBzDy5ZTGbfhz3yyDt+TjlYv6uTg1N2iI3+c8t+baim/skjVaVzBl +qJvj/e6sz8bwYySkihn8ENHxJQ7PWnQ2TjQKlDmhBJKESavTlAFJIj/SRQH+6yID +LwkJler8xr7n23Ch63qagcNGHphcxEMgZ+efLcsCgYBc592kQJEBYSXbSye8Ol3q +qIkwhKsJQGYBsfD3JfpUiajVGP82rPmjO5FrsfAr+QZ+cbdWQrDJerXWN6GPqcWc +NvKLSabGuAeq4sggtlxgspuYYXUSlR7wp2eLdioRTFk6wa5HitravWmXvLVXYuND +Qd+MFTRXh0YhobCAg+czQQKBgG6XjKnRKIL9ZHO8gVtuyRwvvdzDw50TNMH7nw4r +Mc7pCFhCXqX9yNAMwwRgvYzosaNDa1eAIuUrCDMUVMe+T+9HiDujwhpOPJRJCZHj +0FwIBJUHoT5CMmZnsdwJASPD5xuiglVoJlD1vgAfwGugyKTC4Kf77PpIsokoXttZ +71ypAoGBAKn/JcxllgxFnSPi5/1w+wRyDbvku0bhgWXbneqe59umEKLdQ/hiHbfd +6FyTvUmq6mp+B+0eNc6mtkG7soOTw7LvGtmh4t1ZfjmnToAWlv1+MLZXpuxQJbJ5 +gzZvNBY3CUwn72QVsbCh30IZutEv0WlO9afKzfKBc6tux8Rz+OnD +-----END RSA PRIVATE KEY----- diff --git a/anchor/integration/mock-data/operator-2/network/key b/anchor/integration/mock-data/operator-2/network/key new file mode 100644 index 000000000..1be1a5b06 --- /dev/null +++ b/anchor/integration/mock-data/operator-2/network/key @@ -0,0 +1 @@ +b+??jx+ތĻR۰~HXH \ No newline at end of file diff --git a/anchor/integration/mock-data/operator-3/anchor_db.sqlite b/anchor/integration/mock-data/operator-3/anchor_db.sqlite new file mode 100644 index 000000000..cf72ba970 Binary files /dev/null and b/anchor/integration/mock-data/operator-3/anchor_db.sqlite differ diff --git a/anchor/integration/mock-data/operator-3/key.pem b/anchor/integration/mock-data/operator-3/key.pem new file mode 100644 index 000000000..d77cc2a93 --- /dev/null +++ b/anchor/integration/mock-data/operator-3/key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAz6HCCQiU6T1vwFF/XUVu9tcbfDNbY/2pK4m0kWDN5riGpkxr +g5QOxJNl/IgOwpTlwzV5BRzSUqKedXw6WKQTEr5lAihN4Vt3i0+YsxhiKsSxeOLy +818UiNU+mrjlf2kqnfZOC0P3hWXU5H6HurYOqolofHLBzSqKbAJ8dJAtE/Kr6yie +BSI1Y77+L0hOq4sdU4p7hdn/P8+6szD3OqmwA5keQ/aH85naMEImnflIQtGut+8+ +ulT4rfq+C8/wUOEF1AaUUZt/3WH7g42ViSoEv4GRetS4LRA9PLWJr+GnxOw0Z3iU +UACkJL8Xc1YKrGIDt53WARPpH00O4l8xuSFpAQIDAQABAoIBAASrfLO7T64XRaYr +rxOn9iDzIZkfhpSvJdjm1frXFIp16AFhgqGI+PQO5KJTZRGXS7uiPkCRL2HQaoP1 +8VIBDrTDN35e7bF93yhw99w/ViXkGqG/aPt0Tf/t2+Sa9/5vnRfEbGjwdGa5rZoe +Bmt6oMXRJVp3MkitBkP7olT00S67oiWwIX1HYT8HWepvw0mSmVMVRcefOyDmPBgH +5Mgj0b3KQOaSGohw1QZflPtpkuaQX4Iaxf9wcD/KuvigV1vJrgd9tzcEbxBE1AqC +tOPgJ9glBOcf/sI65EZIHO7v9ckB5xSs27vpZorlqT3wDPxByK9pP/yNGS3Yhkqs +OzUqV4ECgYEA7rvVJv8WP0cWsZfnIOr40lUEo1AgmoYa2VwA9JxOdkE3sUgZRu/K +SdNKfYEyYgwvXYAPgJCL7F3Objhp7uWI1EqOwJ9cT7H2s+98j92HjOg1p/9iOzZE +AohPDdCPC9rM30e7h/5BKg8WNJQPd64lpagL0bpIpuoIoikhLUF+QqkCgYEA3qYS +pw+fJfnReGURrrxsRoiqg6W+eTJZWoVjRwqgXqWNEodTgpH9KP1W8pQrk93WaGh0 +ZIJI7bS8VMzrC3hdFpZdTi9a9mMDtti2d4Bhj8GcUPf9zB8mzRWXmN4gHgEaG1zi +JNkE3msSzhnBB6aRpyUeGuOcELhFcWDsaPUcQpkCgYEAjrrB7zSnCmHoEXlt9+JD +rQyjXzhypa/zsWwuLhCdYFoRf+5JHn4ShRzL9kkd5DzAvLfpjMXewgw7dO5Jd0jI +C5Qf0M32FLejdWSDJkgd2IKkQbKP+jKxaoowKWQ9garovb1XQzEhqJGohvrWXIlD +fM0Bc/xZn2FglALfEP2NDTECgYBnQsil2JXsK/fdiapwywzAjcPfeLBlT1enpvOL +UD9ehhNug3rUtNaf+xcnPFcVpi45kDBjKRWfwVITVlKwqCssPaKaj1X1rahcVhgS +RmV5IcdYuhtoXw5E0X3UtThaEhLEnAh6JHigmzJGiiU/Yh5tUcarm+KW0o/KbLRY +XU21CQKBgCtVpkBcHYbkJn8kSAd2ELnDjc+gEiRBkzYZsmv/j3DDPEkcWB/A30Aa +TOxsMdnK/MEBsrWpianyglm3CDKeDp4YKaUfdLvgcvsFLqFU16TbOKsjYA+hvbtA +fDbKWQmziwS3sk38rgbaMQhWiIk0kY79eBxgtIWYkeNf4uoiZSQm +-----END RSA PRIVATE KEY----- diff --git a/anchor/integration/mock-data/operator-3/network/key b/anchor/integration/mock-data/operator-3/network/key new file mode 100644 index 000000000..0dd895c90 --- /dev/null +++ b/anchor/integration/mock-data/operator-3/network/key @@ -0,0 +1 @@ +:kx:nw^qL{򲏂Jq-$" \ No newline at end of file diff --git a/anchor/integration/src/basic_sim.rs b/anchor/integration/src/basic_sim.rs new file mode 100644 index 000000000..69acdf660 --- /dev/null +++ b/anchor/integration/src/basic_sim.rs @@ -0,0 +1,186 @@ +use std::{cmp::max, sync::Arc, time::Duration}; + +use clap::ArgMatches; +use environment::tracing_common; +use node_test_rig::{ + environment::{EnvironmentBuilder, LoggerConfig}, + eth2::types::Epoch, +}; +use tokio::time::sleep; +use tracing::info; +use types::{EthSpec, MainnetEthSpec}; + +use crate::{ + checks, + local_network::{SsvLocalNetwork, SsvNetworkParams}, + mock_websocket::MockServer, + SimConfig, +}; + +const END_EPOCH: u64 = 16; +const GENESIS_DELAY: u64 = 32; +const ACCEPTABLE_FALLBACK_ATTESTATION_HIT_PERCENTAGE: f64 = 95.0; +pub const TERMINAL_BLOCK: u64 = 0; +pub const ALTAIR_FORK_EPOCH: u64 = 0; +pub const BELLATRIX_FORK_EPOCH: u64 = 0; +pub const CAPELLA_FORK_EPOCH: u64 = 1; +pub const DENEB_FORK_EPOCH: u64 = 2; +pub const ELECTRA_FORK_EPOCH: u64 = 3; + +pub struct BasicSim {} + +impl BasicSim { + pub fn run(sim_config: SimConfig) -> Result<(), String> { + info!("Basic Simulator:"); + info!(" nodes: {}", sim_config.node_count); + info!(" proposer-nodes: {}", sim_config.proposer_nodes); + info!(" validators-per-node: {}", sim_config.validators_per_node); + info!(" speed-up-factor: {}", sim_config.speed_up_factor); + info!( + " continue-after-checks: {}", + sim_config.continue_after_checks + ); + + let (env_builder, ..) = tracing_common::construct_logger( + LoggerConfig { + path: None, + debug_level: tracing_common::parse_level(&sim_config.log_level.clone()), + logfile_debug_level: tracing_common::parse_level(&sim_config.log_level.clone()), + log_format: None, + logfile_format: None, + log_color: true, + logfile_color: true, + disable_log_timestamp: false, + max_log_size: 0, + max_log_number: 0, + compression: false, + is_restricted: true, + sse_logging: false, + extra_info: false, + }, + &ArgMatches::default(), + EnvironmentBuilder::mainnet(), + ); + + let mut env = env_builder.multi_threaded_tokio_runtime()?.build()?; + let mut spec = (*env.eth2_config.spec).clone(); + let total_validator_count = sim_config.validators_per_node * sim_config.node_count; + let genesis_delay = GENESIS_DELAY; + spec.seconds_per_slot /= sim_config.speed_up_factor; + spec.seconds_per_slot = max(1, spec.seconds_per_slot); + spec.genesis_delay = genesis_delay; + spec.min_genesis_time = 0; + spec.min_genesis_active_validator_count = total_validator_count as u64; + spec.altair_fork_epoch = Some(Epoch::new(ALTAIR_FORK_EPOCH)); + spec.bellatrix_fork_epoch = Some(Epoch::new(BELLATRIX_FORK_EPOCH)); + spec.capella_fork_epoch = Some(Epoch::new(CAPELLA_FORK_EPOCH)); + spec.deneb_fork_epoch = Some(Epoch::new(DENEB_FORK_EPOCH)); + spec.electra_fork_epoch = Some(Epoch::new(ELECTRA_FORK_EPOCH)); + + let spec = Arc::new(spec); + env.eth2_config.spec = spec.clone(); + + let slot_duration = Duration::from_secs(spec.seconds_per_slot); + let slots_per_epoch = MainnetEthSpec::slots_per_epoch(); + + // Start the mock server + let server = env + .runtime() + .block_on(async { MockServer::start().await })?; + + info!("Mock server available at: {}", server.url); + + // Setup a future that will perform all simulation checks on the network + let main_future = async { + // Create the local_network + let (network, beacon_config, execution_config, anchor_config) = + Box::pin(SsvLocalNetwork::create_local_network( + SsvNetworkParams { + num_validators: sim_config.validators_per_node * sim_config.node_count, + num_nodes: sim_config.node_count, + num_proposers: sim_config.proposer_nodes, + genesis_delay: GENESIS_DELAY, + }, + env.core_context(), + )) + .await?; + + // Add beacon + execution node to the network + for _ in 0..sim_config.node_count { + network + .add_beacon_node(beacon_config.clone(), execution_config.clone(), false) + .await?; + } + + // Add operator nodes to the network + for index in 0..(sim_config.committee_size) { + network + .add_anchor_node( + index, + anchor_config.clone(), + server.url.clone(), + spec.clone(), + ) + .await?; + } + + // Set all payloads as valid. This effectively assumes the EL is infalliable. + network.execution_nodes.write().iter().for_each(|node| { + node.server.all_payloads_valid(); + }); + + // Sleep until we hit genesis + let duration_to_genesis = network.duration_to_genesis().await?; + info!("Duration to genesis: {}", duration_to_genesis.as_secs()); + sleep(duration_to_genesis).await; + + // Run all checks and verify their success + checks::verify_first_finalization(&network, slot_duration).await?; + checks::verify_transition_block_finalized( + &network, + Epoch::new(TERMINAL_BLOCK / slots_per_epoch), + slot_duration, + true, + ) + .await?; + checks::verify_full_block_production_up_to( + &network, + Epoch::new(END_EPOCH).start_slot(slots_per_epoch), + slot_duration, + ) + .await?; + checks::verify_full_sync_aggregates_up_to( + &network, + // Start checking for sync_aggregates at `FORK_EPOCH + 1` to account for + // inefficiencies in finding subnet peers at the `fork_slot`. + Epoch::new(ALTAIR_FORK_EPOCH + 1).start_slot(slots_per_epoch), + Epoch::new(END_EPOCH).start_slot(slots_per_epoch), + slot_duration, + ) + .await?; + checks::check_attestation_correctness( + &network, + 0, + END_EPOCH, + slot_duration, + 1, + ACCEPTABLE_FALLBACK_ATTESTATION_HIT_PERCENTAGE, + ) + .await?; + + if sim_config.continue_after_checks { + futures::future::pending::<()>().await; + } + info!("All tests passed"); + + drop(network); + Ok::<(), String>(()) + }; + + env.runtime().block_on(main_future).unwrap(); + env.fire_signal(); + env.shutdown_on_idle(); + + Ok(()) + } +} diff --git a/anchor/integration/src/checks.rs b/anchor/integration/src/checks.rs new file mode 100644 index 000000000..ead2a4fb1 --- /dev/null +++ b/anchor/integration/src/checks.rs @@ -0,0 +1,238 @@ +// All checks to run on the simulation to ensure that is +// operating in an expected manner +use std::time::Duration; + +use node_test_rig::eth2::types::{BlockId, StateId}; +use types::{Epoch, EthSpec, ExecPayload, ExecutionBlockHash, Slot}; + +use crate::local_network::SsvLocalNetwork; + +// Checks that the chain has made the first possible finalization. +// +// Intended to be run as soon as chain starts. +pub async fn verify_first_finalization( + network: &SsvLocalNetwork, + slot_duration: Duration, +) -> Result<(), String> { + epoch_delay(Epoch::new(4), slot_duration, E::slots_per_epoch()).await; + verify_all_finalized_at(network, Epoch::new(2)).await?; + Ok(()) +} + +// Delays for `epochs`, plus half a slot extra. +pub async fn epoch_delay(epochs: Epoch, slot_duration: Duration, slots_per_epoch: u64) { + let duration = slot_duration * (epochs.as_u64() * slots_per_epoch) as u32 + slot_duration / 2; + tokio::time::sleep(duration).await +} + +// Delays for `slots`, plus half a slot extra. +async fn slot_delay(slots: Slot, slot_duration: Duration) { + let duration = slot_duration * slots.as_u64() as u32 + slot_duration / 2; + tokio::time::sleep(duration).await; +} + +// Verifies that all beacon nodes in the given network have a head state that has a finalized +// epoch of `epoch`. +pub async fn verify_all_finalized_at( + network: &SsvLocalNetwork, + epoch: Epoch, +) -> Result<(), String> { + let epochs = { + let mut epochs = Vec::new(); + for remote_node in network.remote_nodes()? { + epochs.push( + remote_node + .get_beacon_states_finality_checkpoints(StateId::Head) + .await + .map(|body| body.unwrap().data.finalized.epoch) + .map_err(|e| format!("Get head via http failed: {:?}", e))?, + ); + } + epochs + }; + + if epochs.iter().any(|node_epoch| *node_epoch != epoch) { + Err(format!( + "Nodes are not finalized at epoch {}. Finalized epochs: {:?}", + epoch, epochs + )) + } else { + Ok(()) + } +} + +// Verifies that there's been a block produced at every slot up to and including `slot`. +pub async fn verify_full_block_production_up_to( + network: &SsvLocalNetwork, + slot: Slot, + slot_duration: Duration, +) -> Result<(), String> { + slot_delay(slot, slot_duration).await; + let beacon_nodes = network.beacon_nodes.read(); + let beacon_chain = beacon_nodes[0].client.beacon_chain().unwrap(); + let num_blocks = beacon_chain + .chain_dump() + .unwrap() + .iter() + .take_while(|s| s.beacon_block.slot() <= slot) + .count(); + if num_blocks != slot.as_usize() + 1 { + return Err(format!( + "There wasn't a block produced at every slot, got: {}, expected: {}", + num_blocks, + slot.as_usize() + 1 + )); + } + Ok(()) +} + +// Verify that all sync aggregates from `sync_committee_start_slot` until `upto_slot` +// have full aggregates. +pub async fn verify_full_sync_aggregates_up_to( + network: &SsvLocalNetwork, + sync_committee_start_slot: Slot, + upto_slot: Slot, + slot_duration: Duration, +) -> Result<(), String> { + slot_delay(upto_slot, slot_duration).await; + let remote_nodes = network.remote_nodes()?; + let remote_node = remote_nodes.first().unwrap(); + + for slot in sync_committee_start_slot.as_u64()..=upto_slot.as_u64() { + let sync_aggregate_count = remote_node + .get_beacon_blocks::(BlockId::Slot(Slot::new(slot))) + .await + .map(|resp| { + resp.unwrap() + .data + .message() + .body() + .sync_aggregate() + .map(|agg| agg.num_set_bits()) + }) + .map_err(|e| format!("Error while getting beacon block: {:?}", e))? + .map_err(|_| format!("Altair block {} should have sync aggregate", slot))?; + + if sync_aggregate_count != E::sync_committee_size() { + return Err(format!( + "Sync aggregate at slot {} was not full, got: {}, expected: {}", + slot, + sync_aggregate_count, + E::sync_committee_size() + )); + } + } + + Ok(()) +} + +// Verify that the first merged PoS block got finalized. +pub async fn verify_transition_block_finalized( + network: &SsvLocalNetwork, + transition_epoch: Epoch, + slot_duration: Duration, + should_verify: bool, +) -> Result<(), String> { + if !should_verify { + return Ok(()); + } + epoch_delay(transition_epoch + 2, slot_duration, E::slots_per_epoch()).await; + let mut block_hashes = Vec::new(); + for remote_node in network.remote_nodes()?.iter() { + let execution_block_hash: ExecutionBlockHash = remote_node + .get_beacon_blocks::(BlockId::Finalized) + .await + .map(|body| body.unwrap().data) + .map_err(|e| format!("Get state root via http failed: {:?}", e))? + .message() + .execution_payload() + .map(|payload| payload.block_hash()) + .map_err(|e| format!("Execution payload does not exist: {:?}", e))?; + block_hashes.push(execution_block_hash); + } + + let first = block_hashes[0]; + if block_hashes.iter().all(|&item| item == first) { + Ok(()) + } else { + Err(format!( + "Terminal block not finalized on all nodes Finalized block hashes:{:?}", + block_hashes + )) + } +} + +// Ensure all validators have attested correctly. +pub async fn check_attestation_correctness( + network: &SsvLocalNetwork, + start_epoch: u64, + upto_epoch: u64, + slot_duration: Duration, + // Select which node to query. Will use this node to determine the global network performance. + node_index: usize, + acceptable_attestation_performance: f64, +) -> Result<(), String> { + epoch_delay(Epoch::new(upto_epoch), slot_duration, E::slots_per_epoch()).await; + + let remote_node = &network.remote_nodes()?[node_index]; + + let results = remote_node + .get_lighthouse_analysis_attestation_performance( + Epoch::new(start_epoch), + Epoch::new(upto_epoch - 2), + "global".to_string(), + ) + .await + .map_err(|e| format!("Unable to get attestation performance: {e}"))?; + + let mut active_successes: f64 = 0.0; + let mut head_successes: f64 = 0.0; + let mut target_successes: f64 = 0.0; + let mut source_successes: f64 = 0.0; + + let mut total: f64 = 0.0; + + for result in results { + for epochs in result.epochs.values() { + total += 1.0; + + if epochs.active { + active_successes += 1.0; + } + if epochs.head { + head_successes += 1.0; + } + if epochs.target { + target_successes += 1.0; + } + if epochs.source { + source_successes += 1.0; + } + } + } + let active_percent = active_successes / total * 100.0; + let head_percent = head_successes / total * 100.0; + let target_percent = target_successes / total * 100.0; + let source_percent = source_successes / total * 100.0; + + eprintln!("Total Attestations: {}", total); + eprintln!("Active: {}: {}%", active_successes, active_percent); + eprintln!("Head: {}: {}%", head_successes, head_percent); + eprintln!("Target: {}: {}%", target_successes, target_percent); + eprintln!("Source: {}: {}%", source_successes, source_percent); + + if active_percent < acceptable_attestation_performance { + return Err("Active percent was below required level".to_string()); + } + if head_percent < acceptable_attestation_performance { + return Err("Head percent was below required level".to_string()); + } + if target_percent < acceptable_attestation_performance { + return Err("Target percent was below required level".to_string()); + } + if source_percent < acceptable_attestation_performance { + return Err("Source percent was below required level".to_string()); + } + + Ok(()) +} diff --git a/anchor/integration/src/cli.rs b/anchor/integration/src/cli.rs new file mode 100644 index 000000000..c8c6a0c1b --- /dev/null +++ b/anchor/integration/src/cli.rs @@ -0,0 +1,113 @@ +use clap::{crate_version, Parser, Subcommand}; + +#[derive(Parser)] +#[command(name = "simulator")] +#[command(version = crate_version!())] +#[command(author = "Sigma Prime ")] +#[command(about = "Options for interacting with simulator")] +pub struct Cli { + #[command(subcommand)] + pub command: Commands, +} + +#[derive(Subcommand)] +pub enum Commands { + #[command(about = "Runs a ssv validator simulation")] + BasicSim { + #[arg( + short = 'n', + long = "nodes", + default_value = "4", + help = "Number of beacon nodes" + )] + nodes: String, + + #[arg( + short = 'p', + long = "proposer-nodes", + default_value = "4", + help = "Number of proposer-only beacon nodes" + )] + proposer_nodes: String, + + #[arg( + short = 'v', + long = "validators-per-node", + default_value = "256", + help = "Number of validators" + )] + validators_per_node: String, + + #[arg( + short = 's', + long = "speed-up-factor", + default_value = "3", + help = "Speed up factor. Please use a divisor of 12." + )] + speed_up_factor: String, + + #[arg( + short = 'd', + long = "debug-level", + default_value = "debug", + help = "Set the severity level of the logs." + )] + debug_level: String, + + #[arg( + short = 'c', + long = "continue_after_checks", + help = "Continue after checks (default false)" + )] + continue_after_checks: bool, + }, +} + +pub struct SimConfig { + pub node_count: usize, + pub proposer_nodes: usize, + pub validators_per_node: usize, + pub speed_up_factor: u64, + pub log_level: String, + pub committee_size: usize, + pub continue_after_checks: bool, +} + +impl From<&Commands> for SimConfig { + fn from(command: &Commands) -> Self { + match command { + Commands::BasicSim { + nodes, + proposer_nodes, + validators_per_node, + speed_up_factor, + debug_level, + continue_after_checks, + } => { + let node_count = nodes.parse::().expect("Failed to parse nodes"); + + let proposer_node_count = proposer_nodes + .parse::() + .expect("Failed to parse proposer-nodes"); + + let validators = validators_per_node + .parse::() + .expect("Failed to parse validators-per-node"); + + let speed = speed_up_factor + .parse::() + .expect("Failed to parse speed-up-factor"); + + SimConfig { + node_count, + proposer_nodes: proposer_node_count, + validators_per_node: validators, + speed_up_factor: speed, + log_level: debug_level.clone(), + committee_size: 4, + continue_after_checks: *continue_after_checks, + } + } + } + } +} diff --git a/anchor/integration/src/local_anchor_node.rs b/anchor/integration/src/local_anchor_node.rs new file mode 100644 index 000000000..c656ed2c7 --- /dev/null +++ b/anchor/integration/src/local_anchor_node.rs @@ -0,0 +1,97 @@ +use std::{net::Ipv4Addr, path::PathBuf, sync::Arc}; + +use client::{config::Config, Client}; +use lighthouse_network::{ListenAddr, ListenAddress}; +use network::{ + load_enr_from_disk, Enr, DEFAULT_DISC_PORT, DEFAULT_IPV4_ADDRESS, DEFAULT_QUIC_PORT, + DEFAULT_TCP_PORT, +}; +use task_executor::TaskExecutor; +use tracing::{info, warn}; +use types::{ChainSpec, EthSpec}; + +pub struct LocalAnchorNode { + pub config: Config, +} + +impl LocalAnchorNode { + // Create a new local anchor node + pub fn new(index: u16, mut anchor_config: Config) -> Self { + // Access pre-populated database for the operator + // The data dir for each operator is stored in mock-data/operator-{index} + let data_path = PathBuf::from("anchor/integration/mock-data"); + let data_dir = format!("operator-{}", index); + anchor_config.data_dir = data_path.join(data_dir); + + // Make sure to cleanup previously slashing databases. We dont care about the return value + // as it is a static location and it either exists and will be removed, or does not exist + // and nothing will hapenn + let _ = std::fs::remove_file(anchor_config.data_dir.join("slashing_protection.sqlite")); + let _ = std::fs::remove_file( + anchor_config + .data_dir + .join("slashing_protection.sqlite-journal"), + ); + + // Setup the network dir + anchor_config.network.network_dir = anchor_config.data_dir.join("network"); + + // Configure ports + // subtract index to prevent collision with quic port + // index == 0 defines boot node + let libp2p_tcp_port = DEFAULT_TCP_PORT - index; + let discv5_port = DEFAULT_DISC_PORT - index; + + anchor_config.network.listen_addresses = ListenAddress::V4(ListenAddr { + addr: DEFAULT_IPV4_ADDRESS, + disc_port: discv5_port, + quic_port: DEFAULT_QUIC_PORT + index, + tcp_port: libp2p_tcp_port, + }); + + anchor_config.network.enr_udp4_port = Some(discv5_port.try_into().unwrap()); + anchor_config.network.enr_tcp4_port = Some(libp2p_tcp_port.try_into().unwrap()); + anchor_config.network.enr_address = (Some(Ipv4Addr::LOCALHOST), None); + anchor_config.network.disable_quic_support = true; + + Self { + config: anchor_config, + } + } + + // Enr is saved to disk, fetch it + pub fn get_enr(&self) -> Enr { + loop { + if let Some(enr) = load_enr_from_disk(&self.config.network.network_dir) { + return enr; + } + } + } + + // Run the anchor node with the given executor + pub fn run( + &mut self, + executor: TaskExecutor, + spec: Arc, + ) -> Result<(), String> { + // Clone necessary data for the async task + let config = self.config.clone(); + + let executor_clone = executor.clone(); + executor.spawn( + async move { + match Client::run::(executor_clone, config, Some((*spec).clone())).await { + Ok(_) => { + info!("Anchor node completed successfully"); + } + Err(e) => { + warn!("Anchor node failed: {}", e); + } + } + }, + "anchor node", + ); + + Ok(()) + } +} diff --git a/anchor/integration/src/local_network.rs b/anchor/integration/src/local_network.rs new file mode 100644 index 000000000..9ba63b4cd --- /dev/null +++ b/anchor/integration/src/local_network.rs @@ -0,0 +1,317 @@ +use std::{ + ops::Deref, + sync::Arc, + time::{Duration, SystemTime, UNIX_EPOCH}, +}; + +use client::config::Config as AnchorConfig; +use node_test_rig::{ + environment::RuntimeContext, + eth2::{ + types::{ChainSpec, EthSpec}, + BeaconNodeHttpClient, SensitiveUrl as Eth2SensitiveUrl, + }, + ClientConfig, LocalBeaconNode, LocalExecutionNode, MockExecutionConfig, +}; +use parking_lot::RwLock; +use sensitive_url::SensitiveUrl; + +use crate::{ + local_anchor_node::LocalAnchorNode, + util::{default_anchor_config, default_client_config, default_mock_execution_config}, +}; + +const BOOTNODE_PORT: u16 = 42424; +const QUIC_PORT: u16 = 43424; +pub const EXECUTION_PORT: u16 = 4000; + +// Contains all nodes in the simulated network +pub struct SsvLocalNetwork { + pub inner: Arc>, +} + +impl Clone for SsvLocalNetwork { + fn clone(&self) -> Self { + Self { + inner: self.inner.clone(), + } + } +} + +impl Deref for SsvLocalNetwork { + type Target = Inner; + + fn deref(&self) -> &Self::Target { + self.inner.deref() + } +} + +pub struct Inner { + pub context: RuntimeContext, + pub beacon_nodes: RwLock>>, + pub proposer_nodes: RwLock>>, + pub execution_nodes: RwLock>>, + pub anchor_nodes: RwLock>, +} + +pub struct SsvNetworkParams { + pub num_validators: usize, + pub num_nodes: usize, + pub num_proposers: usize, + pub genesis_delay: u64, +} + +impl SsvLocalNetwork { + pub async fn create_local_network( + network_params: SsvNetworkParams, + context: RuntimeContext, + ) -> Result< + ( + SsvLocalNetwork, + ClientConfig, + MockExecutionConfig, + AnchorConfig, + ), + String, + > { + let genesis_time: u64 = (SystemTime::now() + .duration_since(UNIX_EPOCH) + .map_err(|_| "should get system time")? + + Duration::from_secs(network_params.genesis_delay)) + .as_secs(); + + // Create all of the default configs + let anchor_config = default_anchor_config(); + let beacon_config = default_client_config(network_params, genesis_time); + let execution_config = + default_mock_execution_config::(&context.eth2_config().spec, genesis_time); + + let network = Self { + // Initially empty network + inner: Arc::new(Inner { + context, + beacon_nodes: RwLock::new(Vec::new()), + proposer_nodes: RwLock::new(Vec::new()), + execution_nodes: RwLock::new(Vec::new()), + anchor_nodes: RwLock::new(Vec::new()), + }), + }; + + Ok((network, beacon_config, execution_config, anchor_config)) + } + + pub async fn add_anchor_node( + &self, + index: usize, + mut anchor_config: AnchorConfig, + server_url: String, + spec: Arc, + ) -> Result<(), String> { + { + // Add ENR of bootnode + let read_lock = self.anchor_nodes.read(); + let boot_node = read_lock.first(); + + if let Some(boot_node) = boot_node { + let enr = boot_node.get_enr(); + anchor_config.network.boot_nodes_enr.push(enr) + } + } + + // Add a beacon node endpoint + let beacon_node = { + let read_lock = self.beacon_nodes.read(); + let beacon_node = read_lock + .get(index) + .ok_or_else(|| format!("No beacon node for index {}", index))?; + let beacon_node = beacon_node + .client + .http_api_listen_addr() + .expect("Must have http started"); + SensitiveUrl::parse( + format!("http://{}:{}", beacon_node.ip(), beacon_node.port()).as_str(), + ) + .unwrap() + }; + anchor_config.beacon_nodes = vec![beacon_node]; + + // Add execution node endpoints + anchor_config.execution_nodes = vec![]; + let execution_addr = + SensitiveUrl::parse(&format!("http://localhost:{}", EXECUTION_PORT)).unwrap(); + anchor_config.execution_nodes.push(execution_addr); + anchor_config.execution_nodes_websocket = vec![SensitiveUrl::parse(&server_url).unwrap()]; + + // Construct and run a new local anchor node + let mut anchor_node = LocalAnchorNode::new(index as u16, anchor_config); + anchor_node.run::(self.context.executor.clone(), spec)?; + + // Add node to the network + self.anchor_nodes.write().push(anchor_node); + + Ok(()) + } + + // Add a new beacon node to the local network + pub async fn add_beacon_node( + &self, + mut beacon_config: ClientConfig, + execution_config: MockExecutionConfig, + is_proposer: bool, + ) -> Result<(), String> { + let first_bn_exists: bool; + { + // Add ENR of the bootnode if it exists + let read_lock = self.beacon_nodes.read(); + let boot_node = read_lock.first(); + first_bn_exists = boot_node.is_some(); + if let Some(boot_node) = boot_node { + // Modify beacon_config to add boot node details. + beacon_config.network.boot_nodes_enr.push( + boot_node + .client + .enr() + .expect("Bootnode must have a network."), + ); + } + } + let (beacon_node, execution_node) = if first_bn_exists { + // Network already exists. We construct a new node. + self.construct_beacon_node(beacon_config, execution_config, is_proposer) + .await? + } else { + // Network does not exist. We construct a boot node. + self.construct_boot_node(beacon_config, execution_config) + .await? + }; + + // Add nodes to the network. + self.execution_nodes.write().push(execution_node); + if is_proposer { + self.proposer_nodes.write().push(beacon_node); + } else { + self.beacon_nodes.write().push(beacon_node); + } + Ok(()) + } + + async fn construct_boot_node( + &self, + mut beacon_config: ClientConfig, + mock_execution_config: MockExecutionConfig, + ) -> Result<(LocalBeaconNode, LocalExecutionNode), String> { + beacon_config.network.set_ipv4_listening_address( + std::net::Ipv4Addr::UNSPECIFIED, + BOOTNODE_PORT, + BOOTNODE_PORT, + QUIC_PORT, + ); + + beacon_config.network.enr_udp4_port = Some(BOOTNODE_PORT.try_into().expect("non zero")); + beacon_config.network.enr_tcp4_port = Some(BOOTNODE_PORT.try_into().expect("non zero")); + beacon_config.network.discv5_config.table_filter = |_| true; + + let execution_node = LocalExecutionNode::new( + self.context.service_context("boot_node_el".into()), + mock_execution_config, + ); + + beacon_config.execution_layer = Some(execution_layer::Config { + execution_endpoint: Some( + Eth2SensitiveUrl::parse(&execution_node.server.url()).unwrap(), + ), + default_datadir: execution_node.datadir.path().to_path_buf(), + secret_file: Some(execution_node.datadir.path().join("jwt.hex")), + ..Default::default() + }); + + let beacon_node = LocalBeaconNode::production( + self.context.service_context("boot_node".into()), + beacon_config, + ) + .await?; + + Ok((beacon_node, execution_node)) + } + + async fn construct_beacon_node( + &self, + mut beacon_config: ClientConfig, + mut mock_execution_config: MockExecutionConfig, + is_proposer: bool, + ) -> Result<(LocalBeaconNode, LocalExecutionNode), String> { + let beacon_node_count = self.beacon_nodes.read().len(); + let proposer_node_count = self.proposer_nodes.read().len(); + let count = (beacon_node_count + proposer_node_count) as u16; + + // Set config. + let libp2p_tcp_port = BOOTNODE_PORT + count; + let discv5_port = BOOTNODE_PORT + count; + beacon_config.network.set_ipv4_listening_address( + std::net::Ipv4Addr::UNSPECIFIED, + libp2p_tcp_port, + discv5_port, + QUIC_PORT + count, + ); + beacon_config.network.enr_udp4_port = Some(discv5_port.try_into().unwrap()); + beacon_config.network.enr_tcp4_port = Some(libp2p_tcp_port.try_into().unwrap()); + beacon_config.network.discv5_config.table_filter = |_| true; + beacon_config.network.proposer_only = is_proposer; + + mock_execution_config.server_config.listen_port = EXECUTION_PORT + count; + + // Construct execution node. + let execution_node = LocalExecutionNode::new( + self.context.service_context(format!("node_{}_el", count)), + mock_execution_config, + ); + + // Pair the beacon node and execution node. + beacon_config.execution_layer = Some(execution_layer::Config { + execution_endpoint: Some( + Eth2SensitiveUrl::parse(&execution_node.server.url()).unwrap(), + ), + default_datadir: execution_node.datadir.path().to_path_buf(), + secret_file: Some(execution_node.datadir.path().join("jwt.hex")), + ..Default::default() + }); + + // Construct beacon node using the config, + let beacon_node = LocalBeaconNode::production( + self.context.service_context(format!("node_{}", count)), + beacon_config, + ) + .await?; + + Ok((beacon_node, execution_node)) + } + + pub fn remote_nodes(&self) -> Result, String> { + let beacon_nodes = self.beacon_nodes.read(); + let proposer_nodes = self.proposer_nodes.read(); + + beacon_nodes + .iter() + .chain(proposer_nodes.iter()) + .map(|beacon_node| beacon_node.remote_node()) + .collect() + } + + pub async fn duration_to_genesis(&self) -> Result { + let nodes = self.remote_nodes().expect("Failed to get remote nodes"); + let bootnode = nodes.first().expect("Should contain bootnode"); + let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap(); + let genesis_time = Duration::from_secs( + bootnode + .get_beacon_genesis() + .await + .unwrap() + .data + .genesis_time, + ); + genesis_time.checked_sub(now).ok_or( + "The genesis time has already passed since all nodes started. The node startup time \ + may have regressed, and the current `GENESIS_DELAY` is no longer sufficient.", + ) + } +} diff --git a/anchor/integration/src/main.rs b/anchor/integration/src/main.rs new file mode 100644 index 000000000..59c661b1b --- /dev/null +++ b/anchor/integration/src/main.rs @@ -0,0 +1,31 @@ +use clap::Parser; + +use crate::{ + basic_sim::BasicSim, + cli::{Cli, Commands, SimConfig}, + util::setup_logging, +}; + +mod basic_sim; +mod checks; +mod cli; +mod local_anchor_node; +mod local_network; +mod mock_websocket; +mod util; + +fn main() -> Result<(), String> { + setup_logging(); + + // Parse cli config and get simulation config + let cli = Cli::parse(); + let config = SimConfig::from(&cli.command); + + match cli.command { + Commands::BasicSim { .. } => { + BasicSim::run(config)?; + } + } + + Ok(()) +} diff --git a/anchor/integration/src/mock_websocket.rs b/anchor/integration/src/mock_websocket.rs new file mode 100644 index 000000000..0e28de7c7 --- /dev/null +++ b/anchor/integration/src/mock_websocket.rs @@ -0,0 +1,58 @@ +use std::net::SocketAddr; + +use axum::{ + extract::ws::{WebSocket, WebSocketUpgrade}, + response::IntoResponse, + routing::get, + Router, +}; +use tracing::info; + +// To be able to run successfully, the anchor nodes need to bind to a websocket. This is typically +// used for live sycning blocks, but this is not needed in the simulator. This is a mock +// server that acts as a dummy endpoint for the nodes to bind to. +pub struct MockServer { + pub url: String, + _server_handle: tokio::task::JoinHandle<()>, +} + +impl MockServer { + pub async fn start() -> Result { + // Create a simple WebSocket handler function + async fn handle_socket(ws: WebSocketUpgrade) -> impl IntoResponse { + ws.on_upgrade(|_socket: WebSocket| async { + // Connection established, but we don't need to do anything with it + }) + } + + // Set up the router with our WebSocket handler + let app = Router::new().route("/", get(handle_socket)); + + // Find an available port by binding to port 0 + let socket: SocketAddr = ([127, 0, 0, 1], 0).into(); + let listener = tokio::net::TcpListener::bind(socket) + .await + .map_err(|e| format!("Failed to bind to socket: {}", e))?; + + // Get the actual bound address + let addr = listener + .local_addr() + .map_err(|e| format!("Failed to get local address: {}", e))?; + + let url = format!("ws://localhost:{}", addr.port()); + info!("Mock server started at {}", url); + + // Spawn the server in the background with a shutdown signal that never completes + let server = axum::serve(listener, app); + let handle = tokio::spawn(async move { + server.await.unwrap_or_else(|e| { + tracing::error!("Server error: {}", e); + }); + }); + + Ok(Self { + url, + _server_handle: handle, + }) + } +} diff --git a/anchor/integration/src/util.rs b/anchor/integration/src/util.rs new file mode 100644 index 000000000..8f4958726 --- /dev/null +++ b/anchor/integration/src/util.rs @@ -0,0 +1,116 @@ +use std::net::Ipv4Addr; + +use clap::Parser; +use client::{config::Config, Node}; +use kzg::trusted_setup::get_trusted_setup; +use node_test_rig::{ + eth2::{ + types::{ChainSpec, EthSpec}, + SensitiveUrl, + }, + testing_client_config, ClientConfig, ClientGenesis, MockExecutionConfig, MockServerConfig, +}; +use ssv_network_config::SsvNetworkConfig; +use tracing_subscriber::{filter::filter_fn, fmt, prelude::*, EnvFilter}; + +use crate::local_network::{SsvNetworkParams, EXECUTION_PORT}; + +// Create a default execution node config +pub fn default_mock_execution_config( + spec: &ChainSpec, + genesis_time: u64, +) -> MockExecutionConfig { + let mut mock_execution_config = MockExecutionConfig { + server_config: MockServerConfig { + listen_port: EXECUTION_PORT, + ..Default::default() + }, + ..Default::default() + }; + + if let Some(capella_fork_epoch) = spec.capella_fork_epoch { + mock_execution_config.shanghai_time = Some( + genesis_time + + spec.seconds_per_slot * E::slots_per_epoch() * capella_fork_epoch.as_u64(), + ) + } + if let Some(deneb_fork_epoch) = spec.deneb_fork_epoch { + mock_execution_config.cancun_time = Some( + genesis_time + spec.seconds_per_slot * E::slots_per_epoch() * deneb_fork_epoch.as_u64(), + ) + } + if let Some(electra_fork_epoch) = spec.electra_fork_epoch { + mock_execution_config.prague_time = Some( + genesis_time + + spec.seconds_per_slot * E::slots_per_epoch() * electra_fork_epoch.as_u64(), + ) + } + + mock_execution_config +} + +// Create a default beacon node config +pub fn default_client_config(network_params: SsvNetworkParams, genesis_time: u64) -> ClientConfig { + let mut beacon_config = testing_client_config(); + + beacon_config.genesis = ClientGenesis::InteropMerge { + validator_count: network_params.num_validators, // genesis state w/ num_validators + genesis_time, + }; + beacon_config.network.target_peers = network_params.num_nodes + network_params.num_proposers; + beacon_config.network.enr_address = (Some(Ipv4Addr::LOCALHOST), None); + beacon_config.network.enable_light_client_server = true; + beacon_config.network.discv5_config.enable_packet_filter = false; + beacon_config.chain.enable_light_client_server = true; + beacon_config.chain.optimistic_finalized_sync = false; + beacon_config.trusted_setup = serde_json::from_reader(get_trusted_setup().as_slice()) + .expect("Trusted setup bytes should be valid"); + + let el_config = execution_layer::Config { + execution_endpoint: Some( + SensitiveUrl::parse(&format!("http://localhost:{}", EXECUTION_PORT)).unwrap(), + ), + ..Default::default() + }; + beacon_config.execution_layer = Some(el_config); + beacon_config +} + +// Create a default anchor operator configuration +pub fn default_anchor_config() -> Config { + let node = Node::parse_from::, String>(vec![]); + + let mut anchor_config = client::config::from_cli(&node).unwrap(); + anchor_config.ssv_network = SsvNetworkConfig::constant("mainnet").unwrap().unwrap(); + anchor_config.skip_sync = true; + + anchor_config +} + +// Sets up logging configuration +pub fn setup_logging() { + if std::env::var("RUST_LOG").is_err() { + std::env::set_var( + "RUST_LOG", + "integration=debug,execution=debug,client=debug,beacon_node_fallback=debug,anchor=debug,network=debug,qbft=debug", + ); + } + let env_filter = EnvFilter::from_env("RUST_LOG"); + + let dep_log_filter = filter_fn(|metadata| { + if let Some(file) = metadata.file() { + !file.contains("/.cargo/") + } else { + true + } + }); + + if let Err(e) = tracing_subscriber::registry() + .with(env_filter) + .with(dep_log_filter) + .with(fmt::layer()) + .try_init() + { + eprintln!("Failed to initialize logging: {e}"); + } +} diff --git a/anchor/network/src/lib.rs b/anchor/network/src/lib.rs index 018be65fe..c0c31b382 100644 --- a/anchor/network/src/lib.rs +++ b/anchor/network/src/lib.rs @@ -8,7 +8,10 @@ mod keypair_utils; mod network; mod peer_manager; mod transport; -pub use config::Config; +pub use config::{ + Config, DEFAULT_DISC_PORT, DEFAULT_IPV4_ADDRESS, DEFAULT_QUIC_PORT, DEFAULT_TCP_PORT, +}; +pub use discovery::load_enr_from_disk; pub use lighthouse_network::{ListenAddr, ListenAddress}; pub use network::Network; diff --git a/anchor/src/main.rs b/anchor/src/main.rs index b4e9caa7f..e093b9f97 100644 --- a/anchor/src/main.rs +++ b/anchor/src/main.rs @@ -90,11 +90,11 @@ fn start_anchor(anchor_config: Node, mut environment: Environment) { async move { let result = match eth_spec_id { EthSpecId::Mainnet => { - Client::run::(anchor_executor, config).await + Client::run::(anchor_executor, config, None).await } #[cfg(feature = "spec-minimal")] EthSpecId::Minimal => { - Client::run::(anchor_executor, config).await + Client::run::(anchor_executor, config, None).await } other => Err(format!( "Eth spec `{other}` is not supported by this build of Anchor", diff --git a/anchor/subnet_tracker/Cargo.toml b/anchor/subnet_tracker/Cargo.toml index 26beb5192..adb119c61 100644 --- a/anchor/subnet_tracker/Cargo.toml +++ b/anchor/subnet_tracker/Cargo.toml @@ -7,7 +7,7 @@ authors = ["Sigma Prime "] [dependencies] alloy = { workspace = true } database = { workspace = true } -ethereum_serde_utils = "0.7.0" +ethereum_serde_utils = { workspace = true } serde = { workspace = true } ssv_types = { workspace = true } task_executor = { workspace = true } diff --git a/anchor/validator_store/src/lib.rs b/anchor/validator_store/src/lib.rs index b8ae2bba2..6844a9b33 100644 --- a/anchor/validator_store/src/lib.rs +++ b/anchor/validator_store/src/lib.rs @@ -140,8 +140,14 @@ impl AnchorValidatorStore { } async fn updater(self: Arc, mut database_state: watch::Receiver) { - while database_state.changed().await.is_ok() { + // Process initial state and then watch for changes + loop { self.load_validators(&database_state.borrow()); + + // Exit when the sender is dropped + if database_state.changed().await.is_err() { + break; + } } }