From 2ccb358d874b92696e9f9f2da3375da7ea15e113 Mon Sep 17 00:00:00 2001 From: realbigsean Date: Tue, 4 May 2021 00:44:05 +0000 Subject: [PATCH 1/6] cargo audit fix (#2331) ## Issue Addressed `cargo audit` failing due to a vuln in `openssl` ## Proposed Changes Updates to the `Cargo.lock` made as a result of running `cargo audit fix` ## Additional Info Co-authored-by: realbigsean --- Cargo.lock | 877 +++++++++++++++++++++++++---------------------------- 1 file changed, 421 insertions(+), 456 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 10dfc69b042..2768bcd4a70 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,7 +19,7 @@ dependencies = [ "eth2_ssz_derive", "eth2_wallet", "eth2_wallet_manager", - "futures 0.3.13", + "futures 0.3.14", "hex", "libc", "rand 0.7.3", @@ -33,7 +31,7 @@ dependencies = [ "slog-term", "slot_clock", "tempfile", - "tokio 1.2.0", + "tokio 1.5.0", "types", "validator_dir", ] @@ -197,9 +195,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 +227,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 +288,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 +309,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 +339,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 +398,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 +449,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 +522,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 +587,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 +620,7 @@ dependencies = [ "strum", "task_executor", "tempfile", - "tokio 1.2.0", + "tokio 1.5.0", "tree_hash", "types", ] @@ -636,17 +635,17 @@ 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", @@ -658,17 +657,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 +827,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 +846,7 @@ dependencies = [ "eth2_libp2p", "eth2_network_config", "eth2_ssz", - "futures 0.3.13", + "futures 0.3.14", "hex", "log", "logging", @@ -858,7 +856,7 @@ dependencies = [ "slog-stdlog", "slog-term", "sloggers", - "tokio 1.2.0", + "tokio 1.5.0", "types", ] @@ -876,9 +874,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 +914,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 +980,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 +1070,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 +1083,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 +1111,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 +1182,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 +1192,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 +1273,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 +1294,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 +1307,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 +1376,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 +1395,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 +1405,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 +1436,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", @@ -1522,10 +1526,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", @@ -1567,7 +1572,7 @@ version = "0.1.0" dependencies = [ "clap", "clap_utils", - "dirs 3.0.1", + "dirs 3.0.2", "eth2_network_config", ] @@ -1584,9 +1589,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", ] @@ -1603,12 +1608,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", ] @@ -1641,7 +1646,7 @@ dependencies = [ "digest 0.9.0", "enr", "fnv", - "futures 0.3.13", + "futures 0.3.14", "hex", "hkdf", "k256", @@ -1652,9 +1657,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", @@ -1672,7 +1677,7 @@ dependencies = [ "digest 0.9.0", "enr", "fnv", - "futures 0.3.13", + "futures 0.3.14", "hex", "hkdf", "k256", @@ -1684,9 +1689,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", @@ -1695,9 +1700,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" @@ -1712,9 +1717,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", ] @@ -1849,7 +1854,7 @@ dependencies = [ "eth2_config", "eth2_network_config", "exit-future", - "futures 0.3.13", + "futures 0.3.14", "logging", "parking_lot", "slog", @@ -1858,7 +1863,7 @@ dependencies = [ "slog-term", "sloggers", "task_executor", - "tokio 1.2.0", + "tokio 1.5.0", "types", ] @@ -1883,7 +1888,7 @@ dependencies = [ "eth2_ssz", "eth2_ssz_derive", "fallback", - "futures 0.3.13", + "futures 0.3.14", "hex", "lazy_static", "libflate", @@ -1897,7 +1902,7 @@ dependencies = [ "sloggers", "state_processing", "task_executor", - "tokio 1.2.0", + "tokio 1.5.0", "tokio-compat-02", "toml", "tree_hash", @@ -1910,9 +1915,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", @@ -1928,7 +1933,7 @@ dependencies = [ "eth2_libp2p", "eth2_ssz", "eth2_ssz_derive", - "futures 0.3.13", + "futures 0.3.14", "futures-util", "hex", "libsecp256k1", @@ -2020,7 +2025,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", @@ -2028,7 +2033,7 @@ dependencies = [ "eth2_ssz_types", "exit-future", "fnv", - "futures 0.3.13", + "futures 0.3.14", "futures-io", "hashset_delay", "hex", @@ -2052,9 +2057,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", @@ -2185,19 +2190,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]] @@ -2227,9 +2220,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", ] @@ -2266,27 +2259,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]] @@ -2376,9 +2357,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", @@ -2391,9 +2372,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", @@ -2401,15 +2382,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", @@ -2419,9 +2400,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" @@ -2440,9 +2421,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", @@ -2463,15 +2444,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" @@ -2481,9 +2462,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", @@ -2528,7 +2509,7 @@ dependencies = [ "eth2_hashing", "eth2_ssz", "exit-future", - "futures 0.3.13", + "futures 0.3.14", "int_to_bytes", "merkle_proof", "parking_lot", @@ -2537,7 +2518,7 @@ dependencies = [ "serde_derive", "slog", "state_processing", - "tokio 1.2.0", + "tokio 1.5.0", "tokio-compat-02", "tree_hash", "types", @@ -2655,9 +2636,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", @@ -2667,8 +2648,8 @@ dependencies = [ "http", "indexmap", "slab", - "tokio 1.2.0", - "tokio-util 0.6.3", + "tokio 1.5.0", + "tokio-util 0.6.6", "tracing", ] @@ -2700,9 +2681,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]] @@ -2813,9 +2794,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", @@ -2834,12 +2815,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]] @@ -2855,7 +2837,7 @@ dependencies = [ "eth2_libp2p", "eth2_ssz", "fork_choice", - "futures 0.3.13", + "futures 0.3.14", "hex", "lazy_static", "lighthouse_metrics", @@ -2867,9 +2849,9 @@ dependencies = [ "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", @@ -2893,7 +2875,7 @@ dependencies = [ "slog", "slot_clock", "store", - "tokio 1.2.0", + "tokio 1.5.0", "types", "warp", "warp_utils", @@ -2901,9 +2883,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" @@ -2911,11 +2893,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", @@ -2925,7 +2913,7 @@ dependencies = [ "crossbeam-utils", "difference", "futures-util", - "hyper 0.14.4", + "hyper 0.14.7", "isahc", "lazy_static", "levenshtein", @@ -2935,7 +2923,7 @@ dependencies = [ "serde", "serde_json", "serde_regex", - "tokio 1.2.0", + "tokio 1.5.0", ] [[package]] @@ -2958,10 +2946,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", @@ -2970,23 +2958,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", @@ -2999,7 +2987,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", @@ -3030,17 +3018,17 @@ 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", ] [[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", @@ -3075,7 +3063,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", @@ -3187,20 +3175,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", @@ -3235,9 +3224,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", ] @@ -3257,9 +3246,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", @@ -3343,7 +3332,7 @@ dependencies = [ "clap_utils", "deposit_contract", "directory", - "dirs 3.0.1", + "dirs 3.0.2", "environment", "eth1_test_rig", "eth2_keystore", @@ -3351,7 +3340,7 @@ dependencies = [ "eth2_network_config", "eth2_ssz", "eth2_wallet", - "futures 0.3.13", + "futures 0.3.14", "genesis", "hex", "lighthouse_version", @@ -3362,7 +3351,7 @@ dependencies = [ "serde_yaml", "simple_logger", "state_processing", - "tokio 1.2.0", + "tokio 1.5.0", "tree_hash", "types", "validator_dir", @@ -3399,27 +3388,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" @@ -3445,7 +3436,7 @@ checksum = "adc225a49973cf9ab10d0cdd6a4b8f0cda299df9b760824bbb623f15f8f0c95a" dependencies = [ "atomic", "bytes 1.0.1", - "futures 0.3.13", + "futures 0.3.14", "lazy_static", "libp2p-core", "libp2p-dns", @@ -3460,7 +3451,7 @@ dependencies = [ "libp2p-yamux", "parity-multiaddr", "parking_lot", - "pin-project 1.0.5", + "pin-project 1.0.7", "smallvec", "wasm-timer", ] @@ -3476,7 +3467,7 @@ dependencies = [ "ed25519-dalek", "either", "fnv", - "futures 0.3.13", + "futures 0.3.14", "futures-timer", "lazy_static", "libsecp256k1", @@ -3485,7 +3476,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", @@ -3505,7 +3496,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", ] @@ -3521,7 +3512,7 @@ dependencies = [ "byteorder", "bytes 1.0.1", "fnv", - "futures 0.3.13", + "futures 0.3.14", "hex_fmt", "libp2p-core", "libp2p-swarm", @@ -3542,7 +3533,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", @@ -3560,7 +3551,7 @@ checksum = "350ce8b3923594aedabd5d6e3f875d058435052a29c3f32df378bc70d10be464" dependencies = [ "asynchronous-codec", "bytes 1.0.1", - "futures 0.3.13", + "futures 0.3.14", "libp2p-core", "log", "nohash-hasher", @@ -3578,7 +3569,7 @@ checksum = "4aca322b52a0c5136142a7c3971446fb1e9964923a526c9cc6ef3b7c94e57778" dependencies = [ "bytes 1.0.1", "curve25519-dalek", - "futures 0.3.13", + "futures 0.3.14", "lazy_static", "libp2p-core", "log", @@ -3599,7 +3590,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", @@ -3625,7 +3616,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", @@ -3633,8 +3624,8 @@ dependencies = [ "libc", "libp2p-core", "log", - "socket2", - "tokio 1.2.0", + "socket2 0.3.19", + "tokio 1.5.0", ] [[package]] @@ -3644,7 +3635,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", @@ -3661,7 +3652,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", @@ -3697,9 +3688,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", @@ -3722,7 +3713,7 @@ dependencies = [ "env_logger 0.8.3", "environment", "eth2_network_config", - "futures 0.3.13", + "futures 0.3.14", "lazy_static", "lighthouse_metrics", "lighthouse_version", @@ -3734,7 +3725,7 @@ dependencies = [ "slog-term", "sloggers", "tempfile", - "tokio 1.2.0", + "tokio 1.5.0", "types", "validator_client", "validator_dir", @@ -3787,9 +3778,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", ] @@ -3876,15 +3867,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", ] @@ -3929,15 +3920,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" @@ -3969,13 +3951,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", ] @@ -3988,7 +3970,7 @@ checksum = "0840c1c50fd55e521b247f949c241c9997709f23bd7f023b9762cd561e935656" dependencies = [ "log", "mio 0.6.23", - "miow 0.3.6", + "miow 0.3.7", "winapi 0.3.9", ] @@ -4017,11 +3999,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", ] @@ -4054,9 +4035,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" @@ -4083,9 +4064,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", ] @@ -4108,16 +4089,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" @@ -4142,7 +4113,7 @@ dependencies = [ "eth2_ssz_types", "exit-future", "fnv", - "futures 0.3.13", + "futures 0.3.14", "genesis", "hashset_delay", "hex", @@ -4169,9 +4140,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", ] @@ -4215,7 +4186,7 @@ dependencies = [ "environment", "eth2", "eth2_config", - "futures 0.3.13", + "futures 0.3.14", "genesis", "reqwest", "serde", @@ -4352,15 +4323,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", ] @@ -4372,18 +4343,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", @@ -4415,9 +4386,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", @@ -4469,7 +4440,7 @@ dependencies = [ "cfg-if 1.0.0", "instant", "libc", - "redox_syscall 0.2.5", + "redox_syscall 0.2.7", "smallvec", "winapi 0.3.9", ] @@ -4519,33 +4490,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", @@ -4554,9 +4525,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", @@ -4632,11 +4603,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", @@ -4736,9 +4707,9 @@ checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086" [[package]] name = "proc-macro2" -version = "1.0.24" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" +checksum = "a152013215dca273577e18d2bf00fa862b89b24169fb78c4c95aeb07992c9cec" dependencies = [ "unicode-xid", ] @@ -4835,15 +4806,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", @@ -5072,9 +5043,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", ] @@ -5097,19 +5068,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]] @@ -5124,9 +5094,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" @@ -5166,8 +5136,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", @@ -5186,7 +5156,7 @@ dependencies = [ "remote_signer_test", "reqwest", "serde", - "tokio 1.2.0", + "tokio 1.5.0", "types", ] @@ -5204,7 +5174,7 @@ dependencies = [ "serde", "serde_json", "tempfile", - "tokio 1.2.0", + "tokio 1.5.0", "types", ] @@ -5219,9 +5189,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", @@ -5229,8 +5199,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", @@ -5243,7 +5213,7 @@ dependencies = [ "serde", "serde_json", "serde_urlencoded", - "tokio 1.2.0", + "tokio 1.5.0", "tokio-native-tls", "url", "wasm-bindgen", @@ -5331,9 +5301,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" @@ -5358,9 +5328,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", @@ -5381,8 +5351,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", ] @@ -5465,9 +5435,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", @@ -5493,9 +5463,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", @@ -5506,9 +5476,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", @@ -5531,9 +5501,9 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[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", ] @@ -5550,9 +5520,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", @@ -5692,9 +5662,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", @@ -5740,26 +5710,26 @@ 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", + "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" @@ -5802,7 +5772,7 @@ dependencies = [ "slot_clock", "state_processing", "task_executor", - "tokio 1.2.0", + "tokio 1.5.0", "tokio-stream", "types", ] @@ -5948,9 +5918,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" @@ -5981,6 +5951,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" @@ -5990,7 +5970,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", @@ -6003,20 +5983,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", ] @@ -6210,9 +6181,9 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.62" +version = "1.0.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "123a78a3596b24fee53a6464ce52d8ecbf62241e6294c7e7fe12086cd161f512" +checksum = "ad184cc9470f9117b2ac6817bfe297307418819ba40552f9b3846f05c33d5373" dependencies = [ "proc-macro2", "quote", @@ -6254,11 +6225,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]] @@ -6270,7 +6241,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", ] @@ -6373,9 +6344,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", @@ -6414,12 +6385,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", ] @@ -6471,9 +6442,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", ] @@ -6521,15 +6492,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", @@ -6559,7 +6530,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]] @@ -6591,19 +6562,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]] @@ -6624,8 +6595,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", ] @@ -6660,9 +6631,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", @@ -6671,7 +6642,7 @@ dependencies = [ "log", "pin-project-lite 0.2.6", "slab", - "tokio 1.2.0", + "tokio 1.5.0", ] [[package]] @@ -6691,9 +6662,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", @@ -6704,9 +6675,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", @@ -6715,9 +6686,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", ] @@ -6728,7 +6699,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", ] @@ -6755,9 +6726,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", @@ -6777,9 +6748,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", ] @@ -6865,9 +6836,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" @@ -6940,9 +6911,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", ] @@ -6970,9 +6941,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" @@ -6997,7 +6968,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]] @@ -7030,9 +7001,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" @@ -7055,7 +7026,7 @@ dependencies = [ "clap_utils", "deposit_contract", "directory", - "dirs 3.0.1", + "dirs 3.0.2", "environment", "eth2", "eth2_config", @@ -7065,9 +7036,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", @@ -7092,7 +7063,7 @@ dependencies = [ "slog-term", "slot_clock", "tempfile", - "tokio 1.2.0", + "tokio 1.5.0", "tree_hash", "types", "validator_dir", @@ -7129,15 +7100,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" @@ -7147,9 +7112,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" @@ -7165,9 +7130,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", @@ -7190,24 +7155,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", @@ -7225,7 +7190,7 @@ dependencies = [ "safe_arith", "serde", "state_processing", - "tokio 1.2.0", + "tokio 1.5.0", "types", "warp", ] @@ -7244,9 +7209,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", @@ -7256,9 +7221,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", @@ -7271,9 +7236,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", @@ -7283,9 +7248,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", @@ -7293,9 +7258,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", @@ -7306,15 +7271,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", @@ -7326,9 +7291,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", @@ -7340,7 +7305,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", @@ -7351,9 +7316,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", @@ -7371,7 +7336,7 @@ dependencies = [ "derive_more", "ethabi", "ethereum-types", - "futures 0.3.13", + "futures 0.3.14", "futures-timer", "hex", "hyper 0.13.10", @@ -7381,7 +7346,7 @@ dependencies = [ "log", "native-tls", "parking_lot", - "pin-project 1.0.5", + "pin-project 1.0.7", "rlp 0.4.6", "secp256k1", "serde", @@ -7406,9 +7371,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", ] @@ -7424,12 +7389,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]] @@ -7502,9 +7467,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", @@ -7519,9 +7484,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", ] @@ -7541,7 +7506,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", @@ -7551,18 +7516,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", @@ -7572,9 +7537,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", From 4cc613d644b3f077328b5728ed61b6dc2095e974 Mon Sep 17 00:00:00 2001 From: Mac L Date: Tue, 4 May 2021 01:59:51 +0000 Subject: [PATCH 2/6] Add `SensitiveUrl` to redact user secrets from endpoints (#2326) ## Issue Addressed #2276 ## Proposed Changes Add the `SensitiveUrl` struct which wraps `Url` and implements custom `Display` and `Debug` traits to redact user secrets from being logged in eth1 endpoints, beacon node endpoints and metrics. ## Additional Info This also includes a small rewrite of the eth1 crate to make requests using `Url` instead of `&str`. Some error messages have also been changed to remove `Url` data. --- Cargo.lock | 20 ++++ Cargo.toml | 1 + account_manager/Cargo.toml | 1 + account_manager/src/validator/exit.rs | 5 +- beacon_node/Cargo.toml | 1 + beacon_node/eth1/Cargo.toml | 1 + beacon_node/eth1/src/http.rs | 21 ++-- beacon_node/eth1/src/service.rs | 50 ++++++--- beacon_node/eth1/tests/test.rs | 45 +++++--- beacon_node/genesis/Cargo.toml | 1 + beacon_node/genesis/tests/tests.rs | 3 +- beacon_node/http_api/Cargo.toml | 1 + beacon_node/http_api/tests/tests.rs | 7 +- beacon_node/src/config.rs | 15 ++- common/eth2/Cargo.toml | 1 + common/eth2/src/lib.rs | 13 ++- common/eth2/src/lighthouse.rs | 20 ++-- common/eth2/src/lighthouse_vc/http_client.rs | 25 +++-- common/remote_signer_consumer/Cargo.toml | 1 + .../remote_signer_consumer/src/http_client.rs | 7 +- common/remote_signer_consumer/src/lib.rs | 8 +- common/remote_signer_consumer/tests/post.rs | 38 +++---- common/sensitive_url/Cargo.toml | 11 ++ common/sensitive_url/src/lib.rs | 105 ++++++++++++++++++ lcli/Cargo.toml | 1 + lcli/src/eth1_genesis.rs | 7 +- testing/node_test_rig/Cargo.toml | 1 + testing/node_test_rig/src/lib.rs | 13 +-- testing/remote_signer_test/Cargo.toml | 1 + testing/remote_signer_test/src/consumer.rs | 5 +- testing/simulator/Cargo.toml | 1 + testing/simulator/src/eth1_sim.rs | 9 +- testing/simulator/src/local_network.rs | 8 +- validator_client/Cargo.toml | 1 + validator_client/src/config.rs | 35 ++++-- validator_client/src/fork_service.rs | 2 +- validator_client/src/http_api/tests.rs | 10 +- validator_client/src/lib.rs | 10 +- 38 files changed, 362 insertions(+), 143 deletions(-) create mode 100644 common/sensitive_url/Cargo.toml create mode 100644 common/sensitive_url/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 2768bcd4a70..c3290ebc80a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -25,6 +25,7 @@ dependencies = [ "rand 0.7.3", "rayon", "safe_arith", + "sensitive_url", "slashing_protection", "slog", "slog-async", @@ -650,6 +651,7 @@ dependencies = [ "logging", "node_test_rig", "rand 0.7.3", + "sensitive_url", "serde", "slasher", "slog", @@ -1896,6 +1898,7 @@ dependencies = [ "merkle_proof", "parking_lot", "reqwest", + "sensitive_url", "serde", "serde_json", "slog", @@ -1942,6 +1945,7 @@ dependencies = [ "psutil", "reqwest", "ring", + "sensitive_url", "serde", "serde_json", "serde_utils", @@ -2514,6 +2518,7 @@ dependencies = [ "merkle_proof", "parking_lot", "rayon", + "sensitive_url", "serde", "serde_derive", "slog", @@ -2844,6 +2849,7 @@ dependencies = [ "lighthouse_version", "network", "parking_lot", + "sensitive_url", "serde", "slog", "slot_clock", @@ -3347,6 +3353,7 @@ dependencies = [ "log", "rand 0.7.3", "regex", + "sensitive_url", "serde", "serde_yaml", "simple_logger", @@ -4189,6 +4196,7 @@ dependencies = [ "futures 0.3.14", "genesis", "reqwest", + "sensitive_url", "serde", "tempfile", "types", @@ -5155,6 +5163,7 @@ dependencies = [ "rand 0.7.3", "remote_signer_test", "reqwest", + "sensitive_url", "serde", "tokio 1.5.0", "types", @@ -5171,6 +5180,7 @@ dependencies = [ "remote_signer_client", "remote_signer_consumer", "reqwest", + "sensitive_url", "serde", "serde_json", "tempfile", @@ -5499,6 +5509,14 @@ 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.125" @@ -5714,6 +5732,7 @@ dependencies = [ "node_test_rig", "parking_lot", "rayon", + "sensitive_url", "tokio 1.5.0", "types", "validator_client", @@ -7052,6 +7071,7 @@ dependencies = [ "ring", "safe_arith", "scrypt", + "sensitive_url", "serde", "serde_derive", "serde_json", 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 7d57ebcf662..0cf066610a2 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/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..547715a0638 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; @@ -79,7 +80,7 @@ impl FromStr for Eth1Id { } /// 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/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 c5fd2192841..d9ed1808606 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/tests/tests.rs b/beacon_node/http_api/tests/tests.rs index 6027d76a864..6d1dfbf55ad 100644 --- a/beacon_node/http_api/tests/tests.rs +++ b/beacon_node/http_api/tests/tests.rs @@ -8,7 +8,7 @@ use discv5::enr::{CombinedKey, EnrBuilder}; 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}, @@ -18,6 +18,7 @@ use futures::stream::{Stream, StreamExt}; use futures::FutureExt; use http_api::{Config, Context}; use network::NetworkMessage; +use sensitive_url::SensitiveUrl; use slot_clock::SlotClock; use state_processing::per_slot_processing; use std::convert::TryInto; @@ -200,7 +201,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() @@ -307,7 +308,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/src/config.rs b/beacon_node/src/config.rs index 256f7e04fb4..20e8e64d992 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") { 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 13c117b3296..5e1b434601d 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 ssz::Decode; use std::convert::TryFrom; @@ -36,7 +37,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. @@ -81,7 +82,7 @@ impl fmt::Display for Error { #[derive(Clone)] pub struct BeaconNodeHttpClient { client: reqwest::Client, - server: Url, + server: SensitiveUrl, } impl fmt::Display for BeaconNodeHttpClient { @@ -92,25 +93,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 a879b7c8db0..7ea051e2ec4 100644 --- a/common/eth2/src/lighthouse.rs +++ b/common/eth2/src/lighthouse.rs @@ -214,7 +214,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()))? @@ -226,7 +226,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()))? @@ -246,7 +246,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()))? @@ -261,7 +261,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()))? @@ -279,7 +279,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()))? @@ -295,7 +295,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()))? @@ -310,7 +310,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()))? @@ -325,7 +325,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 { &self, state_id: &StateId, ) -> 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 2258e93a2bc..6cb1bf33881 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/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 530295021e0..d929b1784c4 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; @@ -50,7 +51,11 @@ pub fn run(mut env: Environment, matches: &ArgMatches<'_>) -> Res 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/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/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/tests.rs b/validator_client/src/http_api/tests.rs index d7fcc38c1f7..2a748059c7f 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/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() From bacc38c3da2daed7fb92ab196a65440208dd1e8f Mon Sep 17 00:00:00 2001 From: Mac L Date: Thu, 6 May 2021 00:36:22 +0000 Subject: [PATCH 3/6] Add testing for beacon node and validator client CLI flags (#2311) ## Issue Addressed N/A ## Proposed Changes Add unit tests for the various CLI flags associated with the beacon node and validator client. These changes require the addition of two new flags: `dump-config` and `immediate-shutdown`. ## Additional Info Both `dump-config` and `immediate-shutdown` are marked as hidden since they should only be used in testing and other advanced use cases. **Note:** This requires changing `main.rs` so that the flags can adjust the program behavior as necessary. Co-authored-by: Paul Hauner --- Cargo.lock | 3 + beacon_node/beacon_chain/src/beacon_chain.rs | 10 +- beacon_node/beacon_chain/src/builder.rs | 5 +- beacon_node/beacon_chain/src/errors.rs | 3 +- beacon_node/beacon_chain/src/test_utils.rs | 3 +- beacon_node/eth2_libp2p/tests/common/mod.rs | 2 +- beacon_node/network/src/service.rs | 13 +- beacon_node/src/config.rs | 2 +- common/task_executor/src/lib.rs | 24 +- lighthouse/Cargo.toml | 8 + lighthouse/environment/src/lib.rs | 16 +- lighthouse/src/main.rs | 87 +- lighthouse/tests/account_manager.rs | 6 +- lighthouse/tests/beacon_node.rs | 841 +++++++++++++++++++ lighthouse/tests/main.rs | 5 + lighthouse/tests/validator_client.rs | 346 ++++++++ 16 files changed, 1327 insertions(+), 47 deletions(-) create mode 100644 lighthouse/tests/beacon_node.rs create mode 100644 lighthouse/tests/main.rs create mode 100644 lighthouse/tests/validator_client.rs diff --git a/Cargo.lock b/Cargo.lock index c3290ebc80a..a0ced6cf841 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3719,6 +3719,7 @@ dependencies = [ "directory", "env_logger 0.8.3", "environment", + "eth2_libp2p", "eth2_network_config", "futures 0.3.14", "lazy_static", @@ -3726,11 +3727,13 @@ dependencies = [ "lighthouse_version", "logging", "remote_signer", + "serde_json", "slashing_protection", "slog", "slog-async", "slog-term", "sloggers", + "task_executor", "tempfile", "tokio 1.5.0", "types", diff --git a/beacon_node/beacon_chain/src/beacon_chain.rs b/beacon_node/beacon_chain/src/beacon_chain.rs index 94079f02802..7fa306b0933 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. @@ -1699,7 +1700,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); } @@ -2811,7 +2815,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 63d2918b5a9..f905ef0ae60 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, @@ -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/test_utils.rs b/beacon_node/beacon_chain/src/test_utils.rs index c1b1ed75e29..8f89fb63f52 100644 --- a/beacon_node/beacon_chain/src/test_utils.rs +++ b/beacon_node/beacon_chain/src/test_utils.rs @@ -25,6 +25,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::{ @@ -115,7 +116,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/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/network/src/service.rs b/beacon_node/network/src/service.rs index a25ec10389d..082c1353fbf 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 20e8e64d992..0550e8e0850 100644 --- a/beacon_node/src/config.rs +++ b/beacon_node/src/config.rs @@ -643,7 +643,7 @@ pub fn get_eth2_network_config(cli_args: &ArgMatches) -> Result &'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/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 fee7369ac39..7cde85991d2 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, V012LegacyEthSpec}; @@ -314,9 +314,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, @@ -365,7 +365,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 @@ -398,11 +398,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 acbc80a8468..636b9d81d74 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; @@ -125,6 +127,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()) @@ -285,6 +304,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); @@ -292,7 +320,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.", + )); } }); } @@ -302,23 +334,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) { @@ -327,7 +370,7 @@ fn run( .core_context() .executor .shutdown_sender() - .try_send("Failed to start remote signer"); + .try_send(ShutdownReason::Failure("Failed to start remote signer")); } } _ => { @@ -337,12 +380,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()))); +} From cb47388ad7221cb8efa5ba04685a938f021f18b9 Mon Sep 17 00:00:00 2001 From: ethDreamer Date: Mon, 10 May 2021 00:53:09 +0000 Subject: [PATCH 4/6] Updated to comply with new clippy formatting rules (#2336) ## Issue Addressed The latest version of Rust has new clippy rules & the codebase isn't up to date with them. ## Proposed Changes Small formatting changes that clippy tells me are functionally equivalent --- beacon_node/beacon_chain/src/builder.rs | 2 +- beacon_node/beacon_chain/src/eth1_chain.rs | 8 +++----- beacon_node/eth1/src/http.rs | 2 +- beacon_node/eth2_libp2p/src/discovery/enr_ext.rs | 2 +- beacon_node/eth2_libp2p/src/service.rs | 4 ++-- beacon_node/eth2_libp2p/src/types/topics.rs | 9 ++++++--- beacon_node/http_api/src/lib.rs | 6 +++--- .../network/src/beacon_processor/worker/rpc_methods.rs | 5 +---- consensus/types/src/slot_epoch_macros.rs | 6 ++---- slasher/src/slasher.rs | 4 ++-- testing/eth1_test_rig/src/ganache.rs | 2 +- testing/eth1_test_rig/src/lib.rs | 2 +- testing/state_transition_vectors/src/exit.rs | 2 +- validator_client/src/http_api/api_secret.rs | 2 +- 14 files changed, 26 insertions(+), 30 deletions(-) diff --git a/beacon_node/beacon_chain/src/builder.rs b/beacon_node/beacon_chain/src/builder.rs index f905ef0ae60..237e61414b6 100644 --- a/beacon_node/beacon_chain/src/builder.rs +++ b/beacon_node/beacon_chain/src/builder.rs @@ -306,8 +306,8 @@ where })?; let genesis = BeaconSnapshot { - beacon_block_root, beacon_block, + beacon_block_root, beacon_state, }; diff --git a/beacon_node/beacon_chain/src/eth1_chain.rs b/beacon_node/beacon_chain/src/eth1_chain.rs index ed74ff6e411..c269b8c513a 100644 --- a/beacon_node/beacon_chain/src/eth1_chain.rs +++ b/beacon_node/beacon_chain/src/eth1_chain.rs @@ -612,11 +612,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/eth1/src/http.rs b/beacon_node/eth1/src/http.rs index 547715a0638..9ec7576d284 100644 --- a/beacon_node/eth1/src/http.rs +++ b/beacon_node/eth1/src/http.rs @@ -73,7 +73,7 @@ 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)) } 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/http_api/src/lib.rs b/beacon_node/http_api/src/lib.rs index 653820367c1..325b2898865 100644 --- a/beacon_node/http_api/src/lib.rs +++ b/beacon_node/http_api/src/lib.rs @@ -1355,7 +1355,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)) }) @@ -1623,10 +1623,10 @@ pub fn serve( }); Ok(api_types::GenericResponse::from(api_types::PeerCount { - disconnecting, - connecting, connected, + connecting, disconnected, + disconnecting, })) }) }); 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/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/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/state_transition_vectors/src/exit.rs b/testing/state_transition_vectors/src/exit.rs index 10843f9d264..99b8122accc 100644 --- a/testing/state_transition_vectors/src/exit.rs +++ b/testing/state_transition_vectors/src/exit.rs @@ -83,8 +83,8 @@ impl ExitTest { TestVector { title, - block, pre_state, + block, post_state, error, } 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. From 480b2478289154fdb74e1564970238e83bbce5e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rio=20Havel?= Date: Wed, 12 May 2021 00:51:20 +0000 Subject: [PATCH 5/6] Add NETWORK_ID variable (#2330) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Same variable BOOTNODE_PORT was used for p2p port of bootnode and testnet Chain and Network ID. Adding variable NETWORK_ID to make scripts less confusing and create option to choose arbitrary ID. Co-authored-by: Mário Havel <61149543+taxmeifyoucan@users.noreply.github.com> Co-authored-by: Michael Sproul --- scripts/local_testnet/ganache_test_node.sh | 4 ++-- scripts/local_testnet/setup.sh | 4 ++-- scripts/local_testnet/vars.env | 5 +++++ 3 files changed, 9 insertions(+), 4 deletions(-) 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 42fe217ac87..ad0e0537527 100755 --- a/scripts/local_testnet/setup.sh +++ b/scripts/local_testnet/setup.sh @@ -30,7 +30,7 @@ lcli \ --min-genesis-time $GENESIS_TIME \ --genesis-delay $GENESIS_DELAY \ --genesis-fork-version $GENESIS_FORK_VERSION \ - --eth1-id $BOOTNODE_PORT \ + --eth1-id $NETWORK_ID \ --eth1-follow-distance 1 \ --seconds-per-eth1-block 1 \ --force @@ -54,4 +54,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 73202105333..356ddc9d98a 100644 --- a/scripts/local_testnet/vars.env +++ b/scripts/local_testnet/vars.env @@ -19,4 +19,9 @@ 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 From 58e52f8f402210db1bd44a8d78136e5f40d30a57 Mon Sep 17 00:00:00 2001 From: Michael Sproul Date: Wed, 12 May 2021 02:04:44 +0000 Subject: [PATCH 6/6] Write validator definitions atomically (#2338) ## Issue Addressed Closes https://github.com/sigp/lighthouse/issues/2159 ## Proposed Changes Rather than trying to write the validator definitions to disk directly, use a temporary file called `.validator_defintions.yml.tmp` and then atomically rename it to `validator_definitions.yml`. This avoids truncating the primary file, which can cause permanent damage when the disk is full. The same treatment is also applied to the validator key cache, although the situation is less dire if it becomes corrupted because it can just be deleted without the user having to reimport keys or resupply passwords. ## Additional Info * `File::create` truncates upon opening: https://doc.rust-lang.org/std/fs/struct.File.html#method.create * `fs::rename` uses `rename` on UNIX and `MoveFileEx` on Windows: https://doc.rust-lang.org/std/fs/fn.rename.html * UNIX `rename` call is atomic: https://unix.stackexchange.com/questions/322038/is-mv-atomic-on-my-fs * Windows `MoveFileEx` is _not_ atomic in general, and Windows lacks any clear API for atomic file renames :( https://stackoverflow.com/questions/167414/is-an-atomic-file-rename-with-overwrite-possible-on-windows ## Further Work * Consider whether we want to try a different Windows syscall as part of #2333. The `rust-atomicwrites` crate seems promising, but actually uses the same syscall under the hood presently: https://github.com/untitaker/rust-atomicwrites/issues/27. --- common/account_utils/src/lib.rs | 26 +++++++++++++++ .../src/validator_definitions.rs | 32 +++++++++++-------- validator_client/src/key_cache.rs | 24 +++++++------- 3 files changed, 57 insertions(+), 25 deletions(-) diff --git a/common/account_utils/src/lib.rs b/common/account_utils/src/lib.rs index 1ec15fa4e23..3832801486c 100644 --- a/common/account_utils/src/lib.rs +++ b/common/account_utils/src/lib.rs @@ -76,6 +76,32 @@ pub fn create_with_600_perms>(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/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),