diff --git a/Cargo.lock b/Cargo.lock index 710b3a30d0a..6062de91383 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,7 +1,5 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 - [[package]] name = "account_manager" version = "0.3.5" @@ -12,7 +10,7 @@ dependencies = [ "clap_utils", "deposit_contract", "directory", - "dirs 3.0.1", + "dirs 3.0.2", "environment", "eth2", "eth2_keystore", @@ -21,19 +19,20 @@ dependencies = [ "eth2_ssz_derive", "eth2_wallet", "eth2_wallet_manager", - "futures 0.3.13", + "futures 0.3.14", "hex", "libc", "rand 0.7.3", "rayon", "safe_arith", + "sensitive_url", "slashing_protection", "slog", "slog-async", "slog-term", "slot_clock", "tempfile", - "tokio 1.2.0", + "tokio 1.5.0", "types", "validator_dir", ] @@ -197,9 +196,9 @@ checksum = "739f4a8db6605981345c5654f3a85b056ce52f37a39d34da03f25bf2151ea16e" [[package]] name = "aho-corasick" -version = "0.7.15" +version = "0.7.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5" +checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" dependencies = [ "memchr", ] @@ -229,9 +228,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.38" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afddf7f520a80dbf76e6f50a35bca42a2331ef227a28b3b6dc5c2e2338d114b1" +checksum = "28b2cd92db5cbd74e8e5028f7e27dd7aa3090e89e4f2a197cc7c8dfb69c7063b" [[package]] name = "arbitrary" @@ -290,11 +289,10 @@ dependencies = [ [[package]] name = "assert-json-diff" -version = "1.1.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4259cbe96513d2f1073027a259fc2ca917feb3026a5a8d984e3628e490255cc0" +checksum = "50f1c3703dd33532d7f0ca049168930e9099ecac238e23cf932f3a69c42f06da" dependencies = [ - "extend", "serde", "serde_json", ] @@ -312,16 +310,16 @@ dependencies = [ [[package]] name = "async-executor" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb877970c7b440ead138f6321a3b5395d6061183af779340b65e20c0fede9146" +checksum = "871f9bb5e0a22eeb7e8cf16641feb87c9dc67032ccf8ff49e772eb9941d3a965" dependencies = [ "async-task", "concurrent-queue", "fastrand", "futures-lite", "once_cell", - "vec-arena", + "slab", ] [[package]] @@ -342,29 +340,29 @@ dependencies = [ [[package]] name = "async-io" -version = "1.3.1" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9315f8f07556761c3e48fec2e6b276004acf426e6dc068b2c2251854d65ee0fd" +checksum = "4bbfd5cf2794b1e908ea8457e6c45f8f8f1f6ec5f74617bf4662623f47503c3b" dependencies = [ "concurrent-queue", "fastrand", "futures-lite", "libc", "log", - "nb-connect", "once_cell", "parking", "polling", - "vec-arena", + "slab", + "socket2 0.4.0", "waker-fn", "winapi 0.3.9", ] [[package]] name = "async-lock" -version = "2.3.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1996609732bde4a9988bc42125f55f2af5f3c36370e27c778d5191a4a1b63bfb" +checksum = "e6a8ea61bf9947a1007c5cada31e647dbc77b103c679858150003ba697ea798b" dependencies = [ "event-listener", ] @@ -401,15 +399,16 @@ dependencies = [ [[package]] name = "async-process" -version = "1.0.2" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef37b86e2fa961bae5a4d212708ea0154f904ce31d1a4a7f47e1bbc33a0c040b" +checksum = "a8f38756dd9ac84671c428afbf7c9f7495feff9ec5b0710f17100098e5b354ac" dependencies = [ "async-io", "blocking", "cfg-if 1.0.0", "event-listener", "futures-lite", + "libc", "once_cell", "signal-hook", "winapi 0.3.9", @@ -451,9 +450,9 @@ checksum = "e91831deabf0d6d7ec49552e489aed63b7456a7a3c46cff62adad428110b0af0" [[package]] name = "async-trait" -version = "0.1.48" +version = "0.1.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36ea56748e10732c49404c153638a15ec3d6211ec5ff35d9bb20e13b93576adf" +checksum = "0b98e84bbb4cbcdd97da190ba0c58a1bb0de2c1fdf67d159e192ed766aeca722" dependencies = [ "proc-macro2", "quote", @@ -524,14 +523,15 @@ checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" [[package]] name = "backtrace" -version = "0.3.56" +version = "0.3.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d117600f438b1707d4e4ae15d3595657288f8235a0eb593e80ecc98ab34e1bc" +checksum = "88fb5a785d6b44fd9d6700935608639af1b8356de1e55d5f7c2740f4faa15d82" dependencies = [ "addr2line", + "cc", "cfg-if 1.0.0", "libc", - "miniz_oxide 0.4.4", + "miniz_oxide", "object", "rustc-demangle", ] @@ -588,7 +588,7 @@ dependencies = [ "eth2_ssz_types", "exit-future", "fork_choice", - "futures 0.3.13", + "futures 0.3.14", "genesis", "int_to_bytes", "integer-sqrt", @@ -621,7 +621,7 @@ dependencies = [ "strum", "task_executor", "tempfile", - "tokio 1.2.0", + "tokio 1.5.0", "tree_hash", "types", ] @@ -636,21 +636,22 @@ dependencies = [ "client", "ctrlc", "directory", - "dirs 3.0.1", + "dirs 3.0.2", "environment", "eth2_config", "eth2_libp2p", "eth2_network_config", "eth2_ssz", "exit-future", - "futures 0.3.13", + "futures 0.3.14", "genesis", "hex", - "hyper 0.14.4", + "hyper 0.14.7", "lighthouse_version", "logging", "node_test_rig", "rand 0.7.3", + "sensitive_url", "serde", "slasher", "slog", @@ -658,17 +659,16 @@ dependencies = [ "slog-term", "store", "task_executor", - "tokio 1.2.0", + "tokio 1.5.0", "types", ] [[package]] name = "bincode" -version = "1.3.2" +version = "1.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d175dfa69e619905c4c3cdb7c3c203fa3bdd5d51184e3afdb2742c0280493772" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" dependencies = [ - "byteorder", "serde", ] @@ -829,9 +829,9 @@ dependencies = [ [[package]] name = "blst" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd7cb1b48c09ac759808ad27811ca44e27c037d309f837651fc80506bc19819f" +checksum = "04dcd2da2e8ff774aaa0c6ac76d0fecd9d98cb5767682c101895c4858e05b833" dependencies = [ "cc", "glob", @@ -848,7 +848,7 @@ dependencies = [ "eth2_libp2p", "eth2_network_config", "eth2_ssz", - "futures 0.3.13", + "futures 0.3.14", "hex", "log", "logging", @@ -858,7 +858,7 @@ dependencies = [ "slog-stdlog", "slog-term", "sloggers", - "tokio 1.2.0", + "tokio 1.5.0", "types", ] @@ -876,9 +876,9 @@ checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" [[package]] name = "bstr" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a40b47ad93e1a5404e6c18dec46b628214fee441c70f4ab5d6942142cc268a3d" +checksum = "90682c8d613ad3373e66de8c6411e0ae2ab2571e879d2efbf73558cc66f21279" dependencies = [ "lazy_static", "memchr", @@ -916,9 +916,9 @@ checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" [[package]] name = "byteorder" -version = "1.3.4" +version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "bytes" @@ -982,9 +982,9 @@ dependencies = [ [[package]] name = "cast" -version = "0.2.3" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b9434b9a5aa1450faa3f9cb14ea0e8c53bb5d2b3c1bfd1ab4fc03e9f33fbfb0" +checksum = "cc38c385bfd7e444464011bb24820f40dd1c76bcdfa1b78611cb7c2e5cafab75" dependencies = [ "rustc_version", ] @@ -1072,7 +1072,7 @@ name = "clap_utils" version = "0.1.0" dependencies = [ "clap", - "dirs 3.0.1", + "dirs 3.0.2", "eth2_network_config", "eth2_ssz", "hex", @@ -1085,14 +1085,14 @@ version = "0.2.0" dependencies = [ "beacon_chain", "directory", - "dirs 3.0.1", + "dirs 3.0.2", "environment", "error-chain", "eth1", "eth2_config", "eth2_libp2p", "eth2_ssz", - "futures 0.3.13", + "futures 0.3.14", "genesis", "http_api", "http_metrics", @@ -1113,9 +1113,9 @@ dependencies = [ "slot_clock", "store", "task_executor", - "time 0.2.25", + "time 0.2.26", "timer", - "tokio 1.2.0", + "tokio 1.5.0", "toml", "tree_hash", "types", @@ -1184,9 +1184,9 @@ checksum = "9f6b64db6932c7e49332728e3a6bd82c6b7e16016607d20923b537c3bc4c0d5f" [[package]] name = "const_fn" -version = "0.4.5" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28b9d6de7f49e22cf97ad17fc4036ece69300032f45f78f30b4a4482cdc3f4a6" +checksum = "402da840495de3f976eaefc3485b7f5eb5b0bf9761f9a47be27fe975b3b8c2ec" [[package]] name = "constant_time_eq" @@ -1194,6 +1194,12 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + [[package]] name = "core-foundation" version = "0.9.1" @@ -1269,9 +1275,9 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dca26ee1f8d361640700bde38b2c37d8c22b3ce2d360e1fc1c74ea4b0aa7d775" +checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4" dependencies = [ "cfg-if 1.0.0", "crossbeam-utils", @@ -1290,9 +1296,9 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2584f639eb95fea8c798496315b297cf81b9b58b6d30ab066a75455333cf4b12" +checksum = "52fb27eab85b17fbb9f6fd667089e07d6a2eb8743d02639ee7f6a7a7729c9c94" dependencies = [ "cfg-if 1.0.0", "crossbeam-utils", @@ -1303,9 +1309,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7e9d99fa91428effe99c5c6d4634cdeba32b8cf784fc428a2a687f61a952c49" +checksum = "4feb231f0d4d6af81aed15928e58ecf5816aa62a2393e2c82f46973e92a9a278" dependencies = [ "autocfg 1.0.1", "cfg-if 1.0.0", @@ -1372,9 +1378,9 @@ dependencies = [ [[package]] name = "ctor" -version = "0.1.19" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8f45d9ad417bcef4817d614a501ab55cdd96a6fdb24f49aab89a54acfd66b19" +checksum = "5e98e2ad1a782e33928b96fc3948e7c355e5af34ba4de7670fe8bac2a3b2006d" dependencies = [ "quote", "syn", @@ -1391,9 +1397,9 @@ dependencies = [ [[package]] name = "ctrlc" -version = "3.1.8" +version = "3.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c15b8ec3b5755a188c141c1f6a98e76de31b936209bf066b647979e2a84764a9" +checksum = "232295399409a8b7ae41276757b5a1cc21032848d42bff2352261f958b3ca29a" dependencies = [ "nix 0.20.0", "winapi 0.3.9", @@ -1401,24 +1407,24 @@ dependencies = [ [[package]] name = "curl" -version = "0.4.34" +version = "0.4.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e268162af1a5fe89917ae25ba3b0a77c8da752bdc58e7dbb4f15b91fbd33756e" +checksum = "5a872858e9cb9e3b96c80dd78774ad9e32e44d3b05dc31e142b858d14aebc82c" dependencies = [ "curl-sys", "libc", "openssl-probe", "openssl-sys", "schannel", - "socket2", + "socket2 0.3.19", "winapi 0.3.9", ] [[package]] name = "curl-sys" -version = "0.4.40+curl-7.75.0" +version = "0.4.42+curl-7.76.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ffafc1c35958318bd7fdd0582995ce4c72f4f461a8e70499ccee83a619fd562" +checksum = "4636d8d6109c842707018a104051436bffb8991ea20b2d1293db70b6e0ee4c7c" dependencies = [ "cc", "libc", @@ -1432,9 +1438,9 @@ dependencies = [ [[package]] name = "curve25519-dalek" -version = "3.0.2" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f627126b946c25a4638eec0ea634fc52506dea98db118aae985118ce7c3d723f" +checksum = "639891fde0dbea823fc3d798a0fdf9d2f9440a42d64a78ab3488b0ca025117b3" dependencies = [ "byteorder", "digest 0.9.0", @@ -1557,10 +1563,11 @@ dependencies = [ [[package]] name = "derive_more" -version = "0.99.11" +version = "0.99.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41cb0e6161ad61ed084a36ba71fbba9e3ac5aee3606fb607fe08da6acbcf3d8c" +checksum = "f82b1b72f1263f214c0f823371768776c4f5841b942c9883aa8e5ec584fd0ba6" dependencies = [ + "convert_case", "proc-macro2", "quote", "syn", @@ -1602,7 +1609,7 @@ version = "0.1.0" dependencies = [ "clap", "clap_utils", - "dirs 3.0.1", + "dirs 3.0.2", "eth2_network_config", ] @@ -1619,9 +1626,9 @@ dependencies = [ [[package]] name = "dirs" -version = "3.0.1" +version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "142995ed02755914747cc6ca76fc7e4583cd18578746716d0508ea6ed558b9ff" +checksum = "30baa043103c9d0c2a57cf537cc2f35623889dc0d405e6c3cccfadbc81c71309" dependencies = [ "dirs-sys", ] @@ -1638,12 +1645,12 @@ dependencies = [ [[package]] name = "dirs-sys" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e93d7f5705de3e49895a2b5e0b8855a1c27f080192ae9c32a6432d50741a57a" +checksum = "03d86534ed367a67548dc68113a0f5db55432fdfbb6e6f9d77704397d95d5780" dependencies = [ "libc", - "redox_users 0.3.5", + "redox_users 0.4.0", "winapi 0.3.9", ] @@ -1676,7 +1683,7 @@ dependencies = [ "digest 0.9.0", "enr", "fnv", - "futures 0.3.13", + "futures 0.3.14", "hex", "hkdf", "k256", @@ -1687,9 +1694,9 @@ dependencies = [ "rlp 0.5.0", "sha2 0.9.3", "smallvec", - "tokio 1.2.0", + "tokio 1.5.0", "tokio-stream", - "tokio-util 0.6.3", + "tokio-util 0.6.6", "tracing", "tracing-subscriber", "uint", @@ -1707,7 +1714,7 @@ dependencies = [ "digest 0.9.0", "enr", "fnv", - "futures 0.3.13", + "futures 0.3.14", "hex", "hkdf", "k256", @@ -1719,9 +1726,9 @@ dependencies = [ "rlp 0.5.0", "sha2 0.9.3", "smallvec", - "tokio 1.2.0", + "tokio 1.5.0", "tokio-stream", - "tokio-util 0.6.3", + "tokio-util 0.6.6", "tracing", "tracing-subscriber", "uint", @@ -1730,9 +1737,9 @@ dependencies = [ [[package]] name = "dtoa" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d7ed2934d741c6b37e33e3832298e8850b53fd2d2bea03873375596c7cea4e" +checksum = "56899898ce76aaf4a0f24d914c97ea6ed976d42fec6ad33fcbb0a1103e07b2b0" [[package]] name = "ecdsa" @@ -1747,9 +1754,9 @@ dependencies = [ [[package]] name = "ed25519" -version = "1.0.3" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37c66a534cbb46ab4ea03477eae19d5c22c01da8258030280b7bd9d8433fb6ef" +checksum = "8d0860415b12243916284c67a9be413e044ee6668247b99ba26d94b2bc06c8f6" dependencies = [ "signature", ] @@ -1887,7 +1894,7 @@ dependencies = [ "eth2_config", "eth2_network_config", "exit-future", - "futures 0.3.13", + "futures 0.3.14", "logging", "parking_lot", "slog", @@ -1896,7 +1903,7 @@ dependencies = [ "slog-term", "sloggers", "task_executor", - "tokio 1.2.0", + "tokio 1.5.0", "types", ] @@ -1921,7 +1928,7 @@ dependencies = [ "eth2_ssz", "eth2_ssz_derive", "fallback", - "futures 0.3.13", + "futures 0.3.14", "hex", "lazy_static", "libflate", @@ -1929,13 +1936,14 @@ dependencies = [ "merkle_proof", "parking_lot", "reqwest", + "sensitive_url", "serde", "serde_json", "slog", "sloggers", "state_processing", "task_executor", - "tokio 1.2.0", + "tokio 1.5.0", "tokio-compat-02", "toml", "tree_hash", @@ -1948,9 +1956,9 @@ name = "eth1_test_rig" version = "0.2.0" dependencies = [ "deposit_contract", - "futures 0.3.13", + "futures 0.3.14", "serde_json", - "tokio 1.2.0", + "tokio 1.5.0", "tokio-compat-02", "types", "web3", @@ -1966,7 +1974,7 @@ dependencies = [ "eth2_libp2p", "eth2_ssz", "eth2_ssz_derive", - "futures 0.3.13", + "futures 0.3.14", "futures-util", "hex", "libsecp256k1", @@ -1975,6 +1983,7 @@ dependencies = [ "psutil", "reqwest", "ring", + "sensitive_url", "serde", "serde_json", "serde_utils", @@ -2058,7 +2067,7 @@ version = "0.2.0" dependencies = [ "base64 0.13.0", "directory", - "dirs 3.0.1", + "dirs 3.0.2", "discv5 0.1.0-beta.3 (git+https://github.com/sigp/discv5?rev=02d2c896c66f8dc2b848c3996fedcd98e1dfec69)", "error-chain", "eth2_ssz", @@ -2066,7 +2075,7 @@ dependencies = [ "eth2_ssz_types", "exit-future", "fnv", - "futures 0.3.13", + "futures 0.3.14", "futures-io", "hashset_delay", "hex", @@ -2090,9 +2099,9 @@ dependencies = [ "task_executor", "tempfile", "tiny-keccak 2.0.2", - "tokio 1.2.0", + "tokio 1.5.0", "tokio-io-timeout", - "tokio-util 0.6.3", + "tokio-util 0.6.6", "types", "unsigned-varint 0.6.0", "void", @@ -2223,19 +2232,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e43f2f1833d64e33f15592464d6fdd70f349dda7b1a53088eb83cd94014008c5" dependencies = [ - "futures 0.3.13", -] - -[[package]] -name = "extend" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f47da3a72ec598d9c8937a7ebca8962a5c7a1f28444e38c2b33c771ba3f55f05" -dependencies = [ - "proc-macro-error", - "proc-macro2", - "quote", - "syn", + "futures 0.3.14", ] [[package]] @@ -2265,9 +2262,9 @@ checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" [[package]] name = "fastrand" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca5faf057445ce5c9d4329e382b2ce7ca38550ef3b73a5348362d5f24e0c7fe3" +checksum = "77b705829d1e87f762c2df6da140b26af5839e1033aa84aa5f56bb688e4e1bdb" dependencies = [ "instant", ] @@ -2304,27 +2301,15 @@ checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d" [[package]] name = "flate2" -version = "1.0.14" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cfff41391129e0a856d6d822600b8d71179d46879e310417eb9c762eb178b42" +checksum = "cd3aec53de10fe96d7d8c565eb17f2c687bb5518a2ec453b5b1252964526abe0" dependencies = [ - "cfg-if 0.1.10", + "cfg-if 1.0.0", "crc32fast", "libc", "libz-sys", - "miniz_oxide 0.3.7", -] - -[[package]] -name = "flume" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "531a685ab99b8f60a271b44d5dd1a76e55124a8c9fa0407b7a8e9cd172d5b588" -dependencies = [ - "futures-core", - "futures-sink", - "pin-project 1.0.5", - "spinning_top", + "miniz_oxide", ] [[package]] @@ -2414,9 +2399,9 @@ checksum = "3a471a38ef8ed83cd6e40aa59c1ffe17db6855c18e3604d9c4ed8c08ebc28678" [[package]] name = "futures" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f55667319111d593ba876406af7c409c0ebb44dc4be6132a783ccf163ea14c1" +checksum = "a9d5813545e459ad3ca1bff9915e9ad7f1a47dc6a91b627ce321d5863b7dd253" dependencies = [ "futures-channel", "futures-core", @@ -2429,9 +2414,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c2dd2df839b57db9ab69c2c9d8f3e8c81984781937fe2807dc6dcf3b2ad2939" +checksum = "ce79c6a52a299137a6013061e0cf0e688fce5d7f1bc60125f520912fdb29ec25" dependencies = [ "futures-core", "futures-sink", @@ -2439,15 +2424,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15496a72fabf0e62bdc3df11a59a3787429221dd0710ba8ef163d6f7a9112c94" +checksum = "098cd1c6dda6ca01650f1a37a794245eb73181d0d4d4e955e2f3c37db7af1815" [[package]] name = "futures-executor" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "891a4b7b96d84d5940084b2a37632dd65deeae662c114ceaa2c879629c9c0ad1" +checksum = "10f6cb7042eda00f0049b1d2080aa4b93442997ee507eb3828e8bd7577f94c9d" dependencies = [ "futures-core", "futures-task", @@ -2457,9 +2442,9 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71c2c65c57704c32f5241c1223167c2c3294fd34ac020c807ddbe6db287ba59" +checksum = "365a1a1fb30ea1c03a830fdb2158f5236833ac81fa0ad12fe35b29cddc35cb04" [[package]] name = "futures-lite" @@ -2478,9 +2463,9 @@ dependencies = [ [[package]] name = "futures-macro" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea405816a5139fb39af82c2beb921d52143f556038378d6db21183a5c37fbfb7" +checksum = "668c6733a182cd7deb4f1de7ba3bf2120823835b3bcfbeacf7d2c4a773c1bb8b" dependencies = [ "proc-macro-hack", "proc-macro2", @@ -2501,15 +2486,15 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85754d98985841b7d4f5e8e6fbfa4a4ac847916893ec511a2917ccd8525b8bb3" +checksum = "5c5629433c555de3d82861a7a4e3794a4c40040390907cfbfd7143a92a426c23" [[package]] name = "futures-task" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa189ef211c15ee602667a6fcfe1c1fd9e07d42250d2156382820fba33c9df80" +checksum = "ba7aa51095076f3ba6d9a1f702f74bd05ec65f555d70d2033d55ba8d69f581bc" [[package]] name = "futures-timer" @@ -2519,9 +2504,9 @@ checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" [[package]] name = "futures-util" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1812c7ab8aedf8d6f2701a43e1243acdbcc2b36ab26e2ad421eb99ac963d96d1" +checksum = "3c144ad54d60f23927f0a6b6d816e4271278b64f005ad65e4e35291d2de9c025" dependencies = [ "futures-channel", "futures-core", @@ -2566,16 +2551,17 @@ dependencies = [ "eth2_hashing", "eth2_ssz", "exit-future", - "futures 0.3.13", + "futures 0.3.14", "int_to_bytes", "merkle_proof", "parking_lot", "rayon", + "sensitive_url", "serde", "serde_derive", "slog", "state_processing", - "tokio 1.2.0", + "tokio 1.5.0", "tokio-compat-02", "tree_hash", "types", @@ -2693,9 +2679,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.1" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d832b01df74254fe364568d6ddc294443f61cbec82816b60904303af87efae78" +checksum = "825343c4eef0b63f541f8903f395dc5beb362a979b5799a84062527ef1e37726" dependencies = [ "bytes 1.0.1", "fnv", @@ -2705,8 +2691,8 @@ dependencies = [ "http", "indexmap", "slab", - "tokio 1.2.0", - "tokio-util 0.6.3", + "tokio 1.5.0", + "tokio-util 0.6.6", "tracing", ] @@ -2738,9 +2724,9 @@ dependencies = [ name = "hashset_delay" version = "0.2.0" dependencies = [ - "futures 0.3.13", - "tokio 1.2.0", - "tokio-util 0.6.3", + "futures 0.3.14", + "tokio 1.5.0", + "tokio-util 0.6.6", ] [[package]] @@ -2851,9 +2837,9 @@ dependencies = [ [[package]] name = "http" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7245cd7449cc792608c3c8a9eaf69bd4eabbabf802713748fd739c98b82f0747" +checksum = "527e8c9ac747e28542699a951517aa9a6945af506cd1f2e1b53a576c17b6cc11" dependencies = [ "bytes 1.0.1", "fnv", @@ -2872,12 +2858,13 @@ dependencies = [ [[package]] name = "http-body" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2861bd27ee074e5ee891e8b539837a9430012e249d7f0ca2d795650f579c1994" +checksum = "5dfb77c123b4e2f72a2069aeae0b4b4949cc7e966df277813fc16347e7549737" dependencies = [ "bytes 1.0.1", "http", + "pin-project-lite 0.2.6", ] [[package]] @@ -2893,21 +2880,22 @@ dependencies = [ "eth2_libp2p", "eth2_ssz", "fork_choice", - "futures 0.3.13", + "futures 0.3.14", "hex", "lazy_static", "lighthouse_metrics", "lighthouse_version", "network", "parking_lot", + "sensitive_url", "serde", "slog", "slot_clock", "state_processing", "store", - "tokio 1.2.0", + "tokio 1.5.0", "tokio-stream", - "tokio-util 0.6.3", + "tokio-util 0.6.6", "tree_hash", "types", "warp", @@ -2931,7 +2919,7 @@ dependencies = [ "slog", "slot_clock", "store", - "tokio 1.2.0", + "tokio 1.5.0", "types", "warp", "warp_utils", @@ -2939,9 +2927,9 @@ dependencies = [ [[package]] name = "httparse" -version = "1.3.5" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "615caabe2c3160b313d52ccc905335f4ed5f10881dd63dc5699d47e90be85691" +checksum = "4a1ce40d6fc9764887c2fdc7305c3dcc429ba11ff981c1509416afd5697e4437" [[package]] name = "httpdate" @@ -2949,11 +2937,17 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "494b4d60369511e7dea41cf646832512a94e542f68bb9c49e54518e0f468eb47" +[[package]] +name = "httpdate" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05842d0d43232b23ccb7060ecb0f0626922c21f30012e97b767b30afd4a5d4b9" + [[package]] name = "httpmock" -version = "0.5.5" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93a02d342ce934f890fa39865cf7d2f3485d19a805b7c570ea33819106df1c21" +checksum = "b217899bcbe8ad3bdee7a46727bd3754b908831462755567852fb20eac585d46" dependencies = [ "assert-json-diff", "async-object-pool", @@ -2963,7 +2957,7 @@ dependencies = [ "crossbeam-utils", "difference", "futures-util", - "hyper 0.14.4", + "hyper 0.14.7", "isahc", "lazy_static", "levenshtein", @@ -2973,7 +2967,7 @@ dependencies = [ "serde", "serde_json", "serde_regex", - "tokio 1.2.0", + "tokio 1.5.0", ] [[package]] @@ -2996,10 +2990,10 @@ dependencies = [ "http", "http-body 0.3.1", "httparse", - "httpdate", + "httpdate 0.3.2", "itoa", - "pin-project 1.0.5", - "socket2", + "pin-project 1.0.7", + "socket2 0.3.19", "tokio 0.2.25", "tower-service", "tracing", @@ -3008,23 +3002,23 @@ dependencies = [ [[package]] name = "hyper" -version = "0.14.4" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8e946c2b1349055e0b72ae281b238baf1a3ea7307c7e9f9d64673bdd9c26ac7" +checksum = "1e5f105c494081baa3bf9e200b279e27ec1623895cd504c7dbef8d0b080fcf54" dependencies = [ "bytes 1.0.1", "futures-channel", "futures-core", "futures-util", - "h2 0.3.1", + "h2 0.3.3", "http", - "http-body 0.4.0", + "http-body 0.4.1", "httparse", - "httpdate", + "httpdate 1.0.0", "itoa", - "pin-project 1.0.5", - "socket2", - "tokio 1.2.0", + "pin-project 1.0.7", + "socket2 0.4.0", + "tokio 1.5.0", "tower-service", "tracing", "want", @@ -3037,7 +3031,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f93ec5be69758dfc06b9b29efa9d6e9306e387c85eb362c603912eead2ad98c7" dependencies = [ "bytes 0.5.6", - "futures 0.3.13", + "futures 0.3.14", "http", "hyper 0.13.10", "hyper-tls 0.4.3", @@ -3068,9 +3062,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" dependencies = [ "bytes 1.0.1", - "hyper 0.14.4", + "hyper 0.14.7", "native-tls", - "tokio 1.2.0", + "tokio 1.5.0", "tokio-native-tls", ] @@ -3082,9 +3076,9 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "idna" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89829a5d69c23d348314a7ac337fe39173b61149a9864deabd260983aed48c21" +checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" dependencies = [ "matches", "unicode-bidi", @@ -3119,7 +3113,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97b8538953a3f0d0d3868f0a706eb4273535e10d72acb5c82c1c23ae48835c85" dependencies = [ "async-io", - "futures 0.3.13", + "futures 0.3.14", "futures-lite", "if-addrs", "ipnet", @@ -3231,20 +3225,21 @@ checksum = "47be2f14c678be2fdcab04ab1171db51b2762ce6f0a8ee87c8dd4a04ed216135" [[package]] name = "isahc" -version = "1.1.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af3d0a62435883f745c825ec06a03a38d24bf5fa65c43e2c083b6a60ce0058ae" +checksum = "3bd9294f1ecdda747b8a092b07873285e613adc14e9c9526205eacedcf3ecd2b" dependencies = [ + "async-channel", "crossbeam-utils", "curl", "curl-sys", "encoding_rs", - "flume", "futures-lite", "http", "log", "mime", "once_cell", + "polling", "slab", "sluice", "tracing", @@ -3279,9 +3274,9 @@ checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" [[package]] name = "js-sys" -version = "0.3.48" +version = "0.3.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc9f84f9b115ce7843d60706df1422a916680bfdfcbdb0447c5614ff9d7e4d78" +checksum = "2d99f9e3e84b8f67f846ef5b4cbbc3b1c29f6c759fcbce6f01aa0e73d932a24c" dependencies = [ "wasm-bindgen", ] @@ -3301,9 +3296,9 @@ dependencies = [ [[package]] name = "k256" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf02ecc966e1b7e8db1c81ac8f321ba24d1cfab5b634961fab10111f015858e1" +checksum = "4476a0808212a9e81ce802eb1a0cfc60e73aea296553bacc0fac7e1268bc572a" dependencies = [ "cfg-if 1.0.0", "ecdsa", @@ -3387,7 +3382,7 @@ dependencies = [ "clap_utils", "deposit_contract", "directory", - "dirs 3.0.1", + "dirs 3.0.2", "environment", "eth1_test_rig", "eth2_keystore", @@ -3395,18 +3390,19 @@ dependencies = [ "eth2_network_config", "eth2_ssz", "eth2_wallet", - "futures 0.3.13", + "futures 0.3.14", "genesis", "hex", "lighthouse_version", "log", "rand 0.7.3", "regex", + "sensitive_url", "serde", "serde_yaml", "simple_logger", "state_processing", - "tokio 1.2.0", + "tokio 1.5.0", "tree_hash", "types", "validator_dir", @@ -3443,27 +3439,29 @@ checksum = "db13adb97ab515a3691f56e4dbab09283d0b86cb45abd991d8634a9d6f501760" [[package]] name = "libc" -version = "0.2.88" +version = "0.2.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03b07a082330a35e43f63177cc01689da34fbffa0105e1246cf0311472cac73a" +checksum = "18794a8ad5b29321f790b55d93dfba91e125cb1a9edbd4f8e3150acc771c1a5e" [[package]] name = "libflate" -version = "1.0.3" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "389de7875e06476365974da3e7ff85d55f1972188ccd9f6020dd7c8156e17914" +checksum = "6d87eae36b3f680f7f01645121b782798b56ef33c53f83d1c66ba3a22b60bfe3" dependencies = [ "adler32", "crc32fast", "libflate_lz77", - "rle-decode-fast", ] [[package]] name = "libflate_lz77" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3286f09f7d4926fc486334f28d8d2e6ebe4f7f9994494b6dab27ddfad2c9b11b" +checksum = "39a734c0493409afcd49deee13c006a04e3586b9761a03543c6272c9c51f2f5a" +dependencies = [ + "rle-decode-fast", +] [[package]] name = "libm" @@ -3489,7 +3487,7 @@ checksum = "adc225a49973cf9ab10d0cdd6a4b8f0cda299df9b760824bbb623f15f8f0c95a" dependencies = [ "atomic", "bytes 1.0.1", - "futures 0.3.13", + "futures 0.3.14", "lazy_static", "libp2p-core", "libp2p-dns", @@ -3504,7 +3502,7 @@ dependencies = [ "libp2p-yamux", "parity-multiaddr", "parking_lot", - "pin-project 1.0.5", + "pin-project 1.0.7", "smallvec", "wasm-timer", ] @@ -3520,7 +3518,7 @@ dependencies = [ "ed25519-dalek", "either", "fnv", - "futures 0.3.13", + "futures 0.3.14", "futures-timer", "lazy_static", "libsecp256k1", @@ -3529,7 +3527,7 @@ dependencies = [ "multistream-select", "parity-multiaddr", "parking_lot", - "pin-project 1.0.5", + "pin-project 1.0.7", "prost", "prost-build", "rand 0.7.3", @@ -3549,7 +3547,7 @@ version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5153b6db68fd4baa3b304e377db744dd8fea8ff4e4504509ee636abcde88d3e3" dependencies = [ - "futures 0.3.13", + "futures 0.3.14", "libp2p-core", "log", ] @@ -3565,7 +3563,7 @@ dependencies = [ "byteorder", "bytes 1.0.1", "fnv", - "futures 0.3.13", + "futures 0.3.14", "hex_fmt", "libp2p-core", "libp2p-swarm", @@ -3586,7 +3584,7 @@ version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b40fb36a059b7a8cce1514bd8b546fa612e006c9937caa7f5950cb20021fe91e" dependencies = [ - "futures 0.3.13", + "futures 0.3.14", "libp2p-core", "libp2p-swarm", "log", @@ -3604,7 +3602,7 @@ checksum = "350ce8b3923594aedabd5d6e3f875d058435052a29c3f32df378bc70d10be464" dependencies = [ "asynchronous-codec", "bytes 1.0.1", - "futures 0.3.13", + "futures 0.3.14", "libp2p-core", "log", "nohash-hasher", @@ -3622,7 +3620,7 @@ checksum = "4aca322b52a0c5136142a7c3971446fb1e9964923a526c9cc6ef3b7c94e57778" dependencies = [ "bytes 1.0.1", "curve25519-dalek", - "futures 0.3.13", + "futures 0.3.14", "lazy_static", "libp2p-core", "log", @@ -3643,7 +3641,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7955b973e1fd2bd61ffd43ce261c1223f61f4aacd5bae362a924993f9a25fd98" dependencies = [ "either", - "futures 0.3.13", + "futures 0.3.14", "libp2p-core", "log", "rand 0.7.3", @@ -3669,7 +3667,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "88a5aef80e519a6cb8e2663605142f97baaaea1a252eecbf8756184765f7471b" dependencies = [ "async-io", - "futures 0.3.13", + "futures 0.3.14", "futures-timer", "if-addrs", "if-watch", @@ -3677,8 +3675,8 @@ dependencies = [ "libc", "libp2p-core", "log", - "socket2", - "tokio 1.2.0", + "socket2 0.3.19", + "tokio 1.5.0", ] [[package]] @@ -3688,7 +3686,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3b1c6a3431045da8b925ed83384e4c5163e14b990572307fca9c507435d4d22" dependencies = [ "either", - "futures 0.3.13", + "futures 0.3.14", "futures-rustls", "libp2p-core", "log", @@ -3705,7 +3703,7 @@ version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4819358c542a86ff95f6ae691efb4b94ddaf477079b01a686f5705b79bfc232a" dependencies = [ - "futures 0.3.13", + "futures 0.3.14", "libp2p-core", "parking_lot", "thiserror", @@ -3741,9 +3739,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "602113192b08db8f38796c4e85c39e960c145965140e918018bcde1952429655" +checksum = "de5435b8549c16d423ed0c03dbaafe57cf6c3344744f1242520d59c9d8ecec66" dependencies = [ "cc", "libc", @@ -3765,20 +3763,23 @@ dependencies = [ "directory", "env_logger 0.8.3", "environment", + "eth2_libp2p", "eth2_network_config", - "futures 0.3.13", + "futures 0.3.14", "lazy_static", "lighthouse_metrics", "lighthouse_version", "logging", "remote_signer", + "serde_json", "slashing_protection", "slog", "slog-async", "slog-term", "sloggers", + "task_executor", "tempfile", - "tokio 1.2.0", + "tokio 1.5.0", "types", "validator_client", "validator_dir", @@ -3831,9 +3832,9 @@ dependencies = [ [[package]] name = "lock_api" -version = "0.4.2" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd96ffd135b2fd7b973ac026d28085defbe8983df057ced3eb4f2130b0831312" +checksum = "0382880606dff6d15c9476c416d18690b72742aa7b605bb6dd6ec9030fbf07eb" dependencies = [ "scopeguard", ] @@ -3920,15 +3921,15 @@ checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" [[package]] name = "memchr" -version = "2.3.4" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" +checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc" [[package]] name = "memoffset" -version = "0.6.1" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "157b4208e3059a8f9e78d559edc658e13df41410cb3ae03979c83130067fdd87" +checksum = "f83fb6581e8ed1f85fd45c116db8405483899489e38406156c25eb743554361d" dependencies = [ "autocfg 1.0.1", ] @@ -3973,15 +3974,6 @@ dependencies = [ "unicase", ] -[[package]] -name = "miniz_oxide" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "791daaae1ed6889560f8c4359194f56648355540573244a5448a83ba1ecc7435" -dependencies = [ - "adler32", -] - [[package]] name = "miniz_oxide" version = "0.4.4" @@ -4013,13 +4005,13 @@ dependencies = [ [[package]] name = "mio" -version = "0.7.9" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5dede4e2065b3842b8b0af444119f3aa331cc7cc2dd20388bfb0f5d5a38823a" +checksum = "cf80d3e903b34e0bd7282b218398aec54e082c840d9baf8339e0080a0c542956" dependencies = [ "libc", "log", - "miow 0.3.6", + "miow 0.3.7", "ntapi", "winapi 0.3.9", ] @@ -4032,7 +4024,7 @@ checksum = "0840c1c50fd55e521b247f949c241c9997709f23bd7f023b9762cd561e935656" dependencies = [ "log", "mio 0.6.23", - "miow 0.3.6", + "miow 0.3.7", "winapi 0.3.9", ] @@ -4061,11 +4053,10 @@ dependencies = [ [[package]] name = "miow" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a33c1b55807fbed163481b5ba66db4b2fa6cde694a5027be10fb724206c5897" +checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" dependencies = [ - "socket2", "winapi 0.3.9", ] @@ -4098,9 +4089,9 @@ dependencies = [ [[package]] name = "multimap" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1255076139a83bb467426e7f8d0134968a8118844faa755985e077cf31850333" +checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" [[package]] name = "multipart" @@ -4127,9 +4118,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d91ec0a2440aaff5f78ec35631a7027d50386c6163aa975f7caa0d5da4b6ff8" dependencies = [ "bytes 1.0.1", - "futures 0.3.13", + "futures 0.3.14", "log", - "pin-project 1.0.5", + "pin-project 1.0.7", "smallvec", "unsigned-varint 0.7.0", ] @@ -4152,16 +4143,6 @@ dependencies = [ "tempfile", ] -[[package]] -name = "nb-connect" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "670361df1bc2399ee1ff50406a0d422587dd3bb0da596e1978fe8e05dabddf4f" -dependencies = [ - "libc", - "socket2", -] - [[package]] name = "net2" version = "0.2.37" @@ -4186,7 +4167,7 @@ dependencies = [ "eth2_ssz_types", "exit-future", "fnv", - "futures 0.3.13", + "futures 0.3.14", "genesis", "hashset_delay", "hex", @@ -4213,9 +4194,9 @@ dependencies = [ "strum", "task_executor", "tempfile", - "tokio 1.2.0", + "tokio 1.5.0", "tokio-stream", - "tokio-util 0.6.3", + "tokio-util 0.6.6", "tree_hash", "types", ] @@ -4259,9 +4240,10 @@ dependencies = [ "environment", "eth2", "eth2_config", - "futures 0.3.13", + "futures 0.3.14", "genesis", "reqwest", + "sensitive_url", "serde", "tempfile", "types", @@ -4396,15 +4378,15 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "openssl" -version = "0.10.32" +version = "0.10.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "038d43985d1ddca7a9900630d8cd031b56e4794eecc2e9ea39dd17aa04399a70" +checksum = "6d7830286ad6a3973c0f1d9b73738f69c76b739301d0229c4b96501695cbe4c8" dependencies = [ "bitflags", "cfg-if 1.0.0", "foreign-types", - "lazy_static", "libc", + "once_cell", "openssl-sys", ] @@ -4416,18 +4398,18 @@ checksum = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" [[package]] name = "openssl-src" -version = "111.14.0+1.1.1j" +version = "111.15.0+1.1.1k" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "055b569b5bd7e5462a1700f595c7c7d487691d73b5ce064176af7f9f0cbb80a9" +checksum = "b1a5f6ae2ac04393b217ea9f700cd04fa9bf3d93fae2872069f3d15d908af70a" dependencies = [ "cc", ] [[package]] name = "openssl-sys" -version = "0.9.60" +version = "0.9.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "921fc71883267538946025deffb622905ecad223c28efbfdef9bb59a0175f3e6" +checksum = "fa52160d45fa2e7608d504b7c3a3355afed615e6d8b627a74458634ba21b69bd" dependencies = [ "autocfg 1.0.1", "cc", @@ -4460,9 +4442,9 @@ dependencies = [ [[package]] name = "parity-multiaddr" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2c6805f98667a3828afb2ec2c396a8d610497e8d546f5447188aae47c5a79ec" +checksum = "58341485071825827b7f03cf7efd1cb21e6a709bea778fb50227fd45d2f361b4" dependencies = [ "arrayref", "bs58 0.4.0", @@ -4514,7 +4496,7 @@ dependencies = [ "cfg-if 1.0.0", "instant", "libc", - "redox_syscall 0.2.5", + "redox_syscall 0.2.7", "smallvec", "winapi 0.3.9", ] @@ -4564,33 +4546,33 @@ dependencies = [ [[package]] name = "pico-args" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d70072c20945e1ab871c472a285fc772aefd4f5407723c206242f2c6f94595d6" +checksum = "7d7afeb98c5a10e0bffcc7fc16e105b04d06729fac5fd6384aebf7ff5cb5a67d" [[package]] name = "pin-project" -version = "0.4.27" +version = "0.4.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ffbc8e94b38ea3d2d8ba92aea2983b503cd75d0888d75b86bb37970b5698e15" +checksum = "918192b5c59119d51e0cd221f4d49dde9112824ba717369e903c97d076083d0f" dependencies = [ - "pin-project-internal 0.4.27", + "pin-project-internal 0.4.28", ] [[package]] name = "pin-project" -version = "1.0.5" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96fa8ebb90271c4477f144354485b8068bd8f6b78b428b01ba892ca26caf0b63" +checksum = "c7509cc106041c40a4518d2af7a61530e1eed0e6285296a3d8c5472806ccc4a4" dependencies = [ - "pin-project-internal 1.0.5", + "pin-project-internal 1.0.7", ] [[package]] name = "pin-project-internal" -version = "0.4.27" +version = "0.4.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65ad2ae56b6abe3a1ee25f15ee605bacadb9a764edaba9c2bf4103800d4a1895" +checksum = "3be26700300be6d9d23264c73211d8190e755b6b5ca7a1b28230025511b52a5e" dependencies = [ "proc-macro2", "quote", @@ -4599,9 +4581,9 @@ dependencies = [ [[package]] name = "pin-project-internal" -version = "1.0.5" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "758669ae3558c6f74bd2a18b41f7ac0b5a195aea6639d6a9b5e5d1ad5ba24c0b" +checksum = "48c950132583b500556b1efd71d45b319029f2b71518d979fcc208e16b42426f" dependencies = [ "proc-macro2", "quote", @@ -4677,11 +4659,11 @@ dependencies = [ [[package]] name = "polling" -version = "2.0.2" +version = "2.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2a7bc6b2a29e632e45451c941832803a18cce6781db04de8a04696cdca8bde4" +checksum = "4fc12d774e799ee9ebae13f4076ca003b40d18a11ac0f3641e6f899618580b7b" dependencies = [ - "cfg-if 0.1.10", + "cfg-if 1.0.0", "libc", "log", "wepoll-sys", @@ -4880,15 +4862,15 @@ dependencies = [ [[package]] name = "protobuf" -version = "2.22.0" +version = "2.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73f72884896d22e0da0e5b266cb9a780b791f6c3b2f5beab6368d6cd4f0dbb86" +checksum = "45604fc7a88158e7d514d8e22e14ac746081e7a70d7690074dd0029ee37458d6" [[package]] name = "psutil" -version = "3.2.0" +version = "3.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cdb732329774b8765346796abd1e896e9b3c86aae7f135bb1dda98c2c460f55" +checksum = "e780a52bf9358cb8257cac630b130dc603901f7488f8eef13e2d512cead10739" dependencies = [ "cfg-if 0.1.10", "darwin-libproc", @@ -5117,9 +5099,9 @@ checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" [[package]] name = "redox_syscall" -version = "0.2.5" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94341e4e44e24f6b591b59e47a8a027df12e008d73fd5672dbea9cc22f4507d9" +checksum = "85dd92e586f7355c633911e11f77f3d12f04b1b1bd76a198bd34ae3af8341ef2" dependencies = [ "bitflags", ] @@ -5142,19 +5124,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64" dependencies = [ "getrandom 0.2.2", - "redox_syscall 0.2.5", + "redox_syscall 0.2.7", ] [[package]] name = "regex" -version = "1.4.3" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9251239e129e16308e70d853559389de218ac275b515068abc96829d05b948a" +checksum = "ce5f1ceb7f74abbce32601642fcf8e8508a8a8991e0621c7d750295b9095702b" dependencies = [ "aho-corasick", "memchr", "regex-syntax", - "thread_local", ] [[package]] @@ -5169,9 +5150,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.22" +version = "0.6.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5eb417147ba9860a96cfe72a0b93bf88fee1744b5636ec99ab20c1aa9376581" +checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" [[package]] name = "remote_signer" @@ -5211,8 +5192,8 @@ version = "0.2.0" dependencies = [ "clap", "environment", - "futures 0.3.13", - "hyper 0.14.4", + "futures 0.3.14", + "hyper 0.14.7", "lazy_static", "regex", "remote_signer_backend", @@ -5230,8 +5211,9 @@ dependencies = [ "rand 0.7.3", "remote_signer_test", "reqwest", + "sensitive_url", "serde", - "tokio 1.2.0", + "tokio 1.5.0", "types", ] @@ -5246,10 +5228,11 @@ dependencies = [ "remote_signer_client", "remote_signer_consumer", "reqwest", + "sensitive_url", "serde", "serde_json", "tempfile", - "tokio 1.2.0", + "tokio 1.5.0", "types", ] @@ -5264,9 +5247,9 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.11.1" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0460542b551950620a3648c6aa23318ac6b3cd779114bd873209e6e8b5eb1c34" +checksum = "2296f2fac53979e8ccbc4a1136b25dcefd37be9ed7e4a1f6b05a6029c84ff124" dependencies = [ "base64 0.13.0", "bytes 1.0.1", @@ -5274,8 +5257,8 @@ dependencies = [ "futures-core", "futures-util", "http", - "http-body 0.4.0", - "hyper 0.14.4", + "http-body 0.4.1", + "hyper 0.14.7", "hyper-tls 0.5.0", "ipnet", "js-sys", @@ -5288,7 +5271,7 @@ dependencies = [ "serde", "serde_json", "serde_urlencoded", - "tokio 1.2.0", + "tokio 1.5.0", "tokio-native-tls", "url", "wasm-bindgen", @@ -5376,9 +5359,9 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.18" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e3bad0ee36814ca07d7968269dd4b7ec89ec2da10c4bb613928d3077083c232" +checksum = "410f7acf3cb3a44527c5d9546bad4bf4e6c460915d5f9f2fc524498bfe8f70ce" [[package]] name = "rustc-hash" @@ -5403,9 +5386,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.19.0" +version = "0.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "064fd21ff87c6e87ed4506e68beb42459caa4a0e2eb144932e6776768556980b" +checksum = "35edb675feee39aec9c99fa5ff985081995a06d594114ae14cbe797ad7b7a6d7" dependencies = [ "base64 0.13.0", "log", @@ -5426,8 +5409,8 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4da5fcb054c46f5a5dff833b129285a93d3f0179531735e6c866e8cc307d2020" dependencies = [ - "futures 0.3.13", - "pin-project 0.4.27", + "futures 0.3.14", + "pin-project 0.4.28", "static_assertions", ] @@ -5510,9 +5493,9 @@ dependencies = [ [[package]] name = "sct" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3042af939fca8c3453b7af0f1c66e533a15a86169e39de2657310ade8f98d3c" +checksum = "b362b83898e0e69f38515b82ee15aa80636befe47c3b6d3d89a911e78fc228ce" dependencies = [ "ring", "untrusted", @@ -5538,9 +5521,9 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.1.2" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d493c5f39e02dfb062cd8f33301f90f9b13b650e8c1b1d0fd75c19dd64bff69d" +checksum = "3670b1d2fdf6084d192bc71ead7aabe6c06aa2ea3fbd9cc3ac111fa5c2b1bd84" dependencies = [ "bitflags", "core-foundation", @@ -5551,9 +5534,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dee48cdde5ed250b0d3252818f646e174ab414036edb884dde62d80a3ac6082d" +checksum = "3676258fd3cfe2c9a0ec99ce3038798d847ce3e4bb17746373eb9f0f1ac16339" dependencies = [ "core-foundation-sys", "libc", @@ -5574,11 +5557,19 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" +[[package]] +name = "sensitive_url" +version = "0.1.0" +dependencies = [ + "serde", + "url", +] + [[package]] name = "serde" -version = "1.0.124" +version = "1.0.125" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd761ff957cb2a45fbb9ab3da6512de9de55872866160b23c25f1a841e99d29f" +checksum = "558dc50e1a5a5fa7112ca2ce4effcb321b0300c0d4ccf0776a9f60cd89031171" dependencies = [ "serde_derive", ] @@ -5595,9 +5586,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.124" +version = "1.0.125" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1800f7693e94e186f5e25a28291ae1570da908aff7d97a095dec1e56ff99069b" +checksum = "b093b7a2bb58203b5da3056c05b4ec1fed827dcfdb37347a8841695263b3d06d" dependencies = [ "proc-macro2", "quote", @@ -5737,9 +5728,9 @@ dependencies = [ [[package]] name = "signal-hook" -version = "0.3.6" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a7f3f92a1da3d6b1d32245d0cbcbbab0cfc45996d8df619c42bccfa6d2bbb5f" +checksum = "ef33d6d0cd06e0840fba9985aab098c147e67e05cee14d412d3345ed14ff30ac" dependencies = [ "libc", "signal-hook-registry", @@ -5785,26 +5776,27 @@ dependencies = [ "env_logger 0.8.3", "eth1", "eth1_test_rig", - "futures 0.3.13", + "futures 0.3.14", "node_test_rig", "parking_lot", "rayon", - "tokio 1.2.0", + "sensitive_url", + "tokio 1.5.0", "types", "validator_client", ] [[package]] name = "siphasher" -version = "0.3.3" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa8f3741c7372e75519bd9346068370c9cdaabcc1f9599cbcf2a2719352286b7" +checksum = "cbce6d4507c7e4a3962091436e56e95290cb71fa302d0d270e32130b75fbff27" [[package]] name = "slab" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" +checksum = "f173ac3d1a7e3b28003f40de0b5ce7fe2710f9b9dc3fc38664cebee46b3b6527" [[package]] name = "slasher" @@ -5847,7 +5839,7 @@ dependencies = [ "slot_clock", "state_processing", "task_executor", - "tokio 1.2.0", + "tokio 1.5.0", "tokio-stream", "types", ] @@ -5993,9 +5985,9 @@ checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e" [[package]] name = "snap" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc725476a1398f0480d56cd0ad381f6f32acf2642704456f8f59a35df464b59a" +checksum = "45456094d1983e2ee2a18fdfebce3189fa451699d0502cb8e3b49dba5ba41451" [[package]] name = "snow" @@ -6026,6 +6018,16 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "socket2" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e3dfc207c526015c632472a77be09cf1b6e46866581aecae5cc38fb4235dea2" +dependencies = [ + "libc", + "winapi 0.3.9", +] + [[package]] name = "soketto" version = "0.4.2" @@ -6035,7 +6037,7 @@ dependencies = [ "base64 0.12.3", "bytes 0.5.6", "flate2", - "futures 0.3.13", + "futures 0.3.14", "httparse", "log", "rand 0.7.3", @@ -6048,20 +6050,11 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" -[[package]] -name = "spinning_top" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e529d73e80d64b5f2631f9035113347c578a1c9c7774b83a2b880788459ab36" -dependencies = [ - "lock_api", -] - [[package]] name = "standback" -version = "0.2.15" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2beb4d1860a61f571530b3f855a1b538d0200f7871c63331ecd6f17b1f014f8" +checksum = "e113fb6f3de07a243d434a56ec6f186dfd51cb08448239fe7bcae73f87ff28ff" dependencies = [ "version_check", ] @@ -6276,9 +6269,9 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.70" +version = "1.0.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9505f307c872bab8eb46f77ae357c8eba1fdacead58ee5a850116b1d7f82883" +checksum = "ad184cc9470f9117b2ac6817bfe297307418819ba40552f9b3846f05c33d5373" dependencies = [ "proc-macro2", "quote", @@ -6320,11 +6313,11 @@ name = "task_executor" version = "0.1.0" dependencies = [ "exit-future", - "futures 0.3.13", + "futures 0.3.14", "lazy_static", "lighthouse_metrics", "slog", - "tokio 1.2.0", + "tokio 1.5.0", ] [[package]] @@ -6336,7 +6329,7 @@ dependencies = [ "cfg-if 1.0.0", "libc", "rand 0.8.3", - "redox_syscall 0.2.5", + "redox_syscall 0.2.7", "remove_dir_all", "winapi 0.3.9", ] @@ -6439,9 +6432,9 @@ dependencies = [ [[package]] name = "time" -version = "0.2.25" +version = "0.2.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1195b046942c221454c2539395f85413b33383a067449d78aab2b7b052a142f7" +checksum = "08a8cbfbf47955132d0202d1662f49b2423ae35862aee471f3ba4b133358f372" dependencies = [ "const_fn", "libc", @@ -6480,12 +6473,12 @@ name = "timer" version = "0.2.0" dependencies = [ "beacon_chain", - "futures 0.3.13", + "futures 0.3.14", "parking_lot", "slog", "slot_clock", "task_executor", - "tokio 1.2.0", + "tokio 1.5.0", "types", ] @@ -6537,9 +6530,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.1.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "317cca572a0e89c3ce0ca1f1bdc9369547fe318a683418e42ac8f59d14701023" +checksum = "5b5220f05bb7de7f3f53c7c065e1199b3172696fe2db9f9c4d8ad9b4ee74c342" dependencies = [ "tinyvec_macros", ] @@ -6587,15 +6580,15 @@ dependencies = [ [[package]] name = "tokio" -version = "1.2.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8190d04c665ea9e6b6a0dc45523ade572c088d2e6566244c1122671dbf4ae3a" +checksum = "83f0c8e7c0addab50b663055baf787d0af7f413a46e6e7fb9559a4e4db7137a5" dependencies = [ "autocfg 1.0.1", "bytes 1.0.1", "libc", "memchr", - "mio 0.7.9", + "mio 0.7.11", "num_cpus", "once_cell", "parking_lot", @@ -6625,7 +6618,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90c49f106be240de154571dd31fbe48acb10ba6c6dd6f6517ad603abffa42de9" dependencies = [ "pin-project-lite 0.2.6", - "tokio 1.2.0", + "tokio 1.5.0", ] [[package]] @@ -6657,19 +6650,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b" dependencies = [ "native-tls", - "tokio 1.2.0", + "tokio 1.5.0", ] [[package]] name = "tokio-stream" -version = "0.1.3" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1981ad97df782ab506a1f43bf82c967326960d278acf3bf8279809648c3ff3ea" +checksum = "e177a5d8c3bf36de9ebe6d58537d8879e964332f93fb3339e43f618c81361af0" dependencies = [ "futures-core", "pin-project-lite 0.2.6", - "tokio 1.2.0", - "tokio-util 0.6.3", + "tokio 1.5.0", + "tokio-util 0.6.6", ] [[package]] @@ -6690,8 +6683,8 @@ checksum = "e1a5f475f1b9d077ea1017ecbc60890fda8e54942d680ca0b1d2b47cfa2d861b" dependencies = [ "futures-util", "log", - "pin-project 1.0.5", - "tokio 1.2.0", + "pin-project 1.0.7", + "tokio 1.5.0", "tungstenite", ] @@ -6726,9 +6719,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.6.3" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebb7cb2f00c5ae8df755b252306272cd1790d39728363936e01827e11f0b017b" +checksum = "940a12c99365c31ea8dd9ba04ec1be183ffe4920102bb7122c2f515437601e8e" dependencies = [ "bytes 1.0.1", "futures-core", @@ -6737,7 +6730,7 @@ dependencies = [ "log", "pin-project-lite 0.2.6", "slab", - "tokio 1.2.0", + "tokio 1.5.0", ] [[package]] @@ -6757,9 +6750,9 @@ checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6" [[package]] name = "tracing" -version = "0.1.25" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01ebdc2bb4498ab1ab5f5b73c5803825e60199229ccba0698170e3be0e7f959f" +checksum = "09adeb8c97449311ccd28a427f96fb563e7fd31aabf994189879d9da2394b89d" dependencies = [ "cfg-if 1.0.0", "log", @@ -6770,9 +6763,9 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.13" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8a9bd1db7706f2373a190b0d067146caa39350c486f3d455b0e33b431f94c07" +checksum = "c42e6fa53307c8a17e4ccd4dc81cf5ec38db9209f59b222210375b54ee40d1e2" dependencies = [ "proc-macro2", "quote", @@ -6781,9 +6774,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.17" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f50de3927f93d202783f4513cda820ab47ef17f624b03c096e86ef00c67e6b5f" +checksum = "a9ff14f98b1a4b289c6248a023c1c2fa1491062964e9fed67ab29c4e4da4a052" dependencies = [ "lazy_static", ] @@ -6794,7 +6787,7 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" dependencies = [ - "pin-project 1.0.5", + "pin-project 1.0.7", "tracing", ] @@ -6821,9 +6814,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.2.16" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ab8966ac3ca27126141f7999361cc97dd6fb4b71da04c02044fa9045d98bb96" +checksum = "aa5553bf0883ba7c9cbe493b085c29926bd41b66afc31ff72cf17ff4fb60dcd5" dependencies = [ "ansi_term 0.12.1", "chrono", @@ -6843,9 +6836,9 @@ dependencies = [ [[package]] name = "trackable" -version = "1.0.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30fb6e13d129dd92c501458f64d56c708e3685e3fd307e878ec5f934c5c5bdb0" +checksum = "017e2a1a93718e4e8386d037cfb8add78f1d690467f4350fb582f55af1203167" dependencies = [ "trackable_derive", ] @@ -6931,9 +6924,9 @@ dependencies = [ [[package]] name = "typenum" -version = "1.12.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33" +checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06" [[package]] name = "types" @@ -7010,9 +7003,9 @@ dependencies = [ [[package]] name = "unicode-bidi" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" +checksum = "eeb8be209bb1c96b7c177c7420d26e04eccacb0eeae6b980e35fcb74678107e0" dependencies = [ "matches", ] @@ -7040,9 +7033,9 @@ checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" [[package]] name = "unicode-xid" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" [[package]] name = "universal-hash" @@ -7067,7 +7060,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "35581ff83d4101e58b582e607120c7f5ffb17e632a980b1f38334d76b36908b2" dependencies = [ "bytes 1.0.1", - "tokio-util 0.6.3", + "tokio-util 0.6.6", ] [[package]] @@ -7100,9 +7093,9 @@ dependencies = [ [[package]] name = "utf-8" -version = "0.7.5" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05e42f7c18b8f902290b009cde6d651262f956c98bc51bca4cd1d511c9cd85c7" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" [[package]] name = "uuid" @@ -7125,7 +7118,7 @@ dependencies = [ "clap_utils", "deposit_contract", "directory", - "dirs 3.0.1", + "dirs 3.0.2", "environment", "eth2", "eth2_config", @@ -7135,9 +7128,9 @@ dependencies = [ "eth2_ssz_derive", "exit-future", "fallback", - "futures 0.3.13", + "futures 0.3.14", "hex", - "hyper 0.14.4", + "hyper 0.14.7", "lazy_static", "libc", "libsecp256k1", @@ -7151,6 +7144,7 @@ dependencies = [ "ring", "safe_arith", "scrypt", + "sensitive_url", "serde", "serde_derive", "serde_json", @@ -7162,7 +7156,7 @@ dependencies = [ "slog-term", "slot_clock", "tempfile", - "tokio 1.2.0", + "tokio 1.5.0", "tree_hash", "types", "validator_dir", @@ -7199,15 +7193,9 @@ dependencies = [ [[package]] name = "vcpkg" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b00bca6106a5e23f3eee943593759b7fcddb00554332e856d990c893966879fb" - -[[package]] -name = "vec-arena" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eafc1b9b2dfc6f5529177b62cf806484db55b32dc7c9658a118e11bbeb33061d" +checksum = "cbdbff6266a24120518560b5dc983096efb98462e51d0d68169895b237be3e5d" [[package]] name = "vec_map" @@ -7217,9 +7205,9 @@ checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" [[package]] name = "version_check" -version = "0.9.2" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" +checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" [[package]] name = "void" @@ -7235,9 +7223,9 @@ checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" [[package]] name = "walkdir" -version = "2.3.1" +version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d" +checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" dependencies = [ "same-file", "winapi 0.3.9", @@ -7260,24 +7248,24 @@ version = "0.3.0" source = "git+https://github.com/paulhauner/warp?branch=cors-wildcard#1f7daf462e6286fe5fd1743f7b788227efd3fa5c" dependencies = [ "bytes 1.0.1", - "futures 0.3.13", + "futures 0.3.14", "headers", "http", - "hyper 0.14.4", + "hyper 0.14.7", "log", "mime", "mime_guess", "multipart", "percent-encoding", - "pin-project 1.0.5", + "pin-project 1.0.7", "scoped-tls", "serde", "serde_json", "serde_urlencoded", - "tokio 1.2.0", + "tokio 1.5.0", "tokio-stream", "tokio-tungstenite", - "tokio-util 0.6.3", + "tokio-util 0.6.6", "tower-service", "tracing", "tracing-futures", @@ -7295,7 +7283,7 @@ dependencies = [ "safe_arith", "serde", "state_processing", - "tokio 1.2.0", + "tokio 1.5.0", "types", "warp", ] @@ -7314,9 +7302,9 @@ checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" [[package]] name = "wasm-bindgen" -version = "0.2.71" +version = "0.2.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ee1280240b7c461d6a0071313e08f34a60b0365f14260362e5a2b17d1d31aa7" +checksum = "83240549659d187488f91f33c0f8547cbfef0b2088bc470c116d1d260ef623d9" dependencies = [ "cfg-if 1.0.0", "serde", @@ -7326,9 +7314,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.71" +version = "0.2.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b7d8b6942b8bb3a9b0e73fc79b98095a27de6fa247615e59d096754a3bc2aa8" +checksum = "ae70622411ca953215ca6d06d3ebeb1e915f0f6613e3b495122878d7ebec7dae" dependencies = [ "bumpalo", "lazy_static", @@ -7341,9 +7329,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.21" +version = "0.4.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e67a5806118af01f0d9045915676b22aaebecf4178ae7021bc171dab0b897ab" +checksum = "81b8b767af23de6ac18bf2168b690bed2902743ddf0fb39252e36f9e2bfc63ea" dependencies = [ "cfg-if 1.0.0", "js-sys", @@ -7353,9 +7341,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.71" +version = "0.2.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5ac38da8ef716661f0f36c0d8320b89028efe10c7c0afde65baffb496ce0d3b" +checksum = "3e734d91443f177bfdb41969de821e15c516931c3c3db3d318fa1b68975d0f6f" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -7363,9 +7351,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.71" +version = "0.2.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc053ec74d454df287b9374ee8abb36ffd5acb95ba87da3ba5b7d3fe20eb401e" +checksum = "d53739ff08c8a68b0fdbcd54c372b8ab800b1449ab3c9d706503bc7dd1621b2c" dependencies = [ "proc-macro2", "quote", @@ -7376,15 +7364,15 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.71" +version = "0.2.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d6f8ec44822dd71f5f221a5847fb34acd9060535c1211b70a05844c0f6383b1" +checksum = "d9a543ae66aa233d14bb765ed9af4a33e81b8b58d1584cf1b47ff8cd0b9e4489" [[package]] name = "wasm-bindgen-test" -version = "0.3.21" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ea9e4f0050d5498a160e6b9d278a9699598e445b51dacd05598da55114c801a" +checksum = "e972e914de63aa53bd84865e54f5c761bd274d48e5be3a6329a662c0386aa67a" dependencies = [ "console_error_panic_hook", "js-sys", @@ -7396,9 +7384,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-test-macro" -version = "0.3.21" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43f40402f495d92df6cdd0d329e7cc2580c8f99bcd74faff0e468923a764b7d4" +checksum = "ea6153a8f9bf24588e9f25c87223414fff124049f68d3a442a0f0eab4768a8b6" dependencies = [ "proc-macro2", "quote", @@ -7410,7 +7398,7 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "be0ecb0db480561e9a7642b5d3e4187c128914e58aa84330b9493e3eb68c5e7f" dependencies = [ - "futures 0.3.13", + "futures 0.3.14", "js-sys", "parking_lot", "pin-utils", @@ -7421,9 +7409,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.48" +version = "0.3.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec600b26223b2948cedfde2a0aa6756dcf1fef616f43d7b3097aaf53a6c4d92b" +checksum = "a905d57e488fec8861446d3393670fb50d27a262344013181c2cdf9fff5481be" dependencies = [ "js-sys", "wasm-bindgen", @@ -7441,7 +7429,7 @@ dependencies = [ "derive_more", "ethabi", "ethereum-types", - "futures 0.3.13", + "futures 0.3.14", "futures-timer", "hex", "hyper 0.13.10", @@ -7451,7 +7439,7 @@ dependencies = [ "log", "native-tls", "parking_lot", - "pin-project 1.0.5", + "pin-project 1.0.7", "rlp 0.4.6", "secp256k1", "serde", @@ -7476,9 +7464,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.21.0" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82015b7e0b8bad8185994674a13a93306bea76cf5a16c5a181382fd3a5ec2376" +checksum = "aabe153544e473b775453675851ecc86863d2a81d786d741f6b76778f2a48940" dependencies = [ "webpki", ] @@ -7494,12 +7482,12 @@ dependencies = [ [[package]] name = "which" -version = "4.0.2" +version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87c14ef7e1b8b8ecfc75d5eca37949410046e66f15d185c01d70824f1f8111ef" +checksum = "b55551e42cbdf2ce2bedd2203d0cc08dba002c27510f86dab6d0ce304cba3dfe" dependencies = [ + "either", "libc", - "thiserror", ] [[package]] @@ -7572,9 +7560,9 @@ checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214" [[package]] name = "x25519-dalek" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc614d95359fd7afc321b66d2107ede58b246b844cf5d8a0adcca413e439f088" +checksum = "5a0c105152107e3b96f6a00a65e86ce82d9b125230e1c4302940eca58ff71f4f" dependencies = [ "curve25519-dalek", "rand_core 0.5.1", @@ -7589,9 +7577,9 @@ checksum = "b07db065a5cf61a7e4ba64f29e67db906fb1787316516c4e6e5ff0fea1efcd8a" [[package]] name = "xmltree" -version = "0.10.2" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d046fd42d4137234742eae0d05b4fb6fbdda9aed7c78e523ae890fd87c7e11dd" +checksum = "d7d8a75eaf6557bb84a65ace8609883db44a29951042ada9b393151532e41fcb" dependencies = [ "xml-rs", ] @@ -7611,7 +7599,7 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1cc7bd8c983209ed5d527f44b01c41b7dc146fd960c61cf9e1d25399841dc271" dependencies = [ - "futures 0.3.13", + "futures 0.3.14", "log", "nohash-hasher", "parking_lot", @@ -7621,18 +7609,18 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81a974bcdd357f0dca4d41677db03436324d45a4c9ed2d0b873a5a360ce41c36" +checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd" dependencies = [ "zeroize_derive", ] [[package]] name = "zeroize_derive" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3f369ddb18862aba61aa49bf31e74d29f0f162dec753063200e1dc084345d16" +checksum = "a2c1e130bebaeab2f23886bf9acbaca14b092408c452543c857f66399cd6dab1" dependencies = [ "proc-macro2", "quote", @@ -7642,9 +7630,9 @@ dependencies = [ [[package]] name = "zip" -version = "0.5.11" +version = "0.5.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8264fcea9b7a036a4a5103d7153e988dbc2ebbafb34f68a3c2d404b6b82d74b6" +checksum = "9c83dc9b784d252127720168abd71ea82bf8c3d96b17dc565b5e2a02854f2b27" dependencies = [ "byteorder", "bzip2", diff --git a/Cargo.toml b/Cargo.toml index 8fd60b5ab64..c1c4cfd497b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,6 +33,7 @@ members = [ "common/logging", "common/lru_cache", "common/remote_signer_consumer", + "common/sensitive_url", "common/slot_clock", "common/task_executor", "common/test_random_derive", diff --git a/account_manager/Cargo.toml b/account_manager/Cargo.toml index 93b06c18aee..5cd5d03988b 100644 --- a/account_manager/Cargo.toml +++ b/account_manager/Cargo.toml @@ -34,6 +34,7 @@ slashing_protection = { path = "../validator_client/slashing_protection" } eth2 = {path = "../common/eth2"} safe_arith = {path = "../consensus/safe_arith"} slot_clock = { path = "../common/slot_clock" } +sensitive_url = { path = "../common/sensitive_url" } [dev-dependencies] tempfile = "3.1.0" diff --git a/account_manager/src/validator/exit.rs b/account_manager/src/validator/exit.rs index bbdd629fefe..8c7ba761a35 100644 --- a/account_manager/src/validator/exit.rs +++ b/account_manager/src/validator/exit.rs @@ -4,11 +4,12 @@ use clap::{App, Arg, ArgMatches}; use environment::Environment; use eth2::{ types::{GenesisData, StateId, ValidatorData, ValidatorId, ValidatorStatus}, - BeaconNodeHttpClient, Url, + BeaconNodeHttpClient, }; use eth2_keystore::Keystore; use eth2_network_config::Eth2NetworkConfig; use safe_arith::SafeArith; +use sensitive_url::SensitiveUrl; use slot_clock::{SlotClock, SystemTimeSlotClock}; use std::path::{Path, PathBuf}; use std::time::Duration; @@ -75,7 +76,7 @@ pub fn cli_run(matches: &ArgMatches, env: Environment) -> Result< let spec = env.eth2_config().spec.clone(); let server_url: String = clap_utils::parse_required(matches, BEACON_SERVER_FLAG)?; let client = BeaconNodeHttpClient::new( - Url::parse(&server_url) + SensitiveUrl::parse(&server_url) .map_err(|e| format!("Failed to parse beacon http server: {:?}", e))?, ); diff --git a/beacon_node/Cargo.toml b/beacon_node/Cargo.toml index 1661a255e3e..f4a901dc269 100644 --- a/beacon_node/Cargo.toml +++ b/beacon_node/Cargo.toml @@ -44,3 +44,4 @@ hyper = "0.14.4" lighthouse_version = { path = "../common/lighthouse_version" } hex = "0.4.2" slasher = { path = "../slasher" } +sensitive_url = { path = "../common/sensitive_url" } diff --git a/beacon_node/beacon_chain/src/beacon_chain.rs b/beacon_node/beacon_chain/src/beacon_chain.rs index 1ef370f14c4..ea85c5457aa 100644 --- a/beacon_node/beacon_chain/src/beacon_chain.rs +++ b/beacon_node/beacon_chain/src/beacon_chain.rs @@ -58,6 +58,7 @@ use std::sync::Arc; use std::time::{Duration, Instant}; use store::iter::{BlockRootsIterator, ParentRootBlockIterator, StateRootsIterator}; use store::{Error as DBError, HotColdDB, KeyValueStore, KeyValueStoreOp, StoreItem, StoreOp}; +use task_executor::ShutdownReason; use types::beacon_state::CloneConfig; use types::*; @@ -254,7 +255,7 @@ pub struct BeaconChain { pub disabled_forks: Vec, /// Sender given to tasks, so that if they encounter a state in which execution cannot /// continue they can request that everything shuts down. - pub shutdown_sender: Sender<&'static str>, + pub shutdown_sender: Sender, /// Logging to CLI, etc. pub(crate) log: Logger, /// Arbitrary bytes included in the blocks. @@ -1695,7 +1696,10 @@ impl BeaconChain { "error" => ?e, ); crit!(self.log, "You must use the `--purge-db` flag to clear the database and restart sync. You may be on a hostile network."); - shutdown_sender.try_send("Weak subjectivity checkpoint verification failed. Provided block root is not a checkpoint.") + shutdown_sender + .try_send(ShutdownReason::Failure( + "Weak subjectivity checkpoint verification failed. Provided block root is not a checkpoint." + )) .map_err(|err| BlockError::BeaconChainError(BeaconChainError::WeakSubjectivtyShutdownError(err)))?; return Err(BlockError::WeakSubjectivityConflict); } @@ -2825,7 +2829,7 @@ impl BeaconChain { } /// Get a channel to request shutting down. - pub fn shutdown_sender(&self) -> Sender<&'static str> { + pub fn shutdown_sender(&self) -> Sender { self.shutdown_sender.clone() } diff --git a/beacon_node/beacon_chain/src/builder.rs b/beacon_node/beacon_chain/src/builder.rs index d8afeb1c619..efc6865b370 100644 --- a/beacon_node/beacon_chain/src/builder.rs +++ b/beacon_node/beacon_chain/src/builder.rs @@ -25,6 +25,7 @@ use std::marker::PhantomData; use std::sync::Arc; use std::time::Duration; use store::{HotColdDB, ItemStore}; +use task_executor::ShutdownReason; use types::{ BeaconBlock, BeaconState, ChainSpec, EthSpec, Graffiti, Hash256, PublicKeyBytes, Signature, SignedBeaconBlock, Slot, @@ -75,7 +76,7 @@ pub struct BeaconChainBuilder { eth1_chain: Option>, event_handler: Option>, slot_clock: Option, - shutdown_sender: Option>, + shutdown_sender: Option>, head_tracker: Option, validator_pubkey_cache: Option>, spec: ChainSpec, @@ -305,8 +306,8 @@ where })?; let genesis = BeaconSnapshot { - beacon_block_root, beacon_block, + beacon_block_root, beacon_state, }; @@ -349,7 +350,7 @@ where } /// Sets a `Sender` to allow the beacon chain to send shutdown signals. - pub fn shutdown_sender(mut self, sender: Sender<&'static str>) -> Self { + pub fn shutdown_sender(mut self, sender: Sender) -> Self { self.shutdown_sender = Some(sender); self } diff --git a/beacon_node/beacon_chain/src/errors.rs b/beacon_node/beacon_chain/src/errors.rs index 1f5662a62ce..9c47904dda1 100644 --- a/beacon_node/beacon_chain/src/errors.rs +++ b/beacon_node/beacon_chain/src/errors.rs @@ -21,6 +21,7 @@ use state_processing::{ BlockProcessingError, SlotProcessingError, }; use std::time::Duration; +use task_executor::ShutdownReason; use types::*; macro_rules! easy_from_to { @@ -96,7 +97,7 @@ pub enum BeaconChainError { head_block_epoch: Epoch, }, WeakSubjectivtyVerificationFailure, - WeakSubjectivtyShutdownError(TrySendError<&'static str>), + WeakSubjectivtyShutdownError(TrySendError), AttestingPriorToHead { head_slot: Slot, request_slot: Slot, diff --git a/beacon_node/beacon_chain/src/eth1_chain.rs b/beacon_node/beacon_chain/src/eth1_chain.rs index 921c0475e85..8d316691496 100644 --- a/beacon_node/beacon_chain/src/eth1_chain.rs +++ b/beacon_node/beacon_chain/src/eth1_chain.rs @@ -613,11 +613,9 @@ fn collect_valid_votes( .eth1_data_votes() .iter() .filter_map(|vote| { - if let Some(block_num) = votes_to_consider.get(vote) { - Some((vote.clone(), *block_num)) - } else { - None - } + votes_to_consider + .get(vote) + .map(|block_num| (vote.clone(), *block_num)) }) .for_each(|(eth1_data, block_number)| { valid_votes diff --git a/beacon_node/beacon_chain/src/test_utils.rs b/beacon_node/beacon_chain/src/test_utils.rs index 449dcefd4bf..f53969ab866 100644 --- a/beacon_node/beacon_chain/src/test_utils.rs +++ b/beacon_node/beacon_chain/src/test_utils.rs @@ -28,6 +28,7 @@ use std::collections::{HashMap, HashSet}; use std::sync::Arc; use std::time::Duration; use store::{config::StoreConfig, BlockReplay, HotColdDB, ItemStore, LevelDB, MemoryStore}; +use task_executor::ShutdownReason; use tempfile::{tempdir, TempDir}; use tree_hash::TreeHash; use types::{ @@ -144,7 +145,7 @@ pub struct BeaconChainHarness { pub chain: BeaconChain, pub spec: ChainSpec, pub data_dir: TempDir, - pub shutdown_receiver: Receiver<&'static str>, + pub shutdown_receiver: Receiver, pub rng: Mutex, } diff --git a/beacon_node/eth1/Cargo.toml b/beacon_node/eth1/Cargo.toml index bf4835d7104..618b59676af 100644 --- a/beacon_node/eth1/Cargo.toml +++ b/beacon_node/eth1/Cargo.toml @@ -34,3 +34,4 @@ lazy_static = "1.4.0" task_executor = { path = "../../common/task_executor" } eth2 = { path = "../../common/eth2" } fallback = { path = "../../common/fallback" } +sensitive_url = { path = "../../common/sensitive_url" } diff --git a/beacon_node/eth1/src/http.rs b/beacon_node/eth1/src/http.rs index 88e322244d4..9ec7576d284 100644 --- a/beacon_node/eth1/src/http.rs +++ b/beacon_node/eth1/src/http.rs @@ -12,6 +12,7 @@ use futures::future::TryFutureExt; use reqwest::{header::CONTENT_TYPE, ClientBuilder, StatusCode}; +use sensitive_url::SensitiveUrl; use serde::{Deserialize, Serialize}; use serde_json::{json, Value}; use std::ops::Range; @@ -72,14 +73,14 @@ impl FromStr for Eth1Id { type Err = String; fn from_str(s: &str) -> Result { - u64::from_str_radix(s, 10) + s.parse::() .map(Into::into) .map_err(|e| format!("Failed to parse eth1 network id {}", e)) } } /// Get the eth1 network id of the given endpoint. -pub async fn get_network_id(endpoint: &str, timeout: Duration) -> Result { +pub async fn get_network_id(endpoint: &SensitiveUrl, timeout: Duration) -> Result { let response_body = send_rpc_request(endpoint, "net_version", json!([]), timeout).await?; Eth1Id::from_str( response_result(&response_body)? @@ -90,7 +91,7 @@ pub async fn get_network_id(endpoint: &str, timeout: Duration) -> Result Result { +pub async fn get_chain_id(endpoint: &SensitiveUrl, timeout: Duration) -> Result { let response_body = send_rpc_request(endpoint, "eth_chainId", json!([]), timeout).await?; hex_to_u64_be( response_result(&response_body)? @@ -111,7 +112,7 @@ pub struct Block { /// Returns the current block number. /// /// Uses HTTP JSON RPC at `endpoint`. E.g., `http://localhost:8545`. -pub async fn get_block_number(endpoint: &str, timeout: Duration) -> Result { +pub async fn get_block_number(endpoint: &SensitiveUrl, timeout: Duration) -> Result { let response_body = send_rpc_request(endpoint, "eth_blockNumber", json!([]), timeout).await?; hex_to_u64_be( response_result(&response_body)? @@ -126,7 +127,7 @@ pub async fn get_block_number(endpoint: &str, timeout: Duration) -> Result Result { @@ -191,7 +192,7 @@ pub async fn get_block( /// /// Uses HTTP JSON RPC at `endpoint`. E.g., `http://localhost:8545`. pub async fn get_deposit_count( - endpoint: &str, + endpoint: &SensitiveUrl, address: &str, block_number: u64, timeout: Duration, @@ -229,7 +230,7 @@ pub async fn get_deposit_count( /// /// Uses HTTP JSON RPC at `endpoint`. E.g., `http://localhost:8545`. pub async fn get_deposit_root( - endpoint: &str, + endpoint: &SensitiveUrl, address: &str, block_number: u64, timeout: Duration, @@ -266,7 +267,7 @@ pub async fn get_deposit_root( /// /// Uses HTTP JSON RPC at `endpoint`. E.g., `http://localhost:8545`. async fn call( - endpoint: &str, + endpoint: &SensitiveUrl, address: &str, hex_data: &str, block_number: u64, @@ -308,7 +309,7 @@ pub struct Log { /// /// Uses HTTP JSON RPC at `endpoint`. E.g., `http://localhost:8545`. pub async fn get_deposit_logs_in_range( - endpoint: &str, + endpoint: &SensitiveUrl, address: &str, block_height_range: Range, timeout: Duration, @@ -353,7 +354,7 @@ pub async fn get_deposit_logs_in_range( /// /// Tries to receive the response and parse the body as a `String`. pub async fn send_rpc_request( - endpoint: &str, + endpoint: &SensitiveUrl, method: &str, params: Value, timeout: Duration, @@ -374,7 +375,7 @@ pub async fn send_rpc_request( .timeout(timeout) .build() .expect("The builder should always build a client") - .post(endpoint) + .post(endpoint.full.clone()) .header(CONTENT_TYPE, "application/json") .body(body) .send() diff --git a/beacon_node/eth1/src/service.rs b/beacon_node/eth1/src/service.rs index 55aae3b6c3c..0584a4b71be 100644 --- a/beacon_node/eth1/src/service.rs +++ b/beacon_node/eth1/src/service.rs @@ -11,6 +11,7 @@ use crate::{ use fallback::{Fallback, FallbackError}; use futures::future::TryFutureExt; use parking_lot::{RwLock, RwLockReadGuard}; +use sensitive_url::SensitiveUrl; use serde::{Deserialize, Serialize}; use slog::{crit, debug, error, info, trace, warn, Logger}; use std::fmt::Debug; @@ -26,6 +27,8 @@ use types::{ChainSpec, EthSpec, Unsigned}; pub const DEFAULT_NETWORK_ID: Eth1Id = Eth1Id::Goerli; /// Indicates the default eth1 chain id we use for the deposit contract. pub const DEFAULT_CHAIN_ID: Eth1Id = Eth1Id::Goerli; +/// Indicates the default eth1 endpoint. +pub const DEFAULT_ETH1_ENDPOINT: &str = "http://localhost:8545"; const STANDARD_TIMEOUT_MILLIS: u64 = 15_000; @@ -51,7 +54,7 @@ pub enum EndpointError { type EndpointState = Result<(), EndpointError>; -type EndpointWithState = (String, TRwLock>); +type EndpointWithState = (SensitiveUrl, TRwLock>); /// A cache structure to lazily check usability of endpoints. An endpoint is usable if it is /// reachable and has the correct network id and chain id. Emits a `WARN` log if a checked endpoint @@ -74,7 +77,10 @@ impl EndpointsCache { if let Some(result) = *value { return result; } - crate::metrics::inc_counter_vec(&crate::metrics::ENDPOINT_REQUESTS, &[&endpoint.0]); + crate::metrics::inc_counter_vec( + &crate::metrics::ENDPOINT_REQUESTS, + &[&endpoint.0.to_string()], + ); let state = endpoint_state( &endpoint.0, &self.config_network_id, @@ -84,7 +90,10 @@ impl EndpointsCache { .await; *value = Some(state); if state.is_err() { - crate::metrics::inc_counter_vec(&crate::metrics::ENDPOINT_ERRORS, &[&endpoint.0]); + crate::metrics::inc_counter_vec( + &crate::metrics::ENDPOINT_ERRORS, + &[&endpoint.0.to_string()], + ); } state } @@ -94,7 +103,7 @@ impl EndpointsCache { func: F, ) -> Result> where - F: Fn(&'a str) -> R, + F: Fn(&'a SensitiveUrl) -> R, R: Future>, { let func = &func; @@ -102,7 +111,7 @@ impl EndpointsCache { .first_success(|endpoint| async move { match self.state(endpoint).await { Ok(()) => { - let endpoint_str = &endpoint.0; + let endpoint_str = &endpoint.0.to_string(); crate::metrics::inc_counter_vec( &crate::metrics::ENDPOINT_REQUESTS, &[endpoint_str], @@ -131,7 +140,7 @@ impl EndpointsCache { /// Returns `Ok` if the endpoint is usable, i.e. is reachable and has a correct network id and /// chain id. Otherwise it returns `Err`. async fn endpoint_state( - endpoint: &str, + endpoint: &SensitiveUrl, config_network_id: &Eth1Id, config_chain_id: &Eth1Id, log: &Logger, @@ -140,7 +149,7 @@ async fn endpoint_state( warn!( log, "Error connecting to eth1 node endpoint"; - "endpoint" => endpoint, + "endpoint" => %endpoint, "action" => "trying fallbacks" ); EndpointError::NotReachable @@ -152,7 +161,7 @@ async fn endpoint_state( warn!( log, "Invalid eth1 network id on endpoint. Please switch to correct network id"; - "endpoint" => endpoint, + "endpoint" => %endpoint, "action" => "trying fallbacks", "expected" => format!("{:?}",config_network_id), "received" => format!("{:?}",network_id), @@ -168,7 +177,7 @@ async fn endpoint_state( warn!( log, "Remote eth1 node is not synced"; - "endpoint" => endpoint, + "endpoint" => %endpoint, "action" => "trying fallbacks" ); return Err(EndpointError::FarBehind); @@ -177,7 +186,7 @@ async fn endpoint_state( warn!( log, "Invalid eth1 chain id. Please switch to correct chain id on endpoint"; - "endpoint" => endpoint, + "endpoint" => %endpoint, "action" => "trying fallbacks", "expected" => format!("{:?}",config_chain_id), "received" => format!("{:?}", chain_id), @@ -198,7 +207,7 @@ pub enum HeadType { /// Returns the head block and the new block ranges relevant for deposits and the block cache /// from the given endpoint. async fn get_remote_head_and_new_block_ranges( - endpoint: &str, + endpoint: &SensitiveUrl, service: &Service, node_far_behind_seconds: u64, ) -> Result< @@ -218,7 +227,7 @@ async fn get_remote_head_and_new_block_ranges( warn!( service.log, "Eth1 endpoint is not synced"; - "endpoint" => endpoint, + "endpoint" => %endpoint, "last_seen_block_unix_timestamp" => remote_head_block.timestamp, "action" => "trying fallback" ); @@ -230,7 +239,7 @@ async fn get_remote_head_and_new_block_ranges( warn!( service.log, "Eth1 endpoint is not synced"; - "endpoint" => endpoint, + "endpoint" => %endpoint, "action" => "trying fallbacks" ); } @@ -252,7 +261,7 @@ async fn get_remote_head_and_new_block_ranges( /// Returns the range of new block numbers to be considered for the given head type from the given /// endpoint. async fn relevant_new_block_numbers_from_endpoint( - endpoint: &str, + endpoint: &SensitiveUrl, service: &Service, head_type: HeadType, ) -> Result>, SingleEndpointError> { @@ -319,7 +328,7 @@ pub struct DepositCacheUpdateOutcome { #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Config { /// An Eth1 node (e.g., Geth) running a HTTP JSON-RPC endpoint. - pub endpoints: Vec, + pub endpoints: Vec, /// The address the `BlockCache` and `DepositCache` should assume is the canonical deposit contract. pub deposit_contract_address: String, /// The eth1 network id where the deposit contract is deployed (Goerli/Mainnet). @@ -383,7 +392,8 @@ impl Config { impl Default for Config { fn default() -> Self { Self { - endpoints: vec!["http://localhost:8545".into()], + endpoints: vec![SensitiveUrl::parse(DEFAULT_ETH1_ENDPOINT) + .expect("The default Eth1 endpoint must always be a valid URL.")], deposit_contract_address: "0x0000000000000000000000000000000000000000".into(), network_id: DEFAULT_NETWORK_ID, chain_id: DEFAULT_CHAIN_ID, @@ -1137,7 +1147,7 @@ fn relevant_block_range( /// /// Performs three async calls to an Eth1 HTTP JSON RPC endpoint. async fn download_eth1_block( - endpoint: &str, + endpoint: &SensitiveUrl, cache: Arc, block_number_opt: Option, ) -> Result { @@ -1182,6 +1192,12 @@ mod tests { use super::*; use types::MainnetEthSpec; + #[test] + // Ensures the default config does not panic. + fn default_config() { + Config::default(); + } + #[test] fn serde_serialize() { let serialized = diff --git a/beacon_node/eth1/tests/test.rs b/beacon_node/eth1/tests/test.rs index db9b79f8ea9..3a503e78bfd 100644 --- a/beacon_node/eth1/tests/test.rs +++ b/beacon_node/eth1/tests/test.rs @@ -5,6 +5,7 @@ use eth1::{Config, Service}; use eth1::{DepositCache, DEFAULT_CHAIN_ID, DEFAULT_NETWORK_ID}; use eth1_test_rig::GanacheEth1Instance; use merkle_proof::verify_merkle_proof; +use sensitive_url::SensitiveUrl; use slog::Logger; use sloggers::{null::NullLoggerBuilder, Build}; use std::ops::Range; @@ -53,7 +54,7 @@ fn random_deposit_data() -> DepositData { /// Blocking operation to get the deposit logs from the `deposit_contract`. async fn blocking_deposit_logs(eth1: &GanacheEth1Instance, range: Range) -> Vec { get_deposit_logs_in_range( - ð1.endpoint(), + &SensitiveUrl::parse(eth1.endpoint().as_str()).unwrap(), ð1.deposit_contract.address(), range, timeout(), @@ -65,7 +66,7 @@ async fn blocking_deposit_logs(eth1: &GanacheEth1Instance, range: Range) -> /// Blocking operation to get the deposit root from the `deposit_contract`. async fn blocking_deposit_root(eth1: &GanacheEth1Instance, block_number: u64) -> Option { get_deposit_root( - ð1.endpoint(), + &SensitiveUrl::parse(eth1.endpoint().as_str()).unwrap(), ð1.deposit_contract.address(), block_number, timeout(), @@ -77,7 +78,7 @@ async fn blocking_deposit_root(eth1: &GanacheEth1Instance, block_number: u64) -> /// Blocking operation to get the deposit count from the `deposit_contract`. async fn blocking_deposit_count(eth1: &GanacheEth1Instance, block_number: u64) -> Option { get_deposit_count( - ð1.endpoint(), + &SensitiveUrl::parse(eth1.endpoint().as_str()).unwrap(), ð1.deposit_contract.address(), block_number, timeout(), @@ -119,7 +120,7 @@ mod eth1_cache { let service = Service::new( Config { - endpoints: vec![eth1.endpoint()], + endpoints: vec![SensitiveUrl::parse(eth1.endpoint().as_str()).unwrap()], deposit_contract_address: deposit_contract.address(), lowest_cached_block_number: initial_block_number, follow_distance, @@ -200,7 +201,7 @@ mod eth1_cache { let service = Service::new( Config { - endpoints: vec![eth1.endpoint()], + endpoints: vec![SensitiveUrl::parse(eth1.endpoint().as_str()).unwrap()], deposit_contract_address: deposit_contract.address(), lowest_cached_block_number: get_block_number(&web3).await, follow_distance: 0, @@ -255,7 +256,7 @@ mod eth1_cache { let service = Service::new( Config { - endpoints: vec![eth1.endpoint()], + endpoints: vec![SensitiveUrl::parse(eth1.endpoint().as_str()).unwrap()], deposit_contract_address: deposit_contract.address(), lowest_cached_block_number: get_block_number(&web3).await, follow_distance: 0, @@ -306,7 +307,7 @@ mod eth1_cache { let service = Service::new( Config { - endpoints: vec![eth1.endpoint()], + endpoints: vec![SensitiveUrl::parse(eth1.endpoint().as_str()).unwrap()], deposit_contract_address: deposit_contract.address(), lowest_cached_block_number: get_block_number(&web3).await, follow_distance: 0, @@ -359,7 +360,7 @@ mod deposit_tree { let service = Service::new( Config { - endpoints: vec![eth1.endpoint()], + endpoints: vec![SensitiveUrl::parse(eth1.endpoint().as_str()).unwrap()], deposit_contract_address: deposit_contract.address(), deposit_contract_deploy_block: start_block, follow_distance: 0, @@ -440,7 +441,7 @@ mod deposit_tree { let service = Service::new( Config { - endpoints: vec![eth1.endpoint()], + endpoints: vec![SensitiveUrl::parse(eth1.endpoint().as_str()).unwrap()], deposit_contract_address: deposit_contract.address(), deposit_contract_deploy_block: start_block, lowest_cached_block_number: start_block, @@ -582,7 +583,7 @@ mod http { async fn get_block(eth1: &GanacheEth1Instance, block_number: u64) -> Block { eth1::http::get_block( - ð1.endpoint(), + &SensitiveUrl::parse(eth1.endpoint().as_str()).unwrap(), BlockQuery::Number(block_number), timeout(), ) @@ -698,7 +699,7 @@ mod fast { let now = get_block_number(&web3).await; let service = Service::new( Config { - endpoints: vec![eth1.endpoint()], + endpoints: vec![SensitiveUrl::parse(eth1.endpoint().as_str()).unwrap()], deposit_contract_address: deposit_contract.address(), deposit_contract_deploy_block: now, lowest_cached_block_number: now, @@ -775,7 +776,7 @@ mod persist { let now = get_block_number(&web3).await; let config = Config { - endpoints: vec![eth1.endpoint()], + endpoints: vec![SensitiveUrl::parse(eth1.endpoint().as_str()).unwrap()], deposit_contract_address: deposit_contract.address(), deposit_contract_deploy_block: now, lowest_cached_block_number: now, @@ -885,7 +886,10 @@ mod fallbacks { let service = Service::new( Config { - endpoints: vec![endpoint1.endpoint(), endpoint2.endpoint()], + endpoints: vec![ + SensitiveUrl::parse(endpoint1.endpoint().as_str()).unwrap(), + SensitiveUrl::parse(endpoint2.endpoint().as_str()).unwrap(), + ], deposit_contract_address: deposit_contract.address(), lowest_cached_block_number: initial_block_number, follow_distance: 0, @@ -961,7 +965,10 @@ mod fallbacks { let service = Service::new( Config { - endpoints: vec![endpoint2.endpoint(), endpoint1.endpoint()], + endpoints: vec![ + SensitiveUrl::parse(endpoint2.endpoint().as_str()).unwrap(), + SensitiveUrl::parse(endpoint1.endpoint().as_str()).unwrap(), + ], deposit_contract_address: deposit_contract.address(), lowest_cached_block_number: initial_block_number, follow_distance: 0, @@ -1028,7 +1035,10 @@ mod fallbacks { let service = Service::new( Config { - endpoints: vec![endpoint2.endpoint(), endpoint1.endpoint()], + endpoints: vec![ + SensitiveUrl::parse(endpoint2.endpoint().as_str()).unwrap(), + SensitiveUrl::parse(endpoint1.endpoint().as_str()).unwrap(), + ], deposit_contract_address: deposit_contract.address(), lowest_cached_block_number: initial_block_number, follow_distance: 0, @@ -1081,7 +1091,10 @@ mod fallbacks { let service = Service::new( Config { - endpoints: vec![endpoint1.endpoint(), endpoint2.endpoint()], + endpoints: vec![ + SensitiveUrl::parse(endpoint1.endpoint().as_str()).unwrap(), + SensitiveUrl::parse(endpoint2.endpoint().as_str()).unwrap(), + ], deposit_contract_address: deposit_contract.address(), lowest_cached_block_number: initial_block_number, follow_distance: 0, diff --git a/beacon_node/eth2_libp2p/src/discovery/enr_ext.rs b/beacon_node/eth2_libp2p/src/discovery/enr_ext.rs index 30ace623ced..deb554c7f10 100644 --- a/beacon_node/eth2_libp2p/src/discovery/enr_ext.rs +++ b/beacon_node/eth2_libp2p/src/discovery/enr_ext.rs @@ -299,7 +299,7 @@ mod tests { let sk_bytes = hex::decode(sk_hex).unwrap(); let secret = discv5::enr::ed25519_dalek::SecretKey::from_bytes(&sk_bytes).unwrap(); let public = discv5::enr::ed25519_dalek::PublicKey::from(&secret); - let keypair = discv5::enr::ed25519_dalek::Keypair { public, secret }; + let keypair = discv5::enr::ed25519_dalek::Keypair { secret, public }; let libp2p_sk = libp2p::identity::ed25519::SecretKey::from_bytes(sk_bytes).unwrap(); let ed25519_kp: libp2p::identity::ed25519::Keypair = libp2p_sk.into(); diff --git a/beacon_node/eth2_libp2p/src/service.rs b/beacon_node/eth2_libp2p/src/service.rs index 079338b54f8..21c75836eb1 100644 --- a/beacon_node/eth2_libp2p/src/service.rs +++ b/beacon_node/eth2_libp2p/src/service.rs @@ -233,9 +233,9 @@ impl Service { } let service = Service { - local_peer_id, - bandwidth, swarm, + bandwidth, + local_peer_id, log, }; diff --git a/beacon_node/eth2_libp2p/src/types/topics.rs b/beacon_node/eth2_libp2p/src/types/topics.rs index 18efde34528..f8e2b676888 100644 --- a/beacon_node/eth2_libp2p/src/types/topics.rs +++ b/beacon_node/eth2_libp2p/src/types/topics.rs @@ -81,8 +81,8 @@ impl GossipTopic { pub fn new(kind: GossipKind, encoding: GossipEncoding, fork_digest: [u8; 4]) -> Self { GossipTopic { encoding, - kind, fork_digest, + kind, } } @@ -135,8 +135,8 @@ impl GossipTopic { return Ok(GossipTopic { encoding, - kind, fork_digest, + kind, }); } @@ -195,7 +195,10 @@ pub fn subnet_id_from_topic_hash(topic_hash: &TopicHash) -> Option { fn committee_topic_index(topic: &str) -> Option { if topic.starts_with(BEACON_ATTESTATION_PREFIX) { return Some(SubnetId::new( - u64::from_str_radix(topic.trim_start_matches(BEACON_ATTESTATION_PREFIX), 10).ok()?, + topic + .trim_start_matches(BEACON_ATTESTATION_PREFIX) + .parse::() + .ok()?, )); } None diff --git a/beacon_node/eth2_libp2p/tests/common/mod.rs b/beacon_node/eth2_libp2p/tests/common/mod.rs index e0aba71f655..a09f800d076 100644 --- a/beacon_node/eth2_libp2p/tests/common/mod.rs +++ b/beacon_node/eth2_libp2p/tests/common/mod.rs @@ -44,7 +44,7 @@ pub fn build_log(level: slog::Level, enabled: bool) -> slog::Logger { // A bit of hack to find an unused port. /// -/// Does not guarantee that the given port is unused after the function exists, just that it was +/// Does not guarantee that the given port is unused after the function exits, just that it was /// unused before the function started (i.e., it does not reserve a port). pub fn unused_port(transport: &str) -> Result { let local_addr = match transport { diff --git a/beacon_node/genesis/Cargo.toml b/beacon_node/genesis/Cargo.toml index ef9f214011c..67bc30f1da7 100644 --- a/beacon_node/genesis/Cargo.toml +++ b/beacon_node/genesis/Cargo.toml @@ -7,6 +7,7 @@ edition = "2018" [dev-dependencies] eth1_test_rig = { path = "../../testing/eth1_test_rig" } tokio-compat-02 = "0.1" +sensitive_url = { path = "../../common/sensitive_url" } [dependencies] futures = "0.3.7" diff --git a/beacon_node/genesis/tests/tests.rs b/beacon_node/genesis/tests/tests.rs index 34547a19aa6..f99000ee8cc 100644 --- a/beacon_node/genesis/tests/tests.rs +++ b/beacon_node/genesis/tests/tests.rs @@ -7,6 +7,7 @@ use environment::{Environment, EnvironmentBuilder}; use eth1::{DEFAULT_CHAIN_ID, DEFAULT_NETWORK_ID}; use eth1_test_rig::{DelayThenDeposit, GanacheEth1Instance}; use genesis::{Eth1Config, Eth1GenesisService}; +use sensitive_url::SensitiveUrl; use state_processing::is_valid_genesis_state; use std::time::Duration; use tokio_compat_02::FutureExt; @@ -46,7 +47,7 @@ fn basic() { let service = Eth1GenesisService::new( Eth1Config { - endpoints: vec![eth1.endpoint()], + endpoints: vec![SensitiveUrl::parse(eth1.endpoint().as_str()).unwrap()], deposit_contract_address: deposit_contract.address(), deposit_contract_deploy_block: now, lowest_cached_block_number: now, diff --git a/beacon_node/http_api/Cargo.toml b/beacon_node/http_api/Cargo.toml index 4d5d88d405d..606fd7247c3 100644 --- a/beacon_node/http_api/Cargo.toml +++ b/beacon_node/http_api/Cargo.toml @@ -35,3 +35,4 @@ store = { path = "../store" } environment = { path = "../../lighthouse/environment" } tree_hash = "0.1.1" discv5 = { git = "https://github.com/sigp/discv5 ", rev = "02d2c896c66f8dc2b848c3996fedcd98e1dfec69", features = ["libp2p"] } +sensitive_url = { path = "../../common/sensitive_url" } diff --git a/beacon_node/http_api/src/lib.rs b/beacon_node/http_api/src/lib.rs index 82e38b39b0c..bd330bf4e28 100644 --- a/beacon_node/http_api/src/lib.rs +++ b/beacon_node/http_api/src/lib.rs @@ -1354,7 +1354,7 @@ pub fn serve( let heads = chain .heads() .into_iter() - .map(|(root, slot)| api_types::ChainHeadData { root, slot }) + .map(|(root, slot)| api_types::ChainHeadData { slot, root }) .collect::>(); Ok(api_types::GenericResponse::from(heads)) }) @@ -1622,10 +1622,10 @@ pub fn serve( }); Ok(api_types::GenericResponse::from(api_types::PeerCount { - disconnecting, - connecting, connected, + connecting, disconnected, + disconnecting, })) }) }); diff --git a/beacon_node/http_api/tests/tests.rs b/beacon_node/http_api/tests/tests.rs index 2b4777e7e55..dd16d4e8b42 100644 --- a/beacon_node/http_api/tests/tests.rs +++ b/beacon_node/http_api/tests/tests.rs @@ -19,7 +19,7 @@ use beacon_chain::{BeaconChain, StateSkipConfig, MAXIMUM_GOSSIP_CLOCK_DISPARITY} use environment::null_logger; use eth2::Error; use eth2::StatusCode; -use eth2::{types::*, BeaconNodeHttpClient, Url}; +use eth2::{types::*, BeaconNodeHttpClient}; use eth2_libp2p::{ rpc::methods::MetaData, types::{EnrBitfield, SyncState}, @@ -27,6 +27,7 @@ use eth2_libp2p::{ }; use http_api::{Config, Context}; use network::NetworkMessage; +use sensitive_url::SensitiveUrl; use slot_clock::SlotClock; use state_processing::per_slot_processing; use tree_hash::TreeHash; @@ -202,7 +203,7 @@ impl ApiTester { tokio::spawn(async { server.await }); let client = BeaconNodeHttpClient::new( - Url::parse(&format!( + SensitiveUrl::parse(&format!( "http://{}:{}", listening_socket.ip(), listening_socket.port() @@ -309,7 +310,7 @@ impl ApiTester { tokio::spawn(async { server.await }); let client = BeaconNodeHttpClient::new( - Url::parse(&format!( + SensitiveUrl::parse(&format!( "http://{}:{}", listening_socket.ip(), listening_socket.port() diff --git a/beacon_node/network/src/beacon_processor/worker/rpc_methods.rs b/beacon_node/network/src/beacon_processor/worker/rpc_methods.rs index 71b9b11395d..d25590f7c74 100644 --- a/beacon_node/network/src/beacon_processor/worker/rpc_methods.rs +++ b/beacon_node/network/src/beacon_processor/worker/rpc_methods.rs @@ -197,10 +197,7 @@ impl Worker { }; // remove all skip slots - let block_roots = block_roots - .into_iter() - .filter_map(|root| root) - .collect::>(); + let block_roots = block_roots.into_iter().flatten().collect::>(); let mut blocks_sent = 0; for root in block_roots { diff --git a/beacon_node/network/src/service.rs b/beacon_node/network/src/service.rs index ada843e77d6..75786cdc510 100644 --- a/beacon_node/network/src/service.rs +++ b/beacon_node/network/src/service.rs @@ -16,6 +16,7 @@ use futures::prelude::*; use slog::{debug, error, info, o, trace, warn}; use std::{net::SocketAddr, sync::Arc, time::Duration}; use store::HotColdDB; +use task_executor::ShutdownReason; use tokio::sync::mpsc; use tokio::time::Sleep; use types::{EthSpec, RelativeEpoch, SubnetId, Unsigned, ValidatorSubscription}; @@ -522,10 +523,14 @@ fn spawn_service( service.network_globals.listen_multiaddrs.write().push(multiaddr); } Libp2pEvent::ZeroListeners => { - let _ = shutdown_sender.send("All listeners are closed. Unable to listen").await.map_err(|e| { - warn!(service.log, "failed to send a shutdown signal"; "error" => %e - ) - }); + let _ = shutdown_sender + .send(ShutdownReason::Failure("All listeners are closed. Unable to listen")) + .await + .map_err(|e| warn!( + service.log, + "failed to send a shutdown signal"; + "error" => %e + )); } } } diff --git a/beacon_node/src/config.rs b/beacon_node/src/config.rs index 256f7e04fb4..0550e8e0850 100644 --- a/beacon_node/src/config.rs +++ b/beacon_node/src/config.rs @@ -4,6 +4,7 @@ use client::{ClientConfig, ClientGenesis}; use directory::{DEFAULT_BEACON_NODE_DIR, DEFAULT_NETWORK_DIR, DEFAULT_ROOT_DIR}; use eth2_libp2p::{multiaddr::Protocol, Enr, Multiaddr, NetworkConfig, PeerIdSerialized}; use eth2_network_config::{Eth2NetworkConfig, DEFAULT_HARDCODED_NETWORK}; +use sensitive_url::SensitiveUrl; use slog::{info, warn, Logger}; use std::cmp; use std::cmp::max; @@ -163,17 +164,21 @@ pub fn get_config( } // Defines the URL to reach the eth1 node. - if let Some(val) = cli_args.value_of("eth1-endpoint") { + if let Some(endpoint) = cli_args.value_of("eth1-endpoint") { warn!( log, "The --eth1-endpoint flag is deprecated"; "msg" => "please use --eth1-endpoints instead" ); client_config.sync_eth1_chain = true; - client_config.eth1.endpoints = vec![val.to_string()]; - } else if let Some(val) = cli_args.value_of("eth1-endpoints") { - client_config.sync_eth1_chain = true; - client_config.eth1.endpoints = val.split(',').map(String::from).collect(); + client_config.eth1.endpoints = vec![SensitiveUrl::parse(endpoint) + .map_err(|e| format!("eth1-endpoint was an invalid URL: {:?}", e))?]; + } else if let Some(endpoints) = cli_args.value_of("eth1-endpoints") { + client_config.eth1.endpoints = endpoints + .split(',') + .map(|s| SensitiveUrl::parse(s)) + .collect::>() + .map_err(|e| format!("eth1-endpoints contains an invalid URL {:?}", e))?; } if let Some(val) = cli_args.value_of("eth1-blocks-per-log-query") { @@ -638,7 +643,7 @@ pub fn get_eth2_network_config(cli_args: &ArgMatches) -> Result>(path: P, bytes: &[u8]) -> Result<() Ok(()) } +/// Write a file atomically by using a temporary file as an intermediate. +/// +/// Care is taken to preserve the permissions of the file at `file_path` being written. +/// +/// If no file exists at `file_path` one will be created with restricted 0o600-equivalent +/// permissions. +pub fn write_file_via_temporary( + file_path: &Path, + temp_path: &Path, + bytes: &[u8], +) -> Result<(), io::Error> { + // If the file already exists, preserve its permissions by copying it. + // Otherwise, create a new file with restricted permissions. + if file_path.exists() { + fs::copy(&file_path, &temp_path)?; + fs::write(&temp_path, &bytes)?; + } else { + create_with_600_perms(&temp_path, &bytes)?; + } + + // With the temporary file created, perform an atomic rename. + fs::rename(&temp_path, &file_path)?; + + Ok(()) +} + /// Generates a random alphanumeric password of length `DEFAULT_PASSWORD_LEN`. pub fn random_password() -> PlainText { rand::thread_rng() diff --git a/common/account_utils/src/validator_definitions.rs b/common/account_utils/src/validator_definitions.rs index 466349cf95b..2deb95dd347 100644 --- a/common/account_utils/src/validator_definitions.rs +++ b/common/account_utils/src/validator_definitions.rs @@ -3,7 +3,7 @@ //! Serves as the source-of-truth of which validators this validator client should attempt (or not //! attempt) to load into the `crate::intialized_validators::InitializedValidators` struct. -use crate::{create_with_600_perms, default_keystore_password_path, ZeroizeString}; +use crate::{default_keystore_password_path, write_file_via_temporary, ZeroizeString}; use directory::ensure_dir_exists; use eth2_keystore::Keystore; use regex::Regex; @@ -19,6 +19,12 @@ use validator_dir::VOTING_KEYSTORE_FILE; /// The file name for the serialized `ValidatorDefinitions` struct. pub const CONFIG_FILENAME: &str = "validator_definitions.yml"; +/// The temporary file name for the serialized `ValidatorDefinitions` struct. +/// +/// This is used to achieve an atomic update of the contents on disk, without truncation. +/// See: https://github.com/sigp/lighthouse/issues/2159 +pub const CONFIG_TEMP_FILENAME: &str = ".validator_definitions.yml.tmp"; + #[derive(Debug)] pub enum Error { /// The config file could not be opened. @@ -29,7 +35,7 @@ pub enum Error { UnableToSearchForKeystores(io::Error), /// The config file could not be serialized as YAML. UnableToEncodeFile(serde_yaml::Error), - /// The config file could not be written to the filesystem. + /// The config file or temp file could not be written to the filesystem. UnableToWriteFile(io::Error), /// The public key from the keystore is invalid. InvalidKeystorePubkey, @@ -249,19 +255,19 @@ impl ValidatorDefinitions { Ok(new_defs_count) } - /// Encodes `self` as a YAML string it writes it to the `CONFIG_FILENAME` file in the - /// `validators_dir` directory. + /// Encodes `self` as a YAML string and atomically writes it to the `CONFIG_FILENAME` file in + /// the `validators_dir` directory. /// - /// Will create a new file if it does not exist or over-write any existing file. + /// Will create a new file if it does not exist or overwrite any existing file. pub fn save>(&self, validators_dir: P) -> Result<(), Error> { let config_path = validators_dir.as_ref().join(CONFIG_FILENAME); + let temp_path = validators_dir.as_ref().join(CONFIG_TEMP_FILENAME); let bytes = serde_yaml::to_vec(self).map_err(Error::UnableToEncodeFile)?; - if config_path.exists() { - fs::write(config_path, &bytes).map_err(Error::UnableToWriteFile) - } else { - create_with_600_perms(&config_path, &bytes).map_err(Error::UnableToWriteFile) - } + write_file_via_temporary(&config_path, &temp_path, &bytes) + .map_err(Error::UnableToWriteFile)?; + + Ok(()) } /// Adds a new `ValidatorDefinition` to `self`. @@ -392,7 +398,7 @@ mod tests { #[test] fn graffiti_checks() { - let no_graffiti = r#"--- + let no_graffiti = r#"--- description: "" enabled: true type: local_keystore @@ -402,7 +408,7 @@ mod tests { let def: ValidatorDefinition = serde_yaml::from_str(&no_graffiti).unwrap(); assert!(def.graffiti.is_none()); - let invalid_graffiti = r#"--- + let invalid_graffiti = r#"--- description: "" enabled: true type: local_keystore @@ -414,7 +420,7 @@ mod tests { let def: Result = serde_yaml::from_str(&invalid_graffiti); assert!(def.is_err()); - let valid_graffiti = r#"--- + let valid_graffiti = r#"--- description: "" enabled: true type: local_keystore diff --git a/common/eth2/Cargo.toml b/common/eth2/Cargo.toml index 72b18d13fef..e6b69c9686e 100644 --- a/common/eth2/Cargo.toml +++ b/common/eth2/Cargo.toml @@ -21,6 +21,7 @@ libsecp256k1 = "0.3.5" ring = "0.16.19" bytes = "1.0.1" account_utils = { path = "../../common/account_utils" } +sensitive_url = { path = "../../common/sensitive_url" } eth2_ssz = "0.1.2" eth2_ssz_derive = "0.1.0" futures-util = "0.3.8" diff --git a/common/eth2/src/lib.rs b/common/eth2/src/lib.rs index 268902b745a..60f016ad2d2 100644 --- a/common/eth2/src/lib.rs +++ b/common/eth2/src/lib.rs @@ -19,6 +19,7 @@ use futures_util::StreamExt; pub use reqwest; use reqwest::{IntoUrl, Response}; pub use reqwest::{StatusCode, Url}; +use sensitive_url::SensitiveUrl; use serde::{de::DeserializeOwned, Serialize}; use std::convert::TryFrom; use std::fmt; @@ -35,7 +36,7 @@ pub enum Error { /// The server returned an error message where the body was unable to be parsed. StatusCode(StatusCode), /// The supplied URL is badly formatted. It should look something like `http://127.0.0.1:5052`. - InvalidUrl(Url), + InvalidUrl(SensitiveUrl), /// The supplied validator client secret is invalid. InvalidSecret(String), /// The server returned a response with an invalid signature. It may be an impostor. @@ -80,7 +81,7 @@ impl fmt::Display for Error { #[derive(Clone)] pub struct BeaconNodeHttpClient { client: reqwest::Client, - server: Url, + server: SensitiveUrl, } impl fmt::Display for BeaconNodeHttpClient { @@ -91,25 +92,25 @@ impl fmt::Display for BeaconNodeHttpClient { impl AsRef for BeaconNodeHttpClient { fn as_ref(&self) -> &str { - self.server.as_str() + self.server.as_ref() } } impl BeaconNodeHttpClient { - pub fn new(server: Url) -> Self { + pub fn new(server: SensitiveUrl) -> Self { Self { client: reqwest::Client::new(), server, } } - pub fn from_components(server: Url, client: reqwest::Client) -> Self { + pub fn from_components(server: SensitiveUrl, client: reqwest::Client) -> Self { Self { client, server } } /// Return the path with the standard `/eth1/v1` prefix applied. fn eth_path(&self) -> Result { - let mut path = self.server.clone(); + let mut path = self.server.full.clone(); path.path_segments_mut() .map_err(|()| Error::InvalidUrl(self.server.clone()))? diff --git a/common/eth2/src/lighthouse.rs b/common/eth2/src/lighthouse.rs index 9ff047d226b..7a7e1dd5bba 100644 --- a/common/eth2/src/lighthouse.rs +++ b/common/eth2/src/lighthouse.rs @@ -213,7 +213,7 @@ impl BeaconNodeHttpClient { /// `GET lighthouse/health` pub async fn get_lighthouse_health(&self) -> Result, Error> { - let mut path = self.server.clone(); + let mut path = self.server.full.clone(); path.path_segments_mut() .map_err(|()| Error::InvalidUrl(self.server.clone()))? @@ -225,7 +225,7 @@ impl BeaconNodeHttpClient { /// `GET lighthouse/syncing` pub async fn get_lighthouse_syncing(&self) -> Result, Error> { - let mut path = self.server.clone(); + let mut path = self.server.full.clone(); path.path_segments_mut() .map_err(|()| Error::InvalidUrl(self.server.clone()))? @@ -245,7 +245,7 @@ impl BeaconNodeHttpClient { /// `GET lighthouse/proto_array` pub async fn get_lighthouse_proto_array(&self) -> Result, Error> { - let mut path = self.server.clone(); + let mut path = self.server.full.clone(); path.path_segments_mut() .map_err(|()| Error::InvalidUrl(self.server.clone()))? @@ -260,7 +260,7 @@ impl BeaconNodeHttpClient { &self, epoch: Epoch, ) -> Result, Error> { - let mut path = self.server.clone(); + let mut path = self.server.full.clone(); path.path_segments_mut() .map_err(|()| Error::InvalidUrl(self.server.clone()))? @@ -278,7 +278,7 @@ impl BeaconNodeHttpClient { epoch: Epoch, validator_id: ValidatorId, ) -> Result>, Error> { - let mut path = self.server.clone(); + let mut path = self.server.full.clone(); path.path_segments_mut() .map_err(|()| Error::InvalidUrl(self.server.clone()))? @@ -294,7 +294,7 @@ impl BeaconNodeHttpClient { pub async fn get_lighthouse_eth1_syncing( &self, ) -> Result, Error> { - let mut path = self.server.clone(); + let mut path = self.server.full.clone(); path.path_segments_mut() .map_err(|()| Error::InvalidUrl(self.server.clone()))? @@ -309,7 +309,7 @@ impl BeaconNodeHttpClient { pub async fn get_lighthouse_eth1_block_cache( &self, ) -> Result>, Error> { - let mut path = self.server.clone(); + let mut path = self.server.full.clone(); path.path_segments_mut() .map_err(|()| Error::InvalidUrl(self.server.clone()))? @@ -324,7 +324,7 @@ impl BeaconNodeHttpClient { pub async fn get_lighthouse_eth1_deposit_cache( &self, ) -> Result>, Error> { - let mut path = self.server.clone(); + let mut path = self.server.full.clone(); path.path_segments_mut() .map_err(|()| Error::InvalidUrl(self.server.clone()))? @@ -341,7 +341,7 @@ impl BeaconNodeHttpClient { state_id: &StateId, spec: &ChainSpec, ) -> Result>, Error> { - let mut path = self.server.clone(); + let mut path = self.server.full.clone(); path.path_segments_mut() .map_err(|()| Error::InvalidUrl(self.server.clone()))? @@ -359,7 +359,7 @@ impl BeaconNodeHttpClient { /// `GET lighthouse/staking` pub async fn get_lighthouse_staking(&self) -> Result { - let mut path = self.server.clone(); + let mut path = self.server.full.clone(); path.path_segments_mut() .map_err(|()| Error::InvalidUrl(self.server.clone()))? diff --git a/common/eth2/src/lighthouse_vc/http_client.rs b/common/eth2/src/lighthouse_vc/http_client.rs index 3fd8db3e57b..b27bca813fe 100644 --- a/common/eth2/src/lighthouse_vc/http_client.rs +++ b/common/eth2/src/lighthouse_vc/http_client.rs @@ -8,6 +8,7 @@ use reqwest::{ }; use ring::digest::{digest, SHA256}; use secp256k1::{Message, PublicKey, Signature}; +use sensitive_url::SensitiveUrl; use serde::{de::DeserializeOwned, Serialize}; pub use reqwest; @@ -18,7 +19,7 @@ pub use reqwest::{Response, StatusCode, Url}; #[derive(Clone)] pub struct ValidatorClientHttpClient { client: reqwest::Client, - server: Url, + server: SensitiveUrl, secret: ZeroizeString, server_pubkey: PublicKey, } @@ -53,7 +54,7 @@ pub fn parse_pubkey(secret: &str) -> Result { } impl ValidatorClientHttpClient { - pub fn new(server: Url, secret: String) -> Result { + pub fn new(server: SensitiveUrl, secret: String) -> Result { Ok(Self { client: reqwest::Client::new(), server, @@ -63,7 +64,7 @@ impl ValidatorClientHttpClient { } pub fn from_components( - server: Url, + server: SensitiveUrl, client: reqwest::Client, secret: String, ) -> Result { @@ -187,7 +188,7 @@ impl ValidatorClientHttpClient { /// `GET lighthouse/version` pub async fn get_lighthouse_version(&self) -> Result, Error> { - let mut path = self.server.clone(); + let mut path = self.server.full.clone(); path.path_segments_mut() .map_err(|()| Error::InvalidUrl(self.server.clone()))? @@ -199,7 +200,7 @@ impl ValidatorClientHttpClient { /// `GET lighthouse/health` pub async fn get_lighthouse_health(&self) -> Result, Error> { - let mut path = self.server.clone(); + let mut path = self.server.full.clone(); path.path_segments_mut() .map_err(|()| Error::InvalidUrl(self.server.clone()))? @@ -211,7 +212,7 @@ impl ValidatorClientHttpClient { /// `GET lighthouse/spec` pub async fn get_lighthouse_spec(&self) -> Result, Error> { - let mut path = self.server.clone(); + let mut path = self.server.full.clone(); path.path_segments_mut() .map_err(|()| Error::InvalidUrl(self.server.clone()))? @@ -225,7 +226,7 @@ impl ValidatorClientHttpClient { pub async fn get_lighthouse_validators( &self, ) -> Result>, Error> { - let mut path = self.server.clone(); + let mut path = self.server.full.clone(); path.path_segments_mut() .map_err(|()| Error::InvalidUrl(self.server.clone()))? @@ -240,7 +241,7 @@ impl ValidatorClientHttpClient { &self, validator_pubkey: &PublicKeyBytes, ) -> Result>, Error> { - let mut path = self.server.clone(); + let mut path = self.server.full.clone(); path.path_segments_mut() .map_err(|()| Error::InvalidUrl(self.server.clone()))? @@ -256,7 +257,7 @@ impl ValidatorClientHttpClient { &self, validators: Vec, ) -> Result, Error> { - let mut path = self.server.clone(); + let mut path = self.server.full.clone(); path.path_segments_mut() .map_err(|()| Error::InvalidUrl(self.server.clone()))? @@ -271,7 +272,7 @@ impl ValidatorClientHttpClient { &self, request: &CreateValidatorsMnemonicRequest, ) -> Result>, Error> { - let mut path = self.server.clone(); + let mut path = self.server.full.clone(); path.path_segments_mut() .map_err(|()| Error::InvalidUrl(self.server.clone()))? @@ -287,7 +288,7 @@ impl ValidatorClientHttpClient { &self, request: &KeystoreValidatorsPostRequest, ) -> Result, Error> { - let mut path = self.server.clone(); + let mut path = self.server.full.clone(); path.path_segments_mut() .map_err(|()| Error::InvalidUrl(self.server.clone()))? @@ -304,7 +305,7 @@ impl ValidatorClientHttpClient { voting_pubkey: &PublicKeyBytes, enabled: bool, ) -> Result<(), Error> { - let mut path = self.server.clone(); + let mut path = self.server.full.clone(); path.path_segments_mut() .map_err(|()| Error::InvalidUrl(self.server.clone()))? diff --git a/common/remote_signer_consumer/Cargo.toml b/common/remote_signer_consumer/Cargo.toml index 67279715c98..bda6264c621 100644 --- a/common/remote_signer_consumer/Cargo.toml +++ b/common/remote_signer_consumer/Cargo.toml @@ -13,3 +13,4 @@ reqwest = { version = "0.11.0", features = ["json"] } serde = { version = "1.0.116", features = ["derive"] } tokio = { version = "1.1.0", features = ["time"] } types = { path = "../../consensus/types" } +sensitive_url = { path = "../sensitive_url" } diff --git a/common/remote_signer_consumer/src/http_client.rs b/common/remote_signer_consumer/src/http_client.rs index 951fc5d097f..b5b22265b84 100644 --- a/common/remote_signer_consumer/src/http_client.rs +++ b/common/remote_signer_consumer/src/http_client.rs @@ -4,17 +4,18 @@ use crate::{ }; use reqwest::StatusCode; pub use reqwest::Url; +use sensitive_url::SensitiveUrl; use types::{Domain, Fork, Hash256}; /// A wrapper around `reqwest::Client` which provides convenience methods /// to interface with a BLS Remote Signer. pub struct RemoteSignerHttpConsumer { client: reqwest::Client, - server: Url, + server: SensitiveUrl, } impl RemoteSignerHttpConsumer { - pub fn from_components(server: Url, client: reqwest::Client) -> Self { + pub fn from_components(server: SensitiveUrl, client: reqwest::Client) -> Self { Self { client, server } } @@ -43,7 +44,7 @@ impl RemoteSignerHttpConsumer { )); } - let mut path = self.server.clone(); + let mut path = self.server.full.clone(); path.path_segments_mut() .map_err(|()| Error::InvalidUrl(self.server.clone()))? .push("sign") diff --git a/common/remote_signer_consumer/src/lib.rs b/common/remote_signer_consumer/src/lib.rs index cef64d47af0..b8ad33f9860 100644 --- a/common/remote_signer_consumer/src/lib.rs +++ b/common/remote_signer_consumer/src/lib.rs @@ -20,10 +20,11 @@ //! //! ``` //! use remote_signer_consumer::RemoteSignerHttpConsumer; -//! use reqwest::{ClientBuilder, Url}; +//! use reqwest::ClientBuilder; +//! use sensitive_url::SensitiveUrl; //! use tokio::time::Duration; //! -//! let url: Url = "http://127.0.0.1:9000".parse().unwrap(); +//! let url = SensitiveUrl::parse("http://127.0.0.1:9000").unwrap(); //! let reqwest_client = ClientBuilder::new() //! .timeout(Duration::from_secs(2)) //! .build() @@ -115,6 +116,7 @@ mod http_client; pub use http_client::RemoteSignerHttpConsumer; pub use reqwest::Url; +use sensitive_url::SensitiveUrl; use serde::{Deserialize, Serialize}; use types::{AttestationData, BeaconBlock, Domain, Epoch, EthSpec, Fork, Hash256, SignedRoot}; @@ -125,7 +127,7 @@ pub enum Error { /// The server returned an error message where the body was able to be parsed. ServerMessage(String), /// The supplied URL is badly formatted. It should look something like `http://127.0.0.1:5052`. - InvalidUrl(Url), + InvalidUrl(SensitiveUrl), /// The supplied parameter is invalid. InvalidParameter(String), } diff --git a/common/remote_signer_consumer/tests/post.rs b/common/remote_signer_consumer/tests/post.rs index 68a45aac338..1667ee2c621 100644 --- a/common/remote_signer_consumer/tests/post.rs +++ b/common/remote_signer_consumer/tests/post.rs @@ -1,7 +1,8 @@ mod post { use remote_signer_consumer::{Error, RemoteSignerHttpConsumer}; use remote_signer_test::*; - use reqwest::{ClientBuilder, Url}; + use reqwest::ClientBuilder; + use sensitive_url::SensitiveUrl; use tokio::time::Duration; #[test] @@ -53,7 +54,7 @@ mod post { let (test_signer, _tmp_dir) = set_up_api_test_signer_to_sign_message(); let run_testcase = |u: &str| -> Result { - let url: Url = u.parse().map_err(|e| format!("[ParseError] {:?}", e))?; + let url = SensitiveUrl::parse(u).map_err(|e| format!("{:?}", e))?; let reqwest_client = ClientBuilder::new() .timeout(Duration::from_secs(12)) @@ -66,7 +67,7 @@ mod post { let signature = do_sign_request(&test_client, test_input); signature.map_err(|e| match e { - Error::InvalidUrl(message) => format!("[InvalidUrl] {:?}", message), + Error::InvalidUrl(message) => format!("{:?}", message), Error::Reqwest(re) => { if re.is_builder() { format!("[Reqwest - Builder] {:?}", re.url().unwrap()) @@ -84,25 +85,22 @@ mod post { // url::parser::ParseError. // These cases don't even make it to the step of building a RemoteSignerHttpConsumer. - testcase("", "[ParseError] RelativeUrlWithoutBase"); - testcase("/4/8/15/16/23/42", "[ParseError] RelativeUrlWithoutBase"); - testcase("localhost", "[ParseError] RelativeUrlWithoutBase"); - testcase(":", "[ParseError] RelativeUrlWithoutBase"); - testcase("0.0:0", "[ParseError] RelativeUrlWithoutBase"); - testcase(":aa", "[ParseError] RelativeUrlWithoutBase"); - testcase("0:", "[ParseError] RelativeUrlWithoutBase"); - testcase("ftp://", "[ParseError] EmptyHost"); - testcase("http://", "[ParseError] EmptyHost"); - testcase("http://127.0.0.1:abcd", "[ParseError] InvalidPort"); - testcase("http://280.0.0.1", "[ParseError] InvalidIpv4Address"); + testcase("", "ParseError(RelativeUrlWithoutBase)"); + testcase("/4/8/15/16/23/42", "ParseError(RelativeUrlWithoutBase)"); + testcase("localhost", "ParseError(RelativeUrlWithoutBase)"); + testcase(":", "ParseError(RelativeUrlWithoutBase)"); + testcase("0.0:0", "ParseError(RelativeUrlWithoutBase)"); + testcase(":aa", "ParseError(RelativeUrlWithoutBase)"); + testcase("0:", "ParseError(RelativeUrlWithoutBase)"); + testcase("ftp://", "ParseError(EmptyHost)"); + testcase("http://", "ParseError(EmptyHost)"); + testcase("http://127.0.0.1:abcd", "ParseError(InvalidPort)"); + testcase("http://280.0.0.1", "ParseError(InvalidIpv4Address)"); // `Error::InvalidUrl`. // The RemoteSignerHttpConsumer is created, but fails at `path_segments_mut()`. - testcase( - "localhost:abcd", - "[InvalidUrl] Url { scheme: \"localhost\", username: \"\", password: None, host: None, port: None, path: \"abcd\", query: None, fragment: None }", - ); - testcase("localhost:", "[InvalidUrl] Url { scheme: \"localhost\", username: \"\", password: None, host: None, port: None, path: \"\", query: None, fragment: None }"); + testcase("localhost:abcd", "InvalidUrl(\"URL cannot be a base.\")"); + testcase("localhost:", "InvalidUrl(\"URL cannot be a base.\")"); // `Reqwest::Error` of the `Builder` kind. // POST is not made. @@ -130,7 +128,7 @@ mod post { let (test_signer, _tmp_dir) = set_up_api_test_signer_to_sign_message(); let run_testcase = |u: &str| -> Result { - let url: Url = u.parse().unwrap(); + let url = SensitiveUrl::parse(u).unwrap(); let reqwest_client = ClientBuilder::new() .timeout(Duration::from_secs(12)) diff --git a/common/sensitive_url/Cargo.toml b/common/sensitive_url/Cargo.toml new file mode 100644 index 00000000000..b6b0620a08a --- /dev/null +++ b/common/sensitive_url/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "sensitive_url" +version = "0.1.0" +authors = ["Mac L "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +url = "2.2.1" +serde = "1.0.116" diff --git a/common/sensitive_url/src/lib.rs b/common/sensitive_url/src/lib.rs new file mode 100644 index 00000000000..b7e620485ad --- /dev/null +++ b/common/sensitive_url/src/lib.rs @@ -0,0 +1,105 @@ +use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; +use std::fmt; +use url::Url; + +#[derive(Debug)] +pub enum SensitiveError { + InvalidUrl(String), + ParseError(url::ParseError), + RedactError(String), +} + +// Wrapper around Url which provides a custom `Display` implementation to protect user secrets. +#[derive(Clone)] +pub struct SensitiveUrl { + pub full: Url, + pub redacted: String, +} + +impl fmt::Display for SensitiveUrl { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.redacted.fmt(f) + } +} + +impl fmt::Debug for SensitiveUrl { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.redacted.fmt(f) + } +} + +impl AsRef for SensitiveUrl { + fn as_ref(&self) -> &str { + self.redacted.as_str() + } +} + +impl Serialize for SensitiveUrl { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + serializer.serialize_str(&self.full.to_string()) + } +} + +impl<'de> Deserialize<'de> for SensitiveUrl { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let s: String = Deserialize::deserialize(deserializer)?; + SensitiveUrl::parse(&s) + .map_err(|e| de::Error::custom(format!("Failed to deserialize sensitive URL {:?}", e))) + } +} + +impl SensitiveUrl { + pub fn parse(url: &str) -> Result { + let surl = Url::parse(url).map_err(SensitiveError::ParseError)?; + SensitiveUrl::new(surl) + } + + fn new(full: Url) -> Result { + let mut redacted = full.clone(); + redacted + .path_segments_mut() + .map_err(|_| SensitiveError::InvalidUrl("URL cannot be a base.".to_string()))? + .clear(); + redacted.set_query(None); + + if redacted.has_authority() { + redacted.set_username("").map_err(|_| { + SensitiveError::RedactError("Unable to redact username.".to_string()) + })?; + redacted.set_password(None).map_err(|_| { + SensitiveError::RedactError("Unable to redact password.".to_string()) + })?; + } + + Ok(Self { + full, + redacted: redacted.to_string(), + }) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn redact_remote_url() { + let full = "https://project:secret@example.com/example?somequery"; + let surl = SensitiveUrl::parse(full).unwrap(); + assert_eq!(surl.to_string(), "https://example.com/"); + assert_eq!(surl.full.to_string(), full); + } + #[test] + fn redact_localhost_url() { + let full = "http://localhost:5052/"; + let surl = SensitiveUrl::parse(full).unwrap(); + assert_eq!(surl.to_string(), "http://localhost:5052/"); + assert_eq!(surl.full.to_string(), full); + } +} diff --git a/common/task_executor/src/lib.rs b/common/task_executor/src/lib.rs index f2de8b93995..8f5da8f3fe6 100644 --- a/common/task_executor/src/lib.rs +++ b/common/task_executor/src/lib.rs @@ -6,6 +6,24 @@ use slog::{debug, o, trace}; use std::sync::Weak; use tokio::runtime::Runtime; +/// Provides a reason when Lighthouse is shut down. +#[derive(Copy, Clone, Debug)] +pub enum ShutdownReason { + /// The node shut down successfully. + Success(&'static str), + /// The node shut down due to an error condition. + Failure(&'static str), +} + +impl ShutdownReason { + pub fn message(&self) -> &'static str { + match self { + ShutdownReason::Success(msg) => msg, + ShutdownReason::Failure(msg) => msg, + } + } +} + /// A wrapper over a runtime handle which can spawn async and blocking tasks. #[derive(Clone)] pub struct TaskExecutor { @@ -17,7 +35,7 @@ pub struct TaskExecutor { /// continue they can request that everything shuts down. /// /// The task must provide a reason for shutting down. - signal_tx: Sender<&'static str>, + signal_tx: Sender, log: slog::Logger, } @@ -31,7 +49,7 @@ impl TaskExecutor { runtime: Weak, exit: exit_future::Exit, log: slog::Logger, - signal_tx: Sender<&'static str>, + signal_tx: Sender, ) -> Self { Self { runtime, @@ -255,7 +273,7 @@ impl TaskExecutor { } /// Get a channel to request shutting down. - pub fn shutdown_sender(&self) -> Sender<&'static str> { + pub fn shutdown_sender(&self) -> Sender { self.signal_tx.clone() } diff --git a/consensus/types/src/slot_epoch_macros.rs b/consensus/types/src/slot_epoch_macros.rs index caf31417d66..b8e6202fe35 100644 --- a/consensus/types/src/slot_epoch_macros.rs +++ b/consensus/types/src/slot_epoch_macros.rs @@ -572,10 +572,8 @@ macro_rules! math_tests { #[test] fn checked_div() { let assert_checked_div = |a: u64, b: u64, result: Option| { - let division_result_as_u64 = match $type(a).safe_div($type(b)).ok() { - None => None, - Some(val) => Some(val.as_u64()), - }; + let division_result_as_u64 = + $type(a).safe_div($type(b)).ok().map(|val| val.as_u64()); assert_eq!(division_result_as_u64, result); }; diff --git a/lcli/Cargo.toml b/lcli/Cargo.toml index 8141c509f7b..bc9c69c8b7d 100644 --- a/lcli/Cargo.toml +++ b/lcli/Cargo.toml @@ -39,3 +39,4 @@ account_utils = { path = "../common/account_utils" } eth2_wallet = { path = "../crypto/eth2_wallet" } web3 = "0.14.0" eth1_test_rig = { path = "../testing/eth1_test_rig" } +sensitive_url = { path = "../common/sensitive_url" } diff --git a/lcli/src/eth1_genesis.rs b/lcli/src/eth1_genesis.rs index 8ecf2274815..689107228e8 100644 --- a/lcli/src/eth1_genesis.rs +++ b/lcli/src/eth1_genesis.rs @@ -2,6 +2,7 @@ use clap::ArgMatches; use environment::Environment; use eth2_network_config::Eth2NetworkConfig; use genesis::{Eth1Config, Eth1GenesisService}; +use sensitive_url::SensitiveUrl; use ssz::Encode; use std::cmp::max; use std::path::PathBuf; @@ -34,7 +35,11 @@ pub fn run( let mut config = Eth1Config::default(); if let Some(v) = endpoints.clone() { - config.endpoints = v; + config.endpoints = v + .iter() + .map(|s| SensitiveUrl::parse(s)) + .collect::>() + .map_err(|e| format!("Unable to parse eth1 endpoint URL: {:?}", e))?; } config.deposit_contract_address = format!("{:?}", spec.deposit_contract_address); config.deposit_contract_deploy_block = eth2_network_config.deposit_contract_deploy_block; diff --git a/lighthouse/Cargo.toml b/lighthouse/Cargo.toml index cffadf5d826..73321879a9e 100644 --- a/lighthouse/Cargo.toml +++ b/lighthouse/Cargo.toml @@ -3,6 +3,7 @@ name = "lighthouse" version = "1.3.0" authors = ["Sigma Prime "] edition = "2018" +autotests = false [features] # Writes debugging .ssz files to /tmp during block processing. @@ -43,8 +44,15 @@ account_utils = { path = "../common/account_utils" } remote_signer = { "path" = "../remote_signer" } lighthouse_metrics = { path = "../common/lighthouse_metrics" } lazy_static = "1.4.0" +serde_json = "1.0.59" +task_executor = { path = "../common/task_executor" } [dev-dependencies] tempfile = "3.1.0" validator_dir = { path = "../common/validator_dir" } slashing_protection = { path = "../validator_client/slashing_protection" } +eth2_libp2p = { path = "../beacon_node/eth2_libp2p" } + +[[test]] +name = "lighthouse_tests" +path = "tests/main.rs" diff --git a/lighthouse/environment/src/lib.rs b/lighthouse/environment/src/lib.rs index ae5c0cfa80b..4e00785540e 100644 --- a/lighthouse/environment/src/lib.rs +++ b/lighthouse/environment/src/lib.rs @@ -23,7 +23,7 @@ use std::fs::{rename as FsRename, OpenOptions}; use std::path::PathBuf; use std::sync::Arc; use std::time::{SystemTime, UNIX_EPOCH}; -use task_executor::TaskExecutor; +use task_executor::{ShutdownReason, TaskExecutor}; use tokio::runtime::{Builder as RuntimeBuilder, Runtime}; use types::{EthSpec, MainnetEthSpec, MinimalEthSpec}; @@ -289,9 +289,9 @@ impl RuntimeContext { pub struct Environment { runtime: Arc, /// Receiver side of an internal shutdown signal. - signal_rx: Option>, + signal_rx: Option>, /// Sender to request shutting down. - signal_tx: Sender<&'static str>, + signal_tx: Sender, signal: Option, exit: exit_future::Exit, log: Logger, @@ -340,7 +340,7 @@ impl Environment { /// Block the current thread until a shutdown signal is received. /// /// This can be either the user Ctrl-C'ing or a task requesting to shutdown. - pub fn block_until_shutdown_requested(&mut self) -> Result<(), String> { + pub fn block_until_shutdown_requested(&mut self) -> Result { // future of a task requesting to shutdown let mut rx = self .signal_rx @@ -373,11 +373,13 @@ impl Environment { .block_on(future::select(inner_shutdown, ctrlc_oneshot)) { future::Either::Left((Ok(reason), _)) => { - info!(self.log, "Internal shutdown received"; "reason" => reason); - Ok(()) + info!(self.log, "Internal shutdown received"; "reason" => reason.message()); + Ok(reason) } future::Either::Left((Err(e), _)) => Err(e.into()), - future::Either::Right((x, _)) => x.map_err(|e| format!("Ctrlc oneshot failed: {}", e)), + future::Either::Right((x, _)) => x + .map(|()| ShutdownReason::Success("Received Ctrl+C")) + .map_err(|e| format!("Ctrlc oneshot failed: {}", e)), } } diff --git a/lighthouse/src/main.rs b/lighthouse/src/main.rs index 9a26a0189e9..a2520d9be1c 100644 --- a/lighthouse/src/main.rs +++ b/lighthouse/src/main.rs @@ -7,8 +7,10 @@ use environment::EnvironmentBuilder; use eth2_network_config::{Eth2NetworkConfig, DEFAULT_HARDCODED_NETWORK}; use lighthouse_version::VERSION; use slog::{crit, info, warn}; +use std::fs::File; use std::path::PathBuf; use std::process::exit; +use task_executor::ShutdownReason; use types::{EthSpec, EthSpecId}; use validator_client::ProductionValidatorClient; @@ -123,6 +125,23 @@ fn main() { .global(true) ) + .arg( + Arg::with_name("dump-config") + .long("dump-config") + .hidden(true) + .help("Dumps the config to a desired location. Used for testing only.") + .takes_value(true) + .global(true) + ) + .arg( + Arg::with_name("immediate-shutdown") + .long("immediate-shutdown") + .hidden(true) + .help( + "Shuts down immediately after the Beacon Node or Validator has successfully launched. \ + Used for testing only, DO NOT USE IN PRODUCTION.") + .global(true) + ) .subcommand(beacon_node::cli_app()) .subcommand(boot_node::cli_app()) .subcommand(validator_client::cli_app()) @@ -279,6 +298,15 @@ fn run( &context.eth2_config().spec, context.log().clone(), )?; + let shutdown_flag = matches.is_present("immediate-shutdown"); + if let Some(dump_path) = clap_utils::parse_optional::(matches, "dump-config")? + { + let mut file = File::create(dump_path) + .map_err(|e| format!("Failed to create dumped config: {:?}", e))?; + serde_json::to_writer(&mut file, &config) + .map_err(|e| format!("Error serializing config: {:?}", e))?; + }; + environment.runtime().spawn(async move { if let Err(e) = ProductionBeaconNode::new(context.clone(), config).await { crit!(log, "Failed to start beacon node"; "reason" => e); @@ -286,7 +314,11 @@ fn run( // shutting down. let _ = executor .shutdown_sender() - .try_send("Failed to start beacon node"); + .try_send(ShutdownReason::Failure("Failed to start beacon node")); + } else if shutdown_flag { + let _ = executor.shutdown_sender().try_send(ShutdownReason::Success( + "Beacon node immediate shutdown triggered.", + )); } }); } @@ -296,23 +328,34 @@ fn run( let executor = context.executor.clone(); let config = validator_client::Config::from_cli(&matches, context.log()) .map_err(|e| format!("Unable to initialize validator config: {}", e))?; - environment.runtime().spawn(async move { - let run = async { - ProductionValidatorClient::new(context, config) + let shutdown_flag = matches.is_present("immediate-shutdown"); + if let Some(dump_path) = clap_utils::parse_optional::(matches, "dump-config")? + { + let mut file = File::create(dump_path) + .map_err(|e| format!("Failed to create dumped config: {:?}", e))?; + serde_json::to_writer(&mut file, &config) + .map_err(|e| format!("Error serializing config: {:?}", e))?; + }; + if !shutdown_flag { + environment.runtime().spawn(async move { + if let Err(e) = ProductionValidatorClient::new(context, config) .await? - .start_service()?; - + .start_service() + { + crit!(log, "Failed to start validator client"; "reason" => e); + // Ignore the error since it always occurs during normal operation when + // shutting down. + let _ = executor + .shutdown_sender() + .try_send(ShutdownReason::Failure("Failed to start validator client")); + } Ok::<(), String>(()) - }; - if let Err(e) = run.await { - crit!(log, "Failed to start validator client"; "reason" => e); - // Ignore the error since it always occurs during normal operation when - // shutting down. - let _ = executor - .shutdown_sender() - .try_send("Failed to start validator client"); - } - }); + }); + } else { + let _ = executor.shutdown_sender().try_send(ShutdownReason::Success( + "Validator client immediate shutdown triggered.", + )); + } } ("remote_signer", Some(matches)) => { if let Err(e) = remote_signer::run(&mut environment, matches) { @@ -321,7 +364,7 @@ fn run( .core_context() .executor .shutdown_sender() - .try_send("Failed to start remote signer"); + .try_send(ShutdownReason::Failure("Failed to start remote signer")); } } _ => { @@ -331,12 +374,16 @@ fn run( }; // Block this thread until we get a ctrl-c or a task sends a shutdown signal. - environment.block_until_shutdown_requested()?; - info!(log, "Shutting down.."); + let shutdown_reason = environment.block_until_shutdown_requested()?; + info!(log, "Shutting down.."; "reason" => ?shutdown_reason); environment.fire_signal(); // Shutdown the environment once all tasks have completed. environment.shutdown_on_idle(); - Ok(()) + + match shutdown_reason { + ShutdownReason::Success(_) => Ok(()), + ShutdownReason::Failure(msg) => Err(msg.to_string()), + } } diff --git a/lighthouse/tests/account_manager.rs b/lighthouse/tests/account_manager.rs index b5b0129988a..dd4e8443e79 100644 --- a/lighthouse/tests/account_manager.rs +++ b/lighthouse/tests/account_manager.rs @@ -1,5 +1,3 @@ -#![cfg(not(debug_assertions))] - use account_manager::{ validator::{ create::*, @@ -35,8 +33,8 @@ use validator_dir::ValidatorDir; /// Returns the `lighthouse account` command. fn account_cmd() -> Command { - let target_dir = env!("CARGO_BIN_EXE_lighthouse"); - let path = target_dir + let lighthouse_bin = env!("CARGO_BIN_EXE_lighthouse"); + let path = lighthouse_bin .parse::() .expect("should parse CARGO_TARGET_DIR"); diff --git a/lighthouse/tests/beacon_node.rs b/lighthouse/tests/beacon_node.rs new file mode 100644 index 00000000000..ef1edb77475 --- /dev/null +++ b/lighthouse/tests/beacon_node.rs @@ -0,0 +1,841 @@ +use beacon_node::ClientConfig as Config; + +use eth2_libp2p::PeerId; +use serde_json::from_reader; +use std::fs::File; +use std::io::Write; +use std::net::{IpAddr, Ipv4Addr}; +use std::net::{TcpListener, UdpSocket}; +use std::path::PathBuf; +use std::process::{Command, Output}; +use std::str::{from_utf8, FromStr}; +use std::string::ToString; +use tempfile::TempDir; +use types::{Checkpoint, Epoch, Hash256}; + +const BEACON_CMD: &str = "beacon_node"; +const CONFIG_NAME: &str = "bn_dump.json"; +const DUMP_CONFIG_CMD: &str = "dump-config"; +const IMMEDIATE_SHUTDOWN_CMD: &str = "immediate-shutdown"; +const DEFAULT_ETH1_ENDPOINT: &str = "http://localhost:8545/"; + +/// Returns the `lighthouse beacon_node --immediate-shutdown` command. +fn base_cmd() -> Command { + let lighthouse_bin = env!("CARGO_BIN_EXE_lighthouse"); + let path = lighthouse_bin + .parse::() + .expect("should parse CARGO_TARGET_DIR"); + + let mut cmd = Command::new(path); + cmd.arg(BEACON_CMD) + .arg(format!("--{}", IMMEDIATE_SHUTDOWN_CMD)); + + cmd +} + +/// Executes a `Command`, returning a `Result` based upon the success exit code of the command. +fn output_result(cmd: &mut Command) -> Result { + let output = cmd.output().expect("should run command"); + + if output.status.success() { + Ok(output) + } else { + Err(from_utf8(&output.stderr) + .expect("stderr is not utf8") + .to_string()) + } +} + +// Wrapper around `Command` for easier Command Line Testing. +struct CommandLineTest { + cmd: Command, +} +impl CommandLineTest { + fn new() -> CommandLineTest { + let base_cmd = base_cmd(); + CommandLineTest { cmd: base_cmd } + } + + fn flag(mut self, flag: &str, value: Option<&str>) -> Self { + // Build the command by adding the flag and any values. + self.cmd.arg(format!("--{}", flag)); + if let Some(value) = value { + self.cmd.arg(value); + } + self + } + + fn run(&mut self) -> CompletedTest { + // Setup temp directories. + let tmp_dir = TempDir::new().expect("Unable to create temporary directory"); + let tmp_path: PathBuf = tmp_dir.path().join(CONFIG_NAME); + + // Add --datadir --dump-config -z to cmd. + self.cmd + .arg("--datadir") + .arg(tmp_dir.path().as_os_str()) + .arg(format!("--{}", DUMP_CONFIG_CMD)) + .arg(tmp_path.as_os_str()) + .arg("-z"); + + // Run the command. + let output = output_result(&mut self.cmd); + if let Err(e) = output { + panic!("{:?}", e); + } + + // Grab the config. + let config: Config = + from_reader(File::open(tmp_path).expect("Unable to open dumped config")) + .expect("Unable to deserialize to ClientConfig"); + CompletedTest { + config, + dir: tmp_dir, + } + } + + fn run_with_no_zero_port(&mut self) -> CompletedTest { + // Setup temp directories. + let tmp_dir = TempDir::new().expect("Unable to create temporary directory"); + let tmp_path: PathBuf = tmp_dir.path().join(CONFIG_NAME); + + // Add --datadir --dump-config to cmd. + self.cmd + .arg("--datadir") + .arg(tmp_dir.path().as_os_str()) + .arg(format!("--{}", DUMP_CONFIG_CMD)) + .arg(tmp_path.as_os_str()); + + // Run the command. + let output = output_result(&mut self.cmd); + if let Err(e) = output { + panic!("{:?}", e); + } + + // Grab the config. + let config: Config = + from_reader(File::open(tmp_path).expect("Unable to open dumped config")) + .expect("Unable to deserialize to ClientConfig"); + CompletedTest { + config, + dir: tmp_dir, + } + } +} +struct CompletedTest { + config: Config, + dir: TempDir, +} +impl CompletedTest { + fn with_config(self, func: F) { + func(&self.config); + } + fn with_config_and_dir(self, func: F) { + func(&self.config, &self.dir); + } +} + +#[test] +fn datadir_flag() { + CommandLineTest::new() + .run() + .with_config_and_dir(|config, dir| assert_eq!(config.data_dir, dir.path().join("beacon"))); +} + +#[test] +fn staking_flag() { + CommandLineTest::new() + .flag("staking", None) + .run() + .with_config(|config| { + assert!(config.http_api.enabled); + assert!(config.sync_eth1_chain); + assert_eq!(config.eth1.endpoints[0].to_string(), DEFAULT_ETH1_ENDPOINT); + }); +} + +#[test] +fn wss_checkpoint_flag() { + let state = Some(Checkpoint { + epoch: Epoch::new(1010), + root: Hash256::from_str("deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef") + .unwrap(), + }); + CommandLineTest::new() + .flag( + "wss-checkpoint", + Some("0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef:1010"), + ) + .run() + .with_config(|config| assert_eq!(config.chain.weak_subjectivity_checkpoint, state)); +} +#[test] +fn max_skip_slots_flag() { + CommandLineTest::new() + .flag("max-skip-slots", Some("10")) + .run() + .with_config(|config| assert_eq!(config.chain.import_max_skip_slots, Some(10))); +} + +#[test] +fn freezer_dir_flag() { + let dir = TempDir::new().expect("Unable to create temporary directory"); + CommandLineTest::new() + .flag("freezer-dir", dir.path().as_os_str().to_str()) + .run() + .with_config(|config| assert_eq!(config.freezer_db_path, Some(dir.path().to_path_buf()))); +} + +#[test] +fn graffiti_flag() { + CommandLineTest::new() + .flag("graffiti", Some("nice-graffiti")) + .run() + .with_config(|config| { + assert_eq!( + config.graffiti.to_string(), + "0x6e6963652d677261666669746900000000000000000000000000000000000000" + ); + }); +} + +#[test] +fn trusted_peers_flag() { + let peers = vec![PeerId::random(), PeerId::random()]; + CommandLineTest::new() + .flag( + "trusted-peers", + Some(format!("{},{}", peers[0].to_string(), peers[1].to_string()).as_str()), + ) + .run() + .with_config(|config| { + assert_eq!( + PeerId::from(config.network.trusted_peers[0].clone()).to_bytes(), + peers[0].to_bytes() + ); + assert_eq!( + PeerId::from(config.network.trusted_peers[1].clone()).to_bytes(), + peers[1].to_bytes() + ); + }); +} + +// Tests for Eth1 flags. +#[test] +fn dummy_eth1_flag() { + CommandLineTest::new() + .flag("dummy-eth1", None) + .run() + .with_config(|config| assert!(config.dummy_eth1_backend)); +} +#[test] +fn eth1_flag() { + CommandLineTest::new() + .flag("eth1", None) + .run() + .with_config(|config| assert!(config.sync_eth1_chain)); +} +#[test] +fn eth1_endpoints_flag() { + CommandLineTest::new() + .flag( + "eth1-endpoints", + Some("http://localhost:9545,https://infura.io/secret"), + ) + .run() + .with_config(|config| { + assert_eq!( + config.eth1.endpoints[0].full.to_string(), + "http://localhost:9545/" + ); + assert_eq!( + config.eth1.endpoints[0].to_string(), + "http://localhost:9545/" + ); + assert_eq!( + config.eth1.endpoints[1].full.to_string(), + "https://infura.io/secret" + ); + assert_eq!(config.eth1.endpoints[1].to_string(), "https://infura.io/"); + }); +} +#[test] +fn eth1_blocks_per_log_query_flag() { + CommandLineTest::new() + .flag("eth1-blocks-per-log-query", Some("500")) + .run() + .with_config(|config| assert_eq!(config.eth1.blocks_per_log_query, 500)); +} +#[test] +fn eth1_purge_cache_flag() { + CommandLineTest::new() + .flag("eth1-purge-cache", None) + .run() + .with_config(|config| assert!(config.eth1.purge_cache)); +} + +// Tests for Network flags. +#[test] +fn network_dir_flag() { + let dir = TempDir::new().expect("Unable to create temporary directory"); + CommandLineTest::new() + .flag("network-dir", dir.path().as_os_str().to_str()) + .run() + .with_config(|config| assert_eq!(config.network.network_dir, dir.path())); +} +#[test] +fn network_target_peers_flag() { + CommandLineTest::new() + .flag("target-peers", Some("55")) + .run() + .with_config(|config| { + assert_eq!(config.network.target_peers, "55".parse::().unwrap()); + }); +} +#[test] +fn network_subscribe_all_subnets_flag() { + CommandLineTest::new() + .flag("subscribe-all-subnets", None) + .run() + .with_config(|config| assert!(config.network.subscribe_all_subnets)); +} +#[test] +fn network_import_all_attestations_flag() { + CommandLineTest::new() + .flag("import-all-attestations", None) + .run() + .with_config(|config| assert!(config.network.import_all_attestations)); +} +#[test] +fn network_listen_address_flag() { + let addr = "127.0.0.2".parse::().unwrap(); + CommandLineTest::new() + .flag("listen-address", Some("127.0.0.2")) + .run() + .with_config(|config| assert_eq!(config.network.listen_address, addr)); +} +#[test] +fn network_port_flag() { + let port = unused_port("tcp").expect("Unable to find unused port."); + CommandLineTest::new() + .flag("port", Some(port.to_string().as_str())) + .run_with_no_zero_port() + .with_config(|config| { + assert_eq!(config.network.libp2p_port, port); + assert_eq!(config.network.discovery_port, port); + }); +} +#[test] +fn network_port_and_discovery_port_flags() { + let port1 = unused_port("tcp").expect("Unable to find unused port."); + let port2 = unused_port("udp").expect("Unable to find unused port."); + CommandLineTest::new() + .flag("port", Some(port1.to_string().as_str())) + .flag("discovery-port", Some(port2.to_string().as_str())) + .run_with_no_zero_port() + .with_config(|config| { + assert_eq!(config.network.libp2p_port, port1); + assert_eq!(config.network.discovery_port, port2); + }); +} +#[test] +fn disable_discovery_flag() { + CommandLineTest::new() + .flag("disable-discovery", None) + .run() + .with_config(|config| assert!(config.network.disable_discovery)); +} +#[test] +fn disable_upnp_flag() { + CommandLineTest::new() + .flag("disable-upnp", None) + .run() + .with_config(|config| assert!(!config.network.upnp_enabled)); +} +#[test] +fn default_boot_nodes() { + let mainnet = vec![ + // Lighthouse Team (Sigma Prime) + "enr:-Jq4QFs9If3eUC8mHx6-BLVw0jRMbyEgXNn6sl7c77bBmji_afJ-0_X7Q4vttQ8SO8CYReudHsGVvgSybh1y96yyL-oChGV0aDKQtTA_KgAAAAD__________4JpZIJ2NIJpcIQ2_YtGiXNlY3AyNTZrMaECSHaY_36GdNjF8-CLfMSg-8lB0wce5VRZ96HkT9tSkVeDdWRwgiMo", + "enr:-Jq4QA4kNIdO1FkIHpl5iqEKjJEjCVfp77aFulytCEPvEQOdbTTf6ucNmWSuXjlwvgka86gkpnCTv-V7CfBn4AMBRvIChGV0aDKQtTA_KgAAAAD__________4JpZIJ2NIJpcIQ22Gh-iXNlY3AyNTZrMaEC0EiXxAB2QKZJuXnUwmf-KqbP9ZP7m9gsRxcYvoK9iTCDdWRwgiMo", + // EF Team + "enr:-Ku4QHqVeJ8PPICcWk1vSn_XcSkjOkNiTg6Fmii5j6vUQgvzMc9L1goFnLKgXqBJspJjIsB91LTOleFmyWWrFVATGngBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpC1MD8qAAAAAP__________gmlkgnY0gmlwhAMRHkWJc2VjcDI1NmsxoQKLVXFOhp2uX6jeT0DvvDpPcU8FWMjQdR4wMuORMhpX24N1ZHCCIyg", + "enr:-Ku4QG-2_Md3sZIAUebGYT6g0SMskIml77l6yR-M_JXc-UdNHCmHQeOiMLbylPejyJsdAPsTHJyjJB2sYGDLe0dn8uYBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpC1MD8qAAAAAP__________gmlkgnY0gmlwhBLY-NyJc2VjcDI1NmsxoQORcM6e19T1T9gi7jxEZjk_sjVLGFscUNqAY9obgZaxbIN1ZHCCIyg", + "enr:-Ku4QPn5eVhcoF1opaFEvg1b6JNFD2rqVkHQ8HApOKK61OIcIXD127bKWgAtbwI7pnxx6cDyk_nI88TrZKQaGMZj0q0Bh2F0dG5ldHOIAAAAAAAAAACEZXRoMpC1MD8qAAAAAP__________gmlkgnY0gmlwhDayLMaJc2VjcDI1NmsxoQK2sBOLGcUb4AwuYzFuAVCaNHA-dy24UuEKkeFNgCVCsIN1ZHCCIyg", + "enr:-Ku4QEWzdnVtXc2Q0ZVigfCGggOVB2Vc1ZCPEc6j21NIFLODSJbvNaef1g4PxhPwl_3kax86YPheFUSLXPRs98vvYsoBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpC1MD8qAAAAAP__________gmlkgnY0gmlwhDZBrP2Jc2VjcDI1NmsxoQM6jr8Rb1ktLEsVcKAPa08wCsKUmvoQ8khiOl_SLozf9IN1ZHCCIyg", + // Teku team (Consensys) + "enr:-KG4QOtcP9X1FbIMOe17QNMKqDxCpm14jcX5tiOE4_TyMrFqbmhPZHK_ZPG2Gxb1GE2xdtodOfx9-cgvNtxnRyHEmC0ghGV0aDKQ9aX9QgAAAAD__________4JpZIJ2NIJpcIQDE8KdiXNlY3AyNTZrMaEDhpehBDbZjM_L9ek699Y7vhUJ-eAdMyQW_Fil522Y0fODdGNwgiMog3VkcIIjKA", + "enr:-KG4QDyytgmE4f7AnvW-ZaUOIi9i79qX4JwjRAiXBZCU65wOfBu-3Nb5I7b_Rmg3KCOcZM_C3y5pg7EBU5XGrcLTduQEhGV0aDKQ9aX9QgAAAAD__________4JpZIJ2NIJpcIQ2_DUbiXNlY3AyNTZrMaEDKnz_-ps3UUOfHWVYaskI5kWYO_vtYMGYCQRAR3gHDouDdGNwgiMog3VkcIIjKA", + // Prysm team (Prysmatic Labs) + "enr:-Ku4QImhMc1z8yCiNJ1TyUxdcfNucje3BGwEHzodEZUan8PherEo4sF7pPHPSIB1NNuSg5fZy7qFsjmUKs2ea1Whi0EBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpD1pf1CAAAAAP__________gmlkgnY0gmlwhBLf22SJc2VjcDI1NmsxoQOVphkDqal4QzPMksc5wnpuC3gvSC8AfbFOnZY_On34wIN1ZHCCIyg", + "enr:-Ku4QP2xDnEtUXIjzJ_DhlCRN9SN99RYQPJL92TMlSv7U5C1YnYLjwOQHgZIUXw6c-BvRg2Yc2QsZxxoS_pPRVe0yK8Bh2F0dG5ldHOIAAAAAAAAAACEZXRoMpD1pf1CAAAAAP__________gmlkgnY0gmlwhBLf22SJc2VjcDI1NmsxoQMeFF5GrS7UZpAH2Ly84aLK-TyvH-dRo0JM1i8yygH50YN1ZHCCJxA", + "enr:-Ku4QPp9z1W4tAO8Ber_NQierYaOStqhDqQdOPY3bB3jDgkjcbk6YrEnVYIiCBbTxuar3CzS528d2iE7TdJsrL-dEKoBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpD1pf1CAAAAAP__________gmlkgnY0gmlwhBLf22SJc2VjcDI1NmsxoQMw5fqqkw2hHC4F5HZZDPsNmPdB1Gi8JPQK7pRc9XHh-oN1ZHCCKvg", + // Nimbus team + "enr:-LK4QA8FfhaAjlb_BXsXxSfiysR7R52Nhi9JBt4F8SPssu8hdE1BXQQEtVDC3qStCW60LSO7hEsVHv5zm8_6Vnjhcn0Bh2F0dG5ldHOIAAAAAAAAAACEZXRoMpC1MD8qAAAAAP__________gmlkgnY0gmlwhAN4aBKJc2VjcDI1NmsxoQJerDhsJ-KxZ8sHySMOCmTO6sHM3iCFQ6VMvLTe948MyYN0Y3CCI4yDdWRwgiOM", + "enr:-LK4QKWrXTpV9T78hNG6s8AM6IO4XH9kFT91uZtFg1GcsJ6dKovDOr1jtAAFPnS2lvNltkOGA9k29BUN7lFh_sjuc9QBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpC1MD8qAAAAAP__________gmlkgnY0gmlwhANAdd-Jc2VjcDI1NmsxoQLQa6ai7y9PMN5hpLe5HmiJSlYzMuzP7ZhwRiwHvqNXdoN0Y3CCI4yDdWRwgiOM" + ]; + + CommandLineTest::new().run().with_config(|config| { + // Lighthouse Team (Sigma Prime) + assert_eq!(config.network.boot_nodes_enr[0].to_base64(), mainnet[0]); + assert_eq!(config.network.boot_nodes_enr[1].to_base64(), mainnet[1]); + // EF Team + assert_eq!(config.network.boot_nodes_enr[2].to_base64(), mainnet[2]); + assert_eq!(config.network.boot_nodes_enr[3].to_base64(), mainnet[3]); + assert_eq!(config.network.boot_nodes_enr[4].to_base64(), mainnet[4]); + assert_eq!(config.network.boot_nodes_enr[5].to_base64(), mainnet[5]); + // Teku team (Consensys) + assert_eq!(config.network.boot_nodes_enr[6].to_base64(), mainnet[6]); + assert_eq!(config.network.boot_nodes_enr[7].to_base64(), mainnet[7]); + // Prysm team (Prysmatic Labs) + assert_eq!(config.network.boot_nodes_enr[8].to_base64(), mainnet[8]); + assert_eq!(config.network.boot_nodes_enr[9].to_base64(), mainnet[9]); + assert_eq!(config.network.boot_nodes_enr[10].to_base64(), mainnet[10]); + // Nimbus team + assert_eq!(config.network.boot_nodes_enr[11].to_base64(), mainnet[11]); + assert_eq!(config.network.boot_nodes_enr[12].to_base64(), mainnet[12]); + }); +} +#[test] +fn boot_nodes_flag() { + let nodes = "enr:-IS4QHCYrYZbAKWCBRlAy5zzaDZXJBGkcnh4MHcBFZntXNFrdvJjX04jRzjzCBOonrkTfj499SZuOh8R33Ls8RRcy5wBgmlkgnY0gmlwhH8AAAGJc2VjcDI1NmsxoQPKY0yuDUmstAHYpMa2_oxVtw0RW_QAdpzBQA8yWM0xOIN1ZHCCdl8,\ + enr:-LK4QFOFWca5ABQzxiCRcy37G7wy1K6zD4qMYBSN5ozzanwze_XVvXVhCk9JvF0cHXOBZrHK1E4vU7Gn-a0bHVczoDU6h2F0dG5ldHOIAAAAAAAAAACEZXRoMpA7CIeVAAAgCf__________gmlkgnY0gmlwhNIy-4iJc2VjcDI1NmsxoQJA3AXQJ6M3NpBWtJS3HPtbXG14t7qHjXuIaL6IOz89T4N0Y3CCIyiDdWRwgiMo"; + let enr: Vec<&str> = nodes.split(',').collect(); + CommandLineTest::new() + .flag("boot-nodes", Some(nodes)) + .run() + .with_config(|config| { + assert_eq!(config.network.boot_nodes_enr[0].to_base64(), enr[0]); + assert_eq!(config.network.boot_nodes_enr[1].to_base64(), enr[1]); + }); +} +#[test] +fn boot_nodes_multiaddr_flag() { + let nodes = "/ip4/0.0.0.0/tcp/9000/p2p/16Uiu2HAkynrfLjeoAP7R3WFySad2NfduShkTpx8f8ygpSSfP1yen,\ + /ip4/192.167.55.55/tcp/9000/p2p/16Uiu2HAkynrfLjeoBP7R3WFyDad2NfduVhkWpx8f8ygpSSfP1yen"; + let multiaddr: Vec<&str> = nodes.split(',').collect(); + CommandLineTest::new() + .flag("boot-nodes", Some(nodes)) + .run() + .with_config(|config| { + assert_eq!( + config.network.boot_nodes_multiaddr[0].to_string(), + multiaddr[0] + ); + assert_eq!( + config.network.boot_nodes_multiaddr[1].to_string(), + multiaddr[1] + ); + }); +} +#[test] +fn private_flag() { + CommandLineTest::new() + .flag("private", None) + .run() + .with_config(|config| assert!(config.network.private)); +} +#[test] +fn zero_ports_flag() { + CommandLineTest::new().run().with_config(|config| { + assert_eq!(config.network.enr_address, None); + assert_eq!(config.http_api.listen_port, 0); + assert_eq!(config.http_metrics.listen_port, 0); + }); +} + +// Tests for ENR flags. +#[test] +fn enr_udp_port_flags() { + let port = unused_port("udp").expect("Unable to find unused port."); + CommandLineTest::new() + .flag("enr-udp-port", Some(port.to_string().as_str())) + .run() + .with_config(|config| assert_eq!(config.network.enr_udp_port, Some(port))); +} +#[test] +fn enr_tcp_port_flags() { + let port = unused_port("tcp").expect("Unable to find unused port."); + CommandLineTest::new() + .flag("enr-tcp-port", Some(port.to_string().as_str())) + .run() + .with_config(|config| assert_eq!(config.network.enr_tcp_port, Some(port))); +} +#[test] +fn enr_match_flag() { + let addr = "127.0.0.2".parse::().unwrap(); + let port1 = unused_port("udp").expect("Unable to find unused port."); + let port2 = unused_port("udp").expect("Unable to find unused port."); + CommandLineTest::new() + .flag("enr-match", None) + .flag("listen-address", Some("127.0.0.2")) + .flag("discovery-port", Some(port1.to_string().as_str())) + .flag("port", Some(port2.to_string().as_str())) + .run_with_no_zero_port() + .with_config(|config| { + assert_eq!(config.network.listen_address, addr); + assert_eq!(config.network.enr_address, Some(addr)); + assert_eq!(config.network.discovery_port, port1); + assert_eq!(config.network.enr_udp_port, Some(port1)); + }); +} +#[test] +fn enr_address_flag() { + let addr = "192.167.1.1".parse::().unwrap(); + let port = unused_port("udp").expect("Unable to find unused port."); + CommandLineTest::new() + .flag("enr-address", Some("192.167.1.1")) + .flag("enr-udp-port", Some(port.to_string().as_str())) + .run() + .with_config(|config| { + assert_eq!(config.network.enr_address, Some(addr)); + assert_eq!(config.network.enr_udp_port, Some(port)); + }); +} +#[test] +fn enr_address_dns_flag() { + let addr = "127.0.0.1".parse::().unwrap(); + let ipv6addr = "::1".parse::().unwrap(); + let port = unused_port("udp").expect("Unable to find unused port."); + CommandLineTest::new() + .flag("enr-address", Some("localhost")) + .flag("enr-udp-port", Some(port.to_string().as_str())) + .run() + .with_config(|config| { + assert!( + config.network.enr_address == Some(addr) + || config.network.enr_address == Some(ipv6addr) + ); + assert_eq!(config.network.enr_udp_port, Some(port)); + }); +} +#[test] +fn disable_enr_auto_update_flag() { + CommandLineTest::new() + .flag("disable-enr-auto-update", None) + .run() + .with_config(|config| assert!(config.network.discv5_config.enr_update)); +} + +// Tests for HTTP flags. +#[test] +fn http_flag() { + CommandLineTest::new() + .flag("http", None) + .run() + .with_config(|config| assert!(config.http_api.enabled)); +} +#[test] +fn http_address_flag() { + let addr = "127.0.0.99".parse::().unwrap(); + CommandLineTest::new() + .flag("http-address", Some("127.0.0.99")) + .run() + .with_config(|config| assert_eq!(config.http_api.listen_addr, addr)); +} +#[test] +fn http_port_flag() { + let port1 = unused_port("tcp").expect("Unable to find unused port."); + let port2 = unused_port("tcp").expect("Unable to find unused port."); + CommandLineTest::new() + .flag("http-port", Some(port1.to_string().as_str())) + .flag("port", Some(port2.to_string().as_str())) + .run_with_no_zero_port() + .with_config(|config| assert_eq!(config.http_api.listen_port, port1)); +} +#[test] +fn http_allow_origin_flag() { + CommandLineTest::new() + .flag("http-allow-origin", Some("127.0.0.99")) + .run() + .with_config(|config| { + assert_eq!(config.http_api.allow_origin, Some("127.0.0.99".to_string())); + }); +} +#[test] +fn http_allow_origin_all_flag() { + CommandLineTest::new() + .flag("http-allow-origin", Some("*")) + .run() + .with_config(|config| assert_eq!(config.http_api.allow_origin, Some("*".to_string()))); +} + +// Tests for Metrics flags. +#[test] +fn metrics_flag() { + CommandLineTest::new() + .flag("metrics", None) + .run() + .with_config(|config| assert!(config.http_metrics.enabled)); +} +#[test] +fn metrics_address_flag() { + let addr = "127.0.0.99".parse::().unwrap(); + CommandLineTest::new() + .flag("metrics", None) + .flag("metrics-address", Some("127.0.0.99")) + .run() + .with_config(|config| assert_eq!(config.http_metrics.listen_addr, addr)); +} +#[test] +fn metrics_port_flag() { + let port1 = unused_port("tcp").expect("Unable to find unused port."); + let port2 = unused_port("tcp").expect("Unable to find unused port."); + CommandLineTest::new() + .flag("metrics", None) + .flag("metrics-port", Some(port1.to_string().as_str())) + .flag("port", Some(port2.to_string().as_str())) + .run_with_no_zero_port() + .with_config(|config| assert_eq!(config.http_metrics.listen_port, port1)); +} +#[test] +fn metrics_allow_origin_flag() { + CommandLineTest::new() + .flag("metrics", None) + .flag("metrics-allow-origin", Some("http://localhost:5059")) + .run() + .with_config(|config| { + assert_eq!( + config.http_metrics.allow_origin, + Some("http://localhost:5059".to_string()) + ) + }); +} +#[test] +fn metrics_allow_origin_all_flag() { + CommandLineTest::new() + .flag("metrics", None) + .flag("metrics-allow-origin", Some("*")) + .run() + .with_config(|config| assert_eq!(config.http_metrics.allow_origin, Some("*".to_string()))); +} + +// Tests for Validator Monitor flags. +#[test] +fn validator_monitor_auto_flag() { + CommandLineTest::new() + .flag("validator-monitor-auto", None) + .run() + .with_config(|config| assert!(config.validator_monitor_auto)); +} +#[test] +fn validator_monitor_pubkeys_flag() { + CommandLineTest::new() + .flag("validator-monitor-pubkeys", Some("0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef,\ + 0xbeefdeadbeefdeaddeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef")) + .run() + .with_config(|config| { + assert_eq!(config.validator_monitor_pubkeys[0].to_string(), "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef"); + assert_eq!(config.validator_monitor_pubkeys[1].to_string(), "0xbeefdeadbeefdeaddeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef"); + }); +} +#[test] +fn validator_monitor_file_flag() { + let dir = TempDir::new().expect("Unable to create temporary directory"); + let mut file = File::create(dir.path().join("pubkeys.txt")).expect("Unable to create file"); + file.write_all(b"0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef,\ + 0xbeefdeadbeefdeaddeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef") + .expect("Unable to write to file"); + CommandLineTest::new() + .flag("validator-monitor-file", dir.path().join("pubkeys.txt").as_os_str().to_str()) + .run() + .with_config(|config| { + assert_eq!(config.validator_monitor_pubkeys[0].to_string(), "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef"); + assert_eq!(config.validator_monitor_pubkeys[1].to_string(), "0xbeefdeadbeefdeaddeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef"); + }); +} + +// Tests for Store flags. +#[test] +fn slots_per_restore_point_flag() { + CommandLineTest::new() + .flag("slots-per-restore-point", Some("64")) + .run() + .with_config(|config| assert_eq!(config.store.slots_per_restore_point, 64)); +} +#[test] +fn block_cache_size_flag() { + CommandLineTest::new() + .flag("block-cache-size", Some("4")) + .run() + .with_config(|config| assert_eq!(config.store.block_cache_size, 4_usize)); +} +#[test] +fn auto_compact_db_flag() { + CommandLineTest::new() + .flag("auto-compact-db", Some("false")) + .run() + .with_config(|config| assert!(!config.store.compact_on_prune)); +} +#[test] +fn compact_db_flag() { + CommandLineTest::new() + .flag("auto-compact-db", Some("false")) + .flag("compact-db", None) + .run() + .with_config(|config| assert!(config.store.compact_on_init)); +} + +// Tests for Slasher flags. +#[test] +fn slasher_flag() { + CommandLineTest::new() + .flag("slasher", None) + .run() + .with_config_and_dir(|config, dir| { + if let Some(slasher_config) = &config.slasher { + assert_eq!( + slasher_config.database_path, + dir.path().join("beacon").join("slasher_db") + ) + } else { + panic!("Slasher config was parsed incorrectly"); + } + }); +} +#[test] +fn slasher_dir_flag() { + let dir = TempDir::new().expect("Unable to create temporary directory"); + CommandLineTest::new() + .flag("slasher", None) + .flag("slasher-dir", dir.path().as_os_str().to_str()) + .run() + .with_config(|config| { + if let Some(slasher_config) = &config.slasher { + assert_eq!(slasher_config.database_path, dir.path()); + } else { + panic!("Slasher config was parsed incorrectly"); + } + }); +} +#[test] +fn slasher_update_period_flag() { + CommandLineTest::new() + .flag("slasher", None) + .flag("slasher-update-period", Some("100")) + .run() + .with_config(|config| { + if let Some(slasher_config) = &config.slasher { + assert_eq!(slasher_config.update_period, 100); + } else { + panic!("Slasher config was parsed incorrectly"); + } + }); +} +#[test] +fn slasher_history_length_flag() { + CommandLineTest::new() + .flag("slasher", None) + .flag("slasher-history-length", Some("2048")) + .run() + .with_config(|config| { + if let Some(slasher_config) = &config.slasher { + assert_eq!(slasher_config.history_length, 2048); + } else { + panic!("Slasher config was parsed incorrectly"); + } + }); +} +#[test] +fn slasher_max_db_size_flag() { + CommandLineTest::new() + .flag("slasher", None) + .flag("slasher-max-db-size", Some("10")) + .run() + .with_config(|config| { + let slasher_config = config + .slasher + .as_ref() + .expect("Unable to parse Slasher config"); + assert_eq!(slasher_config.max_db_size_mbs, 10240); + }); +} +#[test] +fn slasher_chunk_size_flag() { + CommandLineTest::new() + .flag("slasher", None) + .flag("slasher-chunk-size", Some("32")) + .run() + .with_config(|config| { + let slasher_config = config + .slasher + .as_ref() + .expect("Unable to parse Slasher config"); + assert_eq!(slasher_config.chunk_size, 32); + }); +} +#[test] +fn slasher_validator_chunk_size_flag() { + CommandLineTest::new() + .flag("slasher", None) + .flag("slasher-validator-chunk-size", Some("512")) + .run() + .with_config(|config| { + let slasher_config = config + .slasher + .as_ref() + .expect("Unable to parse Slasher config"); + assert_eq!(slasher_config.validator_chunk_size, 512); + }); +} +#[test] +fn slasher_broadcast_flag() { + CommandLineTest::new() + .flag("slasher", None) + .flag("slasher-broadcast", None) + .run() + .with_config(|config| { + let slasher_config = config + .slasher + .as_ref() + .expect("Unable to parse Slasher config"); + assert!(slasher_config.broadcast); + }); +} +#[test] +#[should_panic] +fn ensure_panic_on_failed_launch() { + CommandLineTest::new() + .flag("slasher", None) + .flag("slasher-chunk-size", Some("10")) + .run() + .with_config(|config| { + let slasher_config = config + .slasher + .as_ref() + .expect("Unable to parse Slasher config"); + assert_eq!(slasher_config.chunk_size, 10); + }); +} + +/// A bit of hack to find an unused port. +/// +/// Does not guarantee that the given port is unused after the function exits, just that it was +/// unused before the function started (i.e., it does not reserve a port). +pub fn unused_port(transport: &str) -> Result { + let local_addr = match transport { + "tcp" => { + let listener = TcpListener::bind("127.0.0.1:0").map_err(|e| { + format!("Failed to create TCP listener to find unused port: {:?}", e) + })?; + listener.local_addr().map_err(|e| { + format!( + "Failed to read TCP listener local_addr to find unused port: {:?}", + e + ) + })? + } + "udp" => { + let socket = UdpSocket::bind("127.0.0.1:0") + .map_err(|e| format!("Failed to create UDP socket to find unused port: {:?}", e))?; + socket.local_addr().map_err(|e| { + format!( + "Failed to read UDP socket local_addr to find unused port: {:?}", + e + ) + })? + } + _ => return Err("Invalid transport to find unused port".into()), + }; + Ok(local_addr.port()) +} diff --git a/lighthouse/tests/main.rs b/lighthouse/tests/main.rs new file mode 100644 index 00000000000..c800e855d90 --- /dev/null +++ b/lighthouse/tests/main.rs @@ -0,0 +1,5 @@ +#![cfg(not(debug_assertions))] + +mod account_manager; +mod beacon_node; +mod validator_client; diff --git a/lighthouse/tests/validator_client.rs b/lighthouse/tests/validator_client.rs new file mode 100644 index 00000000000..435c45dd133 --- /dev/null +++ b/lighthouse/tests/validator_client.rs @@ -0,0 +1,346 @@ +use validator_client::Config; + +use bls::{Keypair, PublicKeyBytes}; +use serde_json::from_reader; +use std::fs::File; +use std::io::Write; +use std::net::Ipv4Addr; +use std::path::PathBuf; +use std::process::{Command, Output}; +use std::str::from_utf8; +use std::string::ToString; +use tempfile::TempDir; + +const VALIDATOR_CMD: &str = "validator_client"; +const CONFIG_NAME: &str = "vc_dump.json"; +const DUMP_CONFIG_CMD: &str = "dump-config"; +const IMMEDIATE_SHUTDOWN_CMD: &str = "immediate-shutdown"; + +/// Returns the `lighthouse validator_client --immediate-shutdown` command. +fn base_cmd() -> Command { + let lighthouse_bin = env!("CARGO_BIN_EXE_lighthouse"); + let path = lighthouse_bin + .parse::() + .expect("should parse CARGO_TARGET_DIR"); + + let mut cmd = Command::new(path); + cmd.arg(VALIDATOR_CMD) + .arg(format!("--{}", IMMEDIATE_SHUTDOWN_CMD)); + + cmd +} + +/// Executes a `Command`, returning a `Result` based upon the success exit code of the command. +fn output_result(cmd: &mut Command) -> Result { + let output = cmd.output().expect("should run command"); + + if output.status.success() { + Ok(output) + } else { + Err(from_utf8(&output.stderr) + .expect("stderr is not utf8") + .to_string()) + } +} + +// Wrapper around `Command` for easier Command Line Testing. +struct CommandLineTest { + cmd: Command, +} +impl CommandLineTest { + fn new() -> CommandLineTest { + let base_cmd = base_cmd(); + CommandLineTest { cmd: base_cmd } + } + + fn flag(mut self, flag: &str, value: Option<&str>) -> Self { + // Build the command by adding the flag and any values. + self.cmd.arg(format!("--{}", flag)); + if let Some(value) = value { + self.cmd.arg(value); + } + self + } + + fn run(&mut self) -> CompletedTest { + // Setup temp directories. + let tmp_dir = TempDir::new().expect("Unable to create temporary directory"); + let tmp_path: PathBuf = tmp_dir.path().join(CONFIG_NAME); + + // Add --datadir --dump-config to cmd. + self.cmd + .arg("--datadir") + .arg(tmp_dir.path().as_os_str()) + .arg(format!("--{}", DUMP_CONFIG_CMD)) + .arg(tmp_path.as_os_str()); + + // Run the command. + let _output = output_result(&mut self.cmd).expect("Unable to run command"); + + // Grab the config. + let config: Config = + from_reader(File::open(tmp_path).expect("Unable to open dumped config")) + .expect("Unable to deserialize to ClientConfig"); + CompletedTest { + config, + dir: tmp_dir, + } + } + + // In order to test custom validator and secrets directory flags, + // datadir cannot be defined. + fn run_with_no_datadir(&mut self) -> CompletedTest { + // Setup temp directories + let tmp_dir = TempDir::new().expect("Unable to create temporary directory"); + let tmp_path: PathBuf = tmp_dir.path().join(CONFIG_NAME); + + // Add --dump-config to cmd. + self.cmd + .arg(format!("--{}", DUMP_CONFIG_CMD)) + .arg(tmp_path.as_os_str()); + + // Run the command. + let _output = output_result(&mut self.cmd).expect("Unable to run command"); + + // Grab the config. + let config: Config = + from_reader(File::open(tmp_path).expect("Unable to open dumped config")) + .expect("Unable to deserialize to ClientConfig"); + CompletedTest { + config, + dir: tmp_dir, + } + } +} +struct CompletedTest { + config: Config, + dir: TempDir, +} +impl CompletedTest { + fn with_config(self, func: F) { + func(&self.config); + } + fn with_config_and_dir(self, func: F) { + func(&self.config, &self.dir); + } +} + +#[test] +fn datadir_flag() { + CommandLineTest::new() + .run() + .with_config_and_dir(|config, dir| { + assert_eq!(config.validator_dir, dir.path().join("validators")); + assert_eq!(config.secrets_dir, dir.path().join("secrets")); + }); +} + +#[test] +fn validators_and_secrets_dir_flags() { + let dir = TempDir::new().expect("Unable to create temporary directory"); + CommandLineTest::new() + .flag("validators-dir", dir.path().join("validators").to_str()) + .flag("secrets-dir", dir.path().join("secrets").to_str()) + .run_with_no_datadir() + .with_config(|config| { + assert_eq!(config.validator_dir, dir.path().join("validators")); + assert_eq!(config.secrets_dir, dir.path().join("secrets")); + }); +} + +#[test] +fn beacon_nodes_flag() { + CommandLineTest::new() + .flag( + "beacon-nodes", + Some("http://localhost:1001,https://project:secret@infura.io/"), + ) + .run() + .with_config(|config| { + assert_eq!( + config.beacon_nodes[0].full.to_string(), + "http://localhost:1001/" + ); + assert_eq!(config.beacon_nodes[0].to_string(), "http://localhost:1001/"); + assert_eq!( + config.beacon_nodes[1].full.to_string(), + "https://project:secret@infura.io/" + ); + assert_eq!(config.beacon_nodes[1].to_string(), "https://infura.io/"); + }); +} + +#[test] +fn allow_unsynced_flag() { + CommandLineTest::new() + .flag("allow-unsynced", None) + .run() + .with_config(|config| assert!(config.allow_unsynced_beacon_node)); +} + +#[test] +fn disable_auto_discover_flag() { + CommandLineTest::new() + .flag("disable-auto-discover", None) + .run() + .with_config(|config| assert!(config.disable_auto_discover)); +} + +#[test] +fn init_slashing_protections_flag() { + CommandLineTest::new() + .flag("init-slashing-protection", None) + .run() + .with_config(|config| assert!(config.init_slashing_protection)); +} + +// Tests for Graffiti flags. +#[test] +fn graffiti_flag() { + CommandLineTest::new() + .flag("graffiti", Some("nice-graffiti")) + .run() + .with_config(|config| { + assert_eq!( + config.graffiti.unwrap().to_string(), + "0x6e6963652d677261666669746900000000000000000000000000000000000000" + ) + }); +} +#[test] +fn graffiti_file_flag() { + let dir = TempDir::new().expect("Unable to create temporary directory"); + let mut file = File::create(dir.path().join("graffiti.txt")).expect("Unable to create file"); + let new_key = Keypair::random(); + let pubkeybytes = PublicKeyBytes::from(new_key.pk); + let contents = "default:nice-graffiti"; + file.write_all(contents.as_bytes()) + .expect("Unable to write to file"); + CommandLineTest::new() + .flag( + "graffiti-file", + dir.path().join("graffiti.txt").as_os_str().to_str(), + ) + .run() + .with_config(|config| { + // Public key not present so load default. + assert_eq!( + config + .graffiti_file + .clone() + .unwrap() + .load_graffiti(&pubkeybytes) + .unwrap() + .unwrap() + .to_string(), + "0x6e6963652d677261666669746900000000000000000000000000000000000000" + ) + }); +} +#[test] +fn graffiti_file_with_pk_flag() { + let dir = TempDir::new().expect("Unable to create temporary directory"); + let mut file = File::create(dir.path().join("graffiti.txt")).expect("Unable to create file"); + let new_key = Keypair::random(); + let pubkeybytes = PublicKeyBytes::from(new_key.pk); + let contents = format!("{}:nice-graffiti", pubkeybytes.to_string()); + file.write_all(contents.as_bytes()) + .expect("Unable to write to file"); + CommandLineTest::new() + .flag( + "graffiti-file", + dir.path().join("graffiti.txt").as_os_str().to_str(), + ) + .run() + .with_config(|config| { + assert_eq!( + config + .graffiti_file + .clone() + .unwrap() + .load_graffiti(&pubkeybytes) + .unwrap() + .unwrap() + .to_string(), + "0x6e6963652d677261666669746900000000000000000000000000000000000000" + ) + }); +} + +// Tests for HTTP flags. +#[test] +fn http_flag() { + CommandLineTest::new() + .flag("http", None) + .run() + .with_config(|config| assert!(config.http_api.enabled)); +} +#[test] +fn http_port_flag() { + CommandLineTest::new() + .flag("http-port", Some("9090")) + .run() + .with_config(|config| assert_eq!(config.http_api.listen_port, 9090)); +} +#[test] +fn http_allow_origin_flag() { + CommandLineTest::new() + .flag("http-allow-origin", Some("http://localhost:9009")) + .run() + .with_config(|config| { + assert_eq!( + config.http_api.allow_origin, + Some("http://localhost:9009".to_string()) + ); + }); +} +#[test] +fn http_allow_origin_all_flag() { + CommandLineTest::new() + .flag("http-allow-origin", Some("*")) + .run() + .with_config(|config| assert_eq!(config.http_api.allow_origin, Some("*".to_string()))); +} + +// Tests for Metrics flags. +#[test] +fn metrics_flag() { + CommandLineTest::new() + .flag("metrics", None) + .run() + .with_config(|config| assert!(config.http_metrics.enabled)); +} +#[test] +fn metrics_address_flag() { + let addr = "127.0.0.99".parse::().unwrap(); + CommandLineTest::new() + .flag("metrics-address", Some("127.0.0.99")) + .run() + .with_config(|config| assert_eq!(config.http_metrics.listen_addr, addr)); +} +#[test] +fn metrics_port_flag() { + CommandLineTest::new() + .flag("metrics-port", Some("9090")) + .run() + .with_config(|config| assert_eq!(config.http_metrics.listen_port, 9090)); +} +#[test] +fn metrics_allow_origin_flag() { + CommandLineTest::new() + .flag("metrics-allow-origin", Some("http://localhost:9009")) + .run() + .with_config(|config| { + assert_eq!( + config.http_metrics.allow_origin, + Some("http://localhost:9009".to_string()) + ); + }); +} +#[test] +fn metrics_allow_origin_all_flag() { + CommandLineTest::new() + .flag("metrics-allow-origin", Some("*")) + .run() + .with_config(|config| assert_eq!(config.http_metrics.allow_origin, Some("*".to_string()))); +} diff --git a/scripts/local_testnet/ganache_test_node.sh b/scripts/local_testnet/ganache_test_node.sh index c6bf47031a6..43a0e0e5dcf 100755 --- a/scripts/local_testnet/ganache_test_node.sh +++ b/scripts/local_testnet/ganache_test_node.sh @@ -9,5 +9,5 @@ ganache-cli \ --mnemonic "$ETH1_NETWORK_MNEMONIC" \ --port 8545 \ --blockTime 3 \ - --networkId 4242 \ - --chainId 4242 + --networkId "$NETWORK_ID" \ + --chainId "$NETWORK_ID" diff --git a/scripts/local_testnet/setup.sh b/scripts/local_testnet/setup.sh index 8200ecb475b..906d8112c2b 100755 --- a/scripts/local_testnet/setup.sh +++ b/scripts/local_testnet/setup.sh @@ -31,7 +31,7 @@ lcli \ --genesis-delay $GENESIS_DELAY \ --genesis-fork-version $GENESIS_FORK_VERSION \ --altair-fork-slot $ALTAIR_FORK_SLOT \ - --eth1-id $BOOTNODE_PORT \ + --eth1-id $NETWORK_ID \ --eth1-follow-distance 1 \ --seconds-per-eth1-block 1 \ --force @@ -55,4 +55,4 @@ lcli \ --testnet-dir $TESTNET_DIR \ $GENESIS_VALIDATOR_COUNT -echo Created genesis state in $TESTNET_DIR \ No newline at end of file +echo Created genesis state in $TESTNET_DIR diff --git a/scripts/local_testnet/vars.env b/scripts/local_testnet/vars.env index 44b5756a96c..252daeae8e8 100644 --- a/scripts/local_testnet/vars.env +++ b/scripts/local_testnet/vars.env @@ -19,7 +19,12 @@ GENESIS_VALIDATOR_COUNT=80 NODE_COUNT=4 GENESIS_DELAY=180 + +# Port for P2P communication with bootnode BOOTNODE_PORT=4242 +# Network ID and Chain ID of local eth1 test network +NETWORK_ID=4242 + # Hard fork configuration ALTAIR_FORK_SLOT=18446744073709551615 diff --git a/slasher/src/slasher.rs b/slasher/src/slasher.rs index fab807fcfeb..91cf84fc309 100644 --- a/slasher/src/slasher.rs +++ b/slasher/src/slasher.rs @@ -38,10 +38,10 @@ impl Slasher { let block_queue = BlockQueue::default(); Ok(Self { db, - attester_slashings, - proposer_slashings, attestation_queue, block_queue, + attester_slashings, + proposer_slashings, config, log, }) diff --git a/testing/eth1_test_rig/src/ganache.rs b/testing/eth1_test_rig/src/ganache.rs index 7b62db30b9a..a890f7c7133 100644 --- a/testing/eth1_test_rig/src/ganache.rs +++ b/testing/eth1_test_rig/src/ganache.rs @@ -62,8 +62,8 @@ impl GanacheInstance { child.stdout = Some(reader.into_inner()); Ok(Self { - child, port, + child, web3, network_id, chain_id, diff --git a/testing/eth1_test_rig/src/lib.rs b/testing/eth1_test_rig/src/lib.rs index e222de05eb4..716ccd35718 100644 --- a/testing/eth1_test_rig/src/lib.rs +++ b/testing/eth1_test_rig/src/lib.rs @@ -104,7 +104,7 @@ impl DepositContract { })?; Contract::from_json(web3.clone().eth(), address, ABI) .map_err(|e| format!("Failed to init contract: {:?}", e)) - .map(move |contract| Self { contract, web3 }) + .map(move |contract| Self { web3, contract }) } /// The deposit contract's address in `0x00ab...` format. diff --git a/testing/node_test_rig/Cargo.toml b/testing/node_test_rig/Cargo.toml index 0a7fd1a98cf..addd05e7e8d 100644 --- a/testing/node_test_rig/Cargo.toml +++ b/testing/node_test_rig/Cargo.toml @@ -18,3 +18,4 @@ genesis = { path = "../../beacon_node/genesis" } eth2 = { path = "../../common/eth2" } validator_client = { path = "../../validator_client" } validator_dir = { path = "../../common/validator_dir", features = ["insecure_keys"] } +sensitive_url = { path = "../../common/sensitive_url" } diff --git a/testing/node_test_rig/src/lib.rs b/testing/node_test_rig/src/lib.rs index ef84a54bd97..436b852c252 100644 --- a/testing/node_test_rig/src/lib.rs +++ b/testing/node_test_rig/src/lib.rs @@ -4,10 +4,8 @@ use beacon_node::ProductionBeaconNode; use environment::RuntimeContext; -use eth2::{ - reqwest::{ClientBuilder, Url}, - BeaconNodeHttpClient, -}; +use eth2::{reqwest::ClientBuilder, BeaconNodeHttpClient}; +use sensitive_url::SensitiveUrl; use std::path::PathBuf; use std::time::Duration; use std::time::{SystemTime, UNIX_EPOCH}; @@ -68,9 +66,10 @@ impl LocalBeaconNode { .http_api_listen_addr() .ok_or("A remote beacon node must have a http server")?; - let beacon_node_url: Url = format!("http://{}:{}", listen_addr.ip(), listen_addr.port()) - .parse() - .map_err(|e| format!("Unable to parse beacon node URL: {:?}", e))?; + let beacon_node_url: SensitiveUrl = SensitiveUrl::parse( + format!("http://{}:{}", listen_addr.ip(), listen_addr.port()).as_str(), + ) + .map_err(|e| format!("Unable to parse beacon node URL: {:?}", e))?; let beacon_node_http_client = ClientBuilder::new() .timeout(HTTP_TIMEOUT) .build() diff --git a/testing/remote_signer_test/Cargo.toml b/testing/remote_signer_test/Cargo.toml index 08dd0b5387f..1daf8c2c582 100644 --- a/testing/remote_signer_test/Cargo.toml +++ b/testing/remote_signer_test/Cargo.toml @@ -17,3 +17,4 @@ serde_json = "1.0.58" tempfile = "3.1.0" tokio = { version = "1.1.0", features = ["time"] } types = { path = "../../consensus/types" } +sensitive_url = { path = "../../common/sensitive_url" } diff --git a/testing/remote_signer_test/src/consumer.rs b/testing/remote_signer_test/src/consumer.rs index cdca7cecae9..377d0c489d1 100644 --- a/testing/remote_signer_test/src/consumer.rs +++ b/testing/remote_signer_test/src/consumer.rs @@ -1,7 +1,8 @@ use crate::*; use remote_signer_client::api_response::SignatureApiResponse; -use remote_signer_consumer::{Error, RemoteSignerHttpConsumer, RemoteSignerObject, Url}; +use remote_signer_consumer::{Error, RemoteSignerHttpConsumer, RemoteSignerObject}; use reqwest::ClientBuilder; +use sensitive_url::SensitiveUrl; use serde::Serialize; use tokio::runtime::Builder; use tokio::time::Duration; @@ -15,7 +16,7 @@ pub fn set_up_test_consumer_with_timeout( test_signer_address: &str, timeout: u64, ) -> RemoteSignerHttpConsumer { - let url: Url = test_signer_address.parse().unwrap(); + let url = SensitiveUrl::parse(test_signer_address).unwrap(); let reqwest_client = ClientBuilder::new() .timeout(Duration::from_secs(timeout)) .build() diff --git a/testing/simulator/Cargo.toml b/testing/simulator/Cargo.toml index 549520c5a0a..6733ee6327c 100644 --- a/testing/simulator/Cargo.toml +++ b/testing/simulator/Cargo.toml @@ -18,3 +18,4 @@ eth1_test_rig = { path = "../eth1_test_rig" } env_logger = "0.8.2" clap = "2.33.3" rayon = "1.4.1" +sensitive_url = { path = "../../common/sensitive_url" } diff --git a/testing/simulator/src/eth1_sim.rs b/testing/simulator/src/eth1_sim.rs index 2172aebcbce..08e960bee03 100644 --- a/testing/simulator/src/eth1_sim.rs +++ b/testing/simulator/src/eth1_sim.rs @@ -10,6 +10,7 @@ use node_test_rig::{ ClientGenesis, ValidatorFiles, }; use rayon::prelude::*; +use sensitive_url::SensitiveUrl; use std::cmp::max; use std::net::{IpAddr, Ipv4Addr}; use std::time::Duration; @@ -84,7 +85,8 @@ pub fn run_eth1_sim(matches: &ArgMatches) -> Result<(), String> { let network_id = ganache_eth1_instance.ganache.network_id(); let chain_id = ganache_eth1_instance.ganache.chain_id(); let ganache = ganache_eth1_instance.ganache; - let eth1_endpoint = ganache.endpoint(); + let eth1_endpoint = SensitiveUrl::parse(ganache.endpoint().as_str()) + .expect("Unable to parse ganache endpoint."); let deposit_contract_address = deposit_contract.address(); // Start a timer that produces eth1 blocks on an interval. @@ -133,7 +135,10 @@ pub fn run_eth1_sim(matches: &ArgMatches) -> Result<(), String> { for i in 0..node_count - 1 { let mut config = beacon_config.clone(); if i % 2 == 0 { - config.eth1.endpoints.insert(0, INVALID_ADDRESS.to_string()); + config.eth1.endpoints.insert( + 0, + SensitiveUrl::parse(INVALID_ADDRESS).expect("Unable to parse invalid address"), + ); } network.add_beacon_node(config).await?; } diff --git a/testing/simulator/src/local_network.rs b/testing/simulator/src/local_network.rs index 325487f49f3..50604040b7a 100644 --- a/testing/simulator/src/local_network.rs +++ b/testing/simulator/src/local_network.rs @@ -4,6 +4,7 @@ use node_test_rig::{ ClientConfig, LocalBeaconNode, LocalValidatorClient, ValidatorConfig, ValidatorFiles, }; use parking_lot::RwLock; +use sensitive_url::SensitiveUrl; use std::{ ops::Deref, time::{SystemTime, UNIX_EPOCH}, @@ -140,9 +141,12 @@ impl LocalNetwork { .expect("Must have http started") }; - let beacon_node = format!("http://{}:{}", socket_addr.ip(), socket_addr.port()); + let beacon_node = SensitiveUrl::parse( + format!("http://{}:{}", socket_addr.ip(), socket_addr.port()).as_str(), + ) + .unwrap(); validator_config.beacon_nodes = if invalid_first_beacon_node { - vec![INVALID_ADDRESS.to_string(), beacon_node] + vec![SensitiveUrl::parse(INVALID_ADDRESS).unwrap(), beacon_node] } else { vec![beacon_node] }; diff --git a/testing/state_transition_vectors/src/exit.rs b/testing/state_transition_vectors/src/exit.rs index 630eb08b8a2..a52ccf420d7 100644 --- a/testing/state_transition_vectors/src/exit.rs +++ b/testing/state_transition_vectors/src/exit.rs @@ -95,8 +95,8 @@ impl ExitTest { TestVector { title, - block, pre_state, + block, post_state, error, } diff --git a/validator_client/Cargo.toml b/validator_client/Cargo.toml index 30b3ce29b40..2ac165b1666 100644 --- a/validator_client/Cargo.toml +++ b/validator_client/Cargo.toml @@ -63,3 +63,4 @@ scrypt = { version = "0.5.0", default-features = false } lighthouse_metrics = { path = "../common/lighthouse_metrics" } lazy_static = "1.4.0" fallback = { path = "../common/fallback" } +sensitive_url = { path = "../common/sensitive_url" } diff --git a/validator_client/src/config.rs b/validator_client/src/config.rs index 0506565bfb3..1c01cc98361 100644 --- a/validator_client/src/config.rs +++ b/validator_client/src/config.rs @@ -7,6 +7,7 @@ use directory::{ DEFAULT_VALIDATOR_DIR, }; use eth2::types::Graffiti; +use sensitive_url::SensitiveUrl; use serde_derive::{Deserialize, Serialize}; use slog::{info, warn, Logger}; use std::fs; @@ -26,7 +27,7 @@ pub struct Config { /// The http endpoints of the beacon node APIs. /// /// Should be similar to `["http://localhost:8080"]` - pub beacon_nodes: Vec, + pub beacon_nodes: Vec, /// If true, the validator client will still poll for duties and produce blocks even if the /// beacon node is not synced at startup. pub allow_unsynced_beacon_node: bool, @@ -55,10 +56,13 @@ impl Default for Config { .join(DEFAULT_HARDCODED_NETWORK); let validator_dir = base_dir.join(DEFAULT_VALIDATOR_DIR); let secrets_dir = base_dir.join(DEFAULT_SECRET_DIR); + + let beacon_nodes = vec![SensitiveUrl::parse(DEFAULT_BEACON_NODE) + .expect("beacon_nodes must always be a valid url.")]; Self { validator_dir, secrets_dir, - beacon_nodes: vec![DEFAULT_BEACON_NODE.to_string()], + beacon_nodes, allow_unsynced_beacon_node: false, disable_auto_discover: false, init_slashing_protection: false, @@ -111,25 +115,31 @@ impl Config { } if let Some(beacon_nodes) = parse_optional::(cli_args, "beacon-nodes")? { - config.beacon_nodes = beacon_nodes.as_str().split(',').map(String::from).collect() + config.beacon_nodes = beacon_nodes + .split(',') + .map(|s| SensitiveUrl::parse(s)) + .collect::>() + .map_err(|e| format!("Unable to parse beacon node URL: {:?}", e))?; } // To be deprecated. - else if let Some(beacon_node) = parse_optional(cli_args, "beacon-node")? { + else if let Some(beacon_node) = parse_optional::(cli_args, "beacon-node")? { warn!( log, "The --beacon-node flag is deprecated"; "msg" => "please use --beacon-nodes instead" ); - config.beacon_nodes = vec![beacon_node]; + config.beacon_nodes = vec![SensitiveUrl::parse(&beacon_node) + .map_err(|e| format!("Unable to parse beacon node URL: {:?}", e))?]; } // To be deprecated. - else if let Some(server) = parse_optional(cli_args, "server")? { + else if let Some(server) = parse_optional::(cli_args, "server")? { warn!( log, "The --server flag is deprecated"; "msg" => "please use --beacon-nodes instead" ); - config.beacon_nodes = vec![server]; + config.beacon_nodes = vec![SensitiveUrl::parse(&server) + .map_err(|e| format!("Unable to parse beacon node URL: {:?}", e))?]; } if cli_args.is_present("delete-lockfiles") { @@ -227,3 +237,14 @@ impl Config { Ok(config) } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + // Ensures the default config does not panic. + fn default_config() { + Config::default(); + } +} diff --git a/validator_client/src/fork_service.rs b/validator_client/src/fork_service.rs index a69edef26b9..487038f0607 100644 --- a/validator_client/src/fork_service.rs +++ b/validator_client/src/fork_service.rs @@ -84,7 +84,7 @@ impl ForkServiceBuilder { std::time::Duration::from_secs(42), ); let candidates = vec![CandidateBeaconNode::new(eth2::BeaconNodeHttpClient::new( - eth2::Url::parse("http://127.0.0.1").unwrap(), + sensitive_url::SensitiveUrl::parse("http://127.0.0.1").unwrap(), ))]; let mut beacon_nodes = BeaconNodeFallback::new(candidates, spec, log.clone()); beacon_nodes.set_slot_clock(slot_clock); diff --git a/validator_client/src/http_api/api_secret.rs b/validator_client/src/http_api/api_secret.rs index 7f2a81d196d..d3e5c2d1253 100644 --- a/validator_client/src/http_api/api_secret.rs +++ b/validator_client/src/http_api/api_secret.rs @@ -133,7 +133,7 @@ impl ApiSecret { )); } - Ok(Self { sk, pk }) + Ok(Self { pk, sk }) } /// Returns the public key of `self` as a 0x-prefixed hex string. diff --git a/validator_client/src/http_api/tests.rs b/validator_client/src/http_api/tests.rs index fd20f1c6e04..d8c3db8246b 100644 --- a/validator_client/src/http_api/tests.rs +++ b/validator_client/src/http_api/tests.rs @@ -11,12 +11,10 @@ use account_utils::{ }; use deposit_contract::decode_eth1_tx_data; use environment::null_logger; -use eth2::{ - lighthouse_vc::{http_client::ValidatorClientHttpClient, types::*}, - Url, -}; +use eth2::lighthouse_vc::{http_client::ValidatorClientHttpClient, types::*}; use eth2_keystore::KeystoreBuilder; use parking_lot::RwLock; +use sensitive_url::SensitiveUrl; use slashing_protection::{SlashingDatabase, SLASHING_PROTECTION_FILENAME}; use slot_clock::TestingSlotClock; use std::marker::PhantomData; @@ -33,7 +31,7 @@ type E = MainnetEthSpec; struct ApiTester { client: ValidatorClientHttpClient, initialized_validators: Arc>, - url: Url, + url: SensitiveUrl, _server_shutdown: oneshot::Sender<()>, _validator_dir: TempDir, } @@ -117,7 +115,7 @@ impl ApiTester { tokio::spawn(async { server.await }); - let url = Url::parse(&format!( + let url = SensitiveUrl::parse(&format!( "http://{}:{}", listening_socket.ip(), listening_socket.port() diff --git a/validator_client/src/key_cache.rs b/validator_client/src/key_cache.rs index 6da06aaa1b2..66d69622300 100644 --- a/validator_client/src/key_cache.rs +++ b/validator_client/src/key_cache.rs @@ -1,4 +1,4 @@ -use account_utils::create_with_600_perms; +use account_utils::write_file_via_temporary; use bls::{Keypair, PublicKey}; use eth2_keystore::json_keystore::{ Aes128Ctr, ChecksumModule, Cipher, CipherModule, Crypto, EmptyMap, EmptyString, KdfModule, @@ -12,12 +12,15 @@ use rand::prelude::*; use serde::{Deserialize, Serialize}; use std::collections::HashMap; use std::fs::OpenOptions; +use std::io; use std::path::{Path, PathBuf}; -use std::{fs, io}; /// The file name for the serialized `KeyCache` struct. pub const CACHE_FILENAME: &str = "validator_key_cache.json"; +/// The file name for the temporary `KeyCache`. +pub const TEMP_CACHE_FILENAME: &str = ".validator_key_cache.json.tmp"; + #[derive(Debug, Copy, Clone, PartialEq)] pub enum State { NotDecrypted, @@ -139,17 +142,14 @@ impl KeyCache { self.encrypt()?; let cache_path = validators_dir.as_ref().join(CACHE_FILENAME); + let temp_path = validators_dir.as_ref().join(TEMP_CACHE_FILENAME); let bytes = serde_json::to_vec(self).map_err(Error::UnableToEncodeFile)?; - let res = if cache_path.exists() { - fs::write(cache_path, &bytes).map_err(Error::UnableToWriteFile) - } else { - create_with_600_perms(&cache_path, &bytes).map_err(Error::UnableToWriteFile) - }; - if res.is_ok() { - self.state = State::DecryptedAndSaved; - } - res.map(|_| true) + write_file_via_temporary(&cache_path, &temp_path, &bytes) + .map_err(Error::UnableToWriteFile)?; + + self.state = State::DecryptedAndSaved; + Ok(true) } else { Ok(false) } @@ -243,7 +243,7 @@ pub enum Error { UnableToParseFile(serde_json::Error), /// The cache file could not be serialized as YAML. UnableToEncodeFile(serde_json::Error), - /// The cache file could not be written to the filesystem. + /// The cache file or its temporary could not be written to the filesystem. UnableToWriteFile(io::Error), /// Couldn't decrypt the cache file UnableToDecrypt(KeystoreError), diff --git a/validator_client/src/lib.rs b/validator_client/src/lib.rs index 1541fce27ed..a1673146e79 100644 --- a/validator_client/src/lib.rs +++ b/validator_client/src/lib.rs @@ -28,7 +28,7 @@ use clap::ArgMatches; use duties_service::DutiesService; use environment::RuntimeContext; use eth2::types::StateId; -use eth2::{reqwest::ClientBuilder, BeaconNodeHttpClient, StatusCode, Url}; +use eth2::{reqwest::ClientBuilder, BeaconNodeHttpClient, StatusCode}; use fork_service::{ForkService, ForkServiceBuilder}; use http_api::ApiSecret; use initialized_validators::InitializedValidators; @@ -209,13 +209,9 @@ impl ProductionValidatorClient { })?; } - let beacon_node_urls: Vec = config + let beacon_nodes: Vec = config .beacon_nodes - .iter() - .map(|s| s.parse()) - .collect::>() - .map_err(|e| format!("Unable to parse beacon node URL: {:?}", e))?; - let beacon_nodes: Vec = beacon_node_urls + .clone() .into_iter() .map(|url| { let beacon_node_http_client = ClientBuilder::new()