diff --git a/.dockerignore b/.dockerignore index f5e4c0356f..151898ca7d 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,2 +1,5 @@ tests/ef_tests/eth2.0-spec-tests target/ +*.data +*.tar.gz +.git diff --git a/Cargo.lock b/Cargo.lock index 463af8a09c..e4575f4d9c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -135,14 +135,15 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "atty" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ + "hermit-abi 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -168,7 +169,7 @@ name = "backtrace-sys" version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -326,7 +327,7 @@ dependencies = [ [[package]] name = "blake2b_simd" -version = "0.5.9" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -400,7 +401,7 @@ dependencies = [ [[package]] name = "bumpalo" -version = "2.6.0" +version = "3.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -470,7 +471,7 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.48" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -494,7 +495,7 @@ version = "2.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", + "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -507,7 +508,7 @@ name = "clear_on_drop" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -543,7 +544,7 @@ dependencies = [ "toml 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", "tree_hash 0.1.1", "types 0.1.0", - "url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "websocket_server 0.1.0", ] @@ -560,7 +561,7 @@ name = "colored" version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", + "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -586,7 +587,7 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen 0.2.56 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -665,11 +666,11 @@ name = "criterion" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", + "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", "cast 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", "criterion-plot 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "csv 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "csv 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", @@ -798,7 +799,7 @@ dependencies = [ [[package]] name = "csv" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bstr 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -962,7 +963,7 @@ dependencies = [ "clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "curve25519-dalek 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1005,12 +1006,13 @@ dependencies = [ [[package]] name = "enr" version = "0.1.0" -source = "git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e#c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e" +source = "git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760#735313ebda6a98604929f6c4606aefac19e00760" dependencies = [ "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "bs58 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", "hex 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.13.2 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", + "libp2p-core 0.13.2 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", "libsecp256k1 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1024,7 +1026,7 @@ name = "env_logger" version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", + "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", "humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1036,7 +1038,7 @@ name = "env_logger" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", + "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", "humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1117,7 +1119,7 @@ version = "0.1.0" dependencies = [ "base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "dirs 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "enr 0.1.0 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", + "enr 0.1.0 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", "error-chain 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", "eth2_ssz 0.1.2", "eth2_ssz_derive 0.1.0", @@ -1125,12 +1127,12 @@ dependencies = [ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p 0.13.2 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", + "libp2p 0.13.2 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", "lighthouse_metrics 0.1.0", "lru 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "slog-async 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "slog-stdlog 4.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1160,8 +1162,8 @@ dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "ring 0.16.9 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-test 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-test 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1295,7 +1297,7 @@ dependencies = [ "fixed-hash 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "impl-rlp 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "impl-serde 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "primitive-types 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "primitive-types 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "uint 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1324,7 +1326,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)", "synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1480,12 +1482,12 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.1.13" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1537,7 +1539,7 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1707,7 +1709,7 @@ name = "impl-codec" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1726,6 +1728,14 @@ dependencies = [ "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "impl-serde" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "indexmap" version = "1.3.0" @@ -1776,10 +1786,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "js-sys" -version = "0.3.33" +version = "0.3.35" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "wasm-bindgen 0.2.56 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1883,35 +1893,35 @@ dependencies = [ [[package]] name = "libp2p" version = "0.13.2" -source = "git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e#c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e" +source = "git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760#735313ebda6a98604929f6c4606aefac19e00760" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "enr 0.1.0 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", + "enr 0.1.0 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.13.2 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", - "libp2p-core-derive 0.13.0 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", - "libp2p-deflate 0.5.0 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", - "libp2p-discv5 0.1.0 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", - "libp2p-dns 0.13.0 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", - "libp2p-floodsub 0.13.1 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", - "libp2p-gossipsub 0.1.0 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", - "libp2p-identify 0.13.2 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", - "libp2p-kad 0.13.2 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", - "libp2p-mdns 0.13.1 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", - "libp2p-mplex 0.13.0 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", - "libp2p-noise 0.11.1 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", - "libp2p-ping 0.13.1 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", - "libp2p-plaintext 0.13.1 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", - "libp2p-secio 0.13.1 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", - "libp2p-swarm 0.3.0 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", - "libp2p-tcp 0.13.0 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", - "libp2p-uds 0.13.0 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", - "libp2p-wasm-ext 0.6.0 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", - "libp2p-websocket 0.13.0 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", - "libp2p-yamux 0.13.0 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", - "parity-multiaddr 0.6.0 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", - "parity-multihash 0.2.0 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", + "libp2p-core 0.13.2 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", + "libp2p-core-derive 0.13.0 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", + "libp2p-deflate 0.5.0 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", + "libp2p-discv5 0.1.0 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", + "libp2p-dns 0.13.0 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", + "libp2p-floodsub 0.13.1 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", + "libp2p-gossipsub 0.1.0 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", + "libp2p-identify 0.13.2 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", + "libp2p-kad 0.13.2 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", + "libp2p-mdns 0.13.1 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", + "libp2p-mplex 0.13.0 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", + "libp2p-noise 0.11.1 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", + "libp2p-ping 0.13.1 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", + "libp2p-plaintext 0.13.1 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", + "libp2p-secio 0.13.1 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", + "libp2p-swarm 0.3.0 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", + "libp2p-tcp 0.13.0 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", + "libp2p-uds 0.13.0 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", + "libp2p-wasm-ext 0.6.0 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", + "libp2p-websocket 0.13.0 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", + "libp2p-yamux 0.13.0 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", + "parity-multiaddr 0.6.0 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", + "parity-multihash 0.2.0 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1923,7 +1933,7 @@ dependencies = [ [[package]] name = "libp2p-core" version = "0.13.2" -source = "git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e#c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e" +source = "git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760#735313ebda6a98604929f6c4606aefac19e00760" dependencies = [ "asn1_der 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", "bs58 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1935,16 +1945,16 @@ dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "libsecp256k1 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "multistream-select 0.6.1 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", - "parity-multiaddr 0.6.0 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", - "parity-multihash 0.2.0 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", + "multistream-select 0.6.1 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", + "parity-multiaddr 0.6.0 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", + "parity-multihash 0.2.0 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "protobuf 2.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "quick-error 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "ring 0.16.9 (registry+https://github.com/rust-lang/crates.io-index)", - "rw-stream-sink 0.1.2 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", - "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rw-stream-sink 0.1.2 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", + "sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1958,46 +1968,46 @@ dependencies = [ [[package]] name = "libp2p-core-derive" version = "0.13.0" -source = "git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e#c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e" +source = "git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760#735313ebda6a98604929f6c4606aefac19e00760" dependencies = [ "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "libp2p-deflate" version = "0.5.0" -source = "git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e#c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e" +source = "git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760#735313ebda6a98604929f6c4606aefac19e00760" dependencies = [ "flate2 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.13.2 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", + "libp2p-core 0.13.2 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "libp2p-discv5" version = "0.1.0" -source = "git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e#c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e" +source = "git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760#735313ebda6a98604929f6c4606aefac19e00760" dependencies = [ "arrayvec 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "bigint 4.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "enr 0.1.0 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", + "enr 0.1.0 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "hex 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "hkdf 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.13.2 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", - "libp2p-swarm 0.3.0 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", + "libp2p-core 0.13.2 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", + "libp2p-swarm 0.3.0 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", "libsecp256k1 0.3.1 (git+https://github.com/SigP/libsecp256k1?branch=ecdh_generalise)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "openssl 0.10.26 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-multiaddr 0.6.0 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", - "parity-multihash 0.2.0 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", + "parity-multiaddr 0.6.0 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", + "parity-multihash 0.2.0 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-timer 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2009,10 +2019,10 @@ dependencies = [ [[package]] name = "libp2p-dns" version = "0.13.0" -source = "git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e#c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e" +source = "git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760#735313ebda6a98604929f6c4606aefac19e00760" dependencies = [ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.13.2 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", + "libp2p-core 0.13.2 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-dns-unofficial 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2020,15 +2030,15 @@ dependencies = [ [[package]] name = "libp2p-floodsub" version = "0.13.1" -source = "git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e#c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e" +source = "git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760#735313ebda6a98604929f6c4606aefac19e00760" dependencies = [ "bs58 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "cuckoofilter 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.13.2 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", - "libp2p-swarm 0.3.0 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", + "libp2p-core 0.13.2 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", + "libp2p-swarm 0.3.0 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", "protobuf 2.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2038,7 +2048,7 @@ dependencies = [ [[package]] name = "libp2p-gossipsub" version = "0.1.0" -source = "git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e#c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e" +source = "git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760#735313ebda6a98604929f6c4606aefac19e00760" dependencies = [ "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "bs58 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2046,13 +2056,13 @@ dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.13.2 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", - "libp2p-swarm 0.3.0 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", + "libp2p-core 0.13.2 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", + "libp2p-swarm 0.3.0 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "lru 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "protobuf 2.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2063,14 +2073,14 @@ dependencies = [ [[package]] name = "libp2p-identify" version = "0.13.2" -source = "git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e#c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e" +source = "git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760#735313ebda6a98604929f6c4606aefac19e00760" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.13.2 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", - "libp2p-swarm 0.3.0 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", + "libp2p-core 0.13.2 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", + "libp2p-swarm 0.3.0 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-multiaddr 0.6.0 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", + "parity-multiaddr 0.6.0 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", "protobuf 2.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2082,21 +2092,21 @@ dependencies = [ [[package]] name = "libp2p-kad" version = "0.13.2" -source = "git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e#c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e" +source = "git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760#735313ebda6a98604929f6c4606aefac19e00760" dependencies = [ "arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.13.2 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", - "libp2p-swarm 0.3.0 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", + "libp2p-core 0.13.2 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", + "libp2p-swarm 0.3.0 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-multiaddr 0.6.0 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", - "parity-multihash 0.2.0 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", + "parity-multiaddr 0.6.0 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", + "parity-multihash 0.2.0 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", "protobuf 2.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2109,16 +2119,16 @@ dependencies = [ [[package]] name = "libp2p-mdns" version = "0.13.1" -source = "git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e#c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e" +source = "git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760#735313ebda6a98604929f6c4606aefac19e00760" dependencies = [ "data-encoding 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "dns-parser 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.13.2 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", - "libp2p-swarm 0.3.0 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", + "libp2p-core 0.13.2 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", + "libp2p-swarm 0.3.0 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-multiaddr 0.6.0 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", + "parity-multiaddr 0.6.0 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2131,12 +2141,12 @@ dependencies = [ [[package]] name = "libp2p-mplex" version = "0.13.0" -source = "git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e#c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e" +source = "git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760#735313ebda6a98604929f6c4606aefac19e00760" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.13.2 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", + "libp2p-core 0.13.2 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2147,13 +2157,13 @@ dependencies = [ [[package]] name = "libp2p-noise" version = "0.11.1" -source = "git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e#c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e" +source = "git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760#735313ebda6a98604929f6c4606aefac19e00760" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "curve25519-dalek 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.13.2 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", + "libp2p-core 0.13.2 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "protobuf 2.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2167,14 +2177,14 @@ dependencies = [ [[package]] name = "libp2p-ping" version = "0.13.1" -source = "git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e#c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e" +source = "git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760#735313ebda6a98604929f6c4606aefac19e00760" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.13.2 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", - "libp2p-swarm 0.3.0 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", + "libp2p-core 0.13.2 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", + "libp2p-swarm 0.3.0 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-multiaddr 0.6.0 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", + "parity-multiaddr 0.6.0 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2184,14 +2194,14 @@ dependencies = [ [[package]] name = "libp2p-plaintext" version = "0.13.1" -source = "git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e#c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e" +source = "git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760#735313ebda6a98604929f6c4606aefac19e00760" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.13.2 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", + "libp2p-core 0.13.2 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "protobuf 2.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rw-stream-sink 0.1.2 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", + "rw-stream-sink 0.1.2 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2199,39 +2209,39 @@ dependencies = [ [[package]] name = "libp2p-secio" version = "0.13.1" -source = "git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e#c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e" +source = "git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760#735313ebda6a98604929f6c4606aefac19e00760" dependencies = [ "aes-ctr 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "ctr 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "js-sys 0.3.33 (registry+https://github.com/rust-lang/crates.io-index)", + "js-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.13.2 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", + "libp2p-core 0.13.2 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-send-wrapper 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "protobuf 2.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "ring 0.16.9 (registry+https://github.com/rust-lang/crates.io-index)", - "rw-stream-sink 0.1.2 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", - "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rw-stream-sink 0.1.2 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", + "sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "twofish 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "untrusted 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen 0.2.56 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen-futures 0.3.27 (registry+https://github.com/rust-lang/crates.io-index)", - "web-sys 0.3.33 (registry+https://github.com/rust-lang/crates.io-index)", + "web-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "libp2p-swarm" version = "0.3.0" -source = "git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e#c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e" +source = "git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760#735313ebda6a98604929f6c4606aefac19e00760" dependencies = [ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.13.2 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", + "libp2p-core 0.13.2 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", "smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2241,13 +2251,13 @@ dependencies = [ [[package]] name = "libp2p-tcp" version = "0.13.0" -source = "git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e#c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e" +source = "git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760#735313ebda6a98604929f6c4606aefac19e00760" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "get_if_addrs 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "ipnet 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.13.2 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", + "libp2p-core 0.13.2 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2257,10 +2267,10 @@ dependencies = [ [[package]] name = "libp2p-uds" version = "0.13.0" -source = "git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e#c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e" +source = "git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760#735313ebda6a98604929f6c4606aefac19e00760" dependencies = [ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.13.2 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", + "libp2p-core 0.13.2 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-uds 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2268,42 +2278,42 @@ dependencies = [ [[package]] name = "libp2p-wasm-ext" version = "0.6.0" -source = "git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e#c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e" +source = "git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760#735313ebda6a98604929f6c4606aefac19e00760" dependencies = [ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "js-sys 0.3.33 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.13.2 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", + "js-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-core 0.13.2 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", "parity-send-wrapper 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen 0.2.56 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen-futures 0.3.27 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "libp2p-websocket" version = "0.13.0" -source = "git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e#c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e" +source = "git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760#735313ebda6a98604929f6c4606aefac19e00760" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.13.2 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", + "libp2p-core 0.13.2 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "rw-stream-sink 0.1.2 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", + "rw-stream-sink 0.1.2 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", "soketto 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-rustls 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", - "url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-rustls 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", + "url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "webpki-roots 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "libp2p-yamux" version = "0.13.0" -source = "git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e#c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e" +source = "git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760#735313ebda6a98604929f6c4606aefac19e00760" dependencies = [ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.13.2 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", + "libp2p-core 0.13.2 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "yamux 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2318,7 +2328,7 @@ dependencies = [ "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "hmac-drbg 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "subtle 2.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2333,7 +2343,7 @@ dependencies = [ "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "hmac-drbg 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "subtle 2.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2343,7 +2353,7 @@ name = "libz-sys" version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)", "vcpkg 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2351,7 +2361,7 @@ dependencies = [ [[package]] name = "lighthouse" -version = "0.1.0" +version = "0.1.1" dependencies = [ "account_manager 0.0.1", "beacon_node 0.1.0", @@ -2414,7 +2424,7 @@ dependencies = [ [[package]] name = "lock_api" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2521,7 +2531,7 @@ dependencies = [ [[package]] name = "mime" -version = "0.3.14" +version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -2529,7 +2539,7 @@ name = "mime_guess" version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "mime 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "mime 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", "unicase 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2594,7 +2604,7 @@ dependencies = [ [[package]] name = "multistream-select" version = "0.6.1" -source = "git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e#c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e" +source = "git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760#735313ebda6a98604929f6c4606aefac19e00760" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2659,7 +2669,7 @@ version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2734,7 +2744,7 @@ name = "num_cpus" version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "hermit-abi 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "hermit-abi 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2767,7 +2777,7 @@ version = "0.9.53" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)", "vcpkg 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2806,37 +2816,37 @@ dependencies = [ [[package]] name = "parity-multiaddr" version = "0.6.0" -source = "git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e#c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e" +source = "git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760#735313ebda6a98604929f6c4606aefac19e00760" dependencies = [ "arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "bs58 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "data-encoding 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-multihash 0.2.0 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)", + "parity-multihash 0.2.0 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)", "percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "unsigned-varint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "parity-multihash" version = "0.2.0" -source = "git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e#c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e" +source = "git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760#735313ebda6a98604929f6c4606aefac19e00760" dependencies = [ "blake2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "sha-1 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sha-1 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", + "sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "sha3 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", "unsigned-varint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "parity-scale-codec" -version = "1.1.0" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2874,7 +2884,7 @@ name = "parking_lot" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lock_api 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lock_api 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot_core 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2954,13 +2964,13 @@ dependencies = [ [[package]] name = "primitive-types" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "fixed-hash 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "impl-codec 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "impl-rlp 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "impl-serde 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "impl-serde 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "uint 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2971,7 +2981,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3028,7 +3038,7 @@ dependencies = [ "idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3129,7 +3139,7 @@ name = "rand" version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", + "getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3172,7 +3182,7 @@ name = "rand_core" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", + "getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3227,7 +3237,7 @@ name = "rand_os" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", + "getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3374,7 +3384,7 @@ dependencies = [ "hyper 0.12.35 (registry+https://github.com/rust-lang/crates.io-index)", "hyper-tls 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "mime 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "mime 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", "mime_guess 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3424,7 +3434,7 @@ dependencies = [ "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", "tree_hash 0.1.1", "types 0.1.0", - "url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "version 0.1.0", ] @@ -3433,12 +3443,12 @@ name = "ring" version = "0.16.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "spin 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "untrusted 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "web-sys 0.3.33 (registry+https://github.com/rust-lang/crates.io-index)", + "web-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3461,7 +3471,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", - "blake2b_simd 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)", + "blake2b_simd 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3498,7 +3508,7 @@ dependencies = [ [[package]] name = "rw-stream-sink" version = "0.1.2" -source = "git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e#c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e" +source = "git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760#735313ebda6a98604929f6c4606aefac19e00760" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3613,7 +3623,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3641,7 +3651,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3668,7 +3678,7 @@ dependencies = [ [[package]] name = "sha-1" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3684,7 +3694,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "sha2" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3710,7 +3720,7 @@ name = "simple_logger" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", + "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", "chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "colored 1.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3799,7 +3809,7 @@ name = "slog-term" version = "2.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", + "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", "chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "term 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3936,6 +3946,7 @@ dependencies = [ "db-key 0.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "eth2_ssz 0.1.2", "eth2_ssz_derive 0.1.0", + "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "leveldb 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)", "lighthouse_metrics 0.1.0", @@ -4006,7 +4017,7 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4032,7 +4043,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4277,7 +4288,7 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.10.2" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4624,7 +4635,7 @@ dependencies = [ [[package]] name = "url" -version = "2.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4732,30 +4743,30 @@ dependencies = [ [[package]] name = "wasi" -version = "0.7.0" +version = "0.9.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "wasm-bindgen" -version = "0.2.56" +version = "0.2.58" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-macro 0.2.56 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-macro 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.56" +version = "0.2.58" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bumpalo 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bumpalo 3.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-shared 0.2.56 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-shared 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4765,64 +4776,64 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "js-sys 0.3.33 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen 0.2.56 (registry+https://github.com/rust-lang/crates.io-index)", - "web-sys 0.3.33 (registry+https://github.com/rust-lang/crates.io-index)", + "js-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "web-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.6" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "js-sys 0.3.33 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen 0.2.56 (registry+https://github.com/rust-lang/crates.io-index)", - "web-sys 0.3.33 (registry+https://github.com/rust-lang/crates.io-index)", + "js-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "web-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.56" +version = "0.2.58" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-macro-support 0.2.56 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-macro-support 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.56" +version = "0.2.58" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-backend 0.2.56 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-shared 0.2.56 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-backend 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-shared 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.56" +version = "0.2.58" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "wasm-bindgen-test" -version = "0.3.6" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "console_error_panic_hook 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "js-sys 0.3.33 (registry+https://github.com/rust-lang/crates.io-index)", + "js-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", "scoped-tls 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen 0.2.56 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-futures 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-test-macro 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-futures 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-test-macro 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "wasm-bindgen-test-macro" -version = "0.3.6" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4831,7 +4842,7 @@ dependencies = [ [[package]] name = "wasm-bindgen-webidl" -version = "0.2.56" +version = "0.2.58" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "anyhow 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4839,8 +4850,8 @@ dependencies = [ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-backend 0.2.56 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-backend 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", "weedle 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4850,23 +4861,23 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "js-sys 0.3.33 (registry+https://github.com/rust-lang/crates.io-index)", + "js-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", "send_wrapper 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-timer 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen 0.2.56 (registry+https://github.com/rust-lang/crates.io-index)", - "web-sys 0.3.33 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "web-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "web-sys" -version = "0.3.33" +version = "0.3.35" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "anyhow 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", - "js-sys 0.3.33 (registry+https://github.com/rust-lang/crates.io-index)", + "js-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", "sourcefile 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen 0.2.56 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-webidl 0.2.56 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-webidl 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5024,9 +5035,9 @@ dependencies = [ "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", "mio-extras 2.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "sha-1 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "sha-1 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5130,7 +5141,7 @@ dependencies = [ "checksum arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" "checksum asn1_der 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6fce6b6a0ffdafebd82c87e79e3f40e8d2c523e5fea5566ff6b90509bf98d638" "checksum asn1_der_derive 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0d0864d84b8e07b145449be9a8537db86bf9de5ce03b913214694643b4743502" -"checksum atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1803c647a3ec87095e7ae7acfca019e98de5ec9a7d01343f611cf3152ed71a90" +"checksum atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" "checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" "checksum backtrace 0.3.40 (registry+https://github.com/rust-lang/crates.io-index)" = "924c76597f0d9ca25d762c25a4d369d51267536465dc5064bdf0eb073ed477ea" "checksum backtrace-sys 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6575f128516de27e3ce99689419835fce9643a9b215a14d2b5b685be018491" @@ -5143,14 +5154,14 @@ dependencies = [ "checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" "checksum bitvec 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a993f74b4c99c1908d156b8d2e0fb6277736b0ecbd833982fd1241d39b2766a6" "checksum blake2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "94cb07b0da6a73955f8fb85d24c466778e70cda767a568229b104f0264089330" -"checksum blake2b_simd 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)" = "b83b7baab1e671718d78204225800d6b170e648188ac7dc992e9d6bddf87d0c0" +"checksum blake2b_simd 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d8fb2d74254a3a0b5cac33ac9f8ed0e44aa50378d9dbb2e5d83bd21ed1dc2c8a" "checksum block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" "checksum block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1c924d49bd09e7c06003acda26cd9742e796e34282ec6c1189404dee0c1f4774" "checksum block-padding 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" "checksum bs58 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "c95ee6bba9d950218b6cc910cf62bc9e0a171d0f4537e3627b0f54d08549b188" "checksum bs58 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b170cd256a3f9fa6b9edae3e44a7dfdfc77e8124dbc3e2612d75f9c3e2396dae" "checksum bstr 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8d6c2c5b58ab920a4f5aeaaca34b4488074e8cc7596af94e6f8c6ff247c60245" -"checksum bumpalo 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ad807f2fc2bf185eeb98ff3a901bd46dc5ad58163d0fa4577ba0d25674d71708" +"checksum bumpalo 3.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5fb8038c1ddc0a5f73787b130f4cc75151e96ed33e417fde765eb5a81e3532f4" "checksum byte-slice-cast 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "b0a5e3906bcbf133e33c1d4d95afc664ad37fbdb9f6568d8043e7ea8c27d93d3" "checksum byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" "checksum byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0fc10e8cc6b2580fda3f36eb6dc5316657f812a3df879a44a66fc9f0fdbc4855" @@ -5159,7 +5170,7 @@ dependencies = [ "checksum c2-chacha 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "214238caa1bf3a496ec3392968969cab8549f96ff30652c9e56885329315f6bb" "checksum c_linked_list 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4964518bd3b4a8190e832886cdc0da9794f12e8e6c1613a9e90ff331c4c8724b" "checksum cast 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4b9434b9a5aa1450faa3f9cb14ea0e8c53bb5d2b3c1bfd1ab4fc03e9f33fbfb0" -"checksum cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)" = "f52a465a666ca3d838ebbf08b241383421412fe7ebb463527bba275526d89f76" +"checksum cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)" = "95e28fa049fda1c330bcf9d723be7663a899c4679724b34c81e9f5a326aab8cd" "checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" "checksum chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "31850b4a4d6bae316f7a09e691c944c28299298837edc0a03f755618c23cbc01" "checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9" @@ -5189,7 +5200,7 @@ dependencies = [ "checksum crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a2f4a431c5c9f662e1200b7c7f02c34e91361150e382089a8f2dec3ba680cbda" "checksum crunchy 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" "checksum crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5" -"checksum csv 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "37519ccdfd73a75821cac9319d4fce15a81b9fcf75f951df5b9988aa3a0af87d" +"checksum csv 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "11f8cbd084b9a431d52dfac0b8428a26b68f1061138a7bea18aa56b9cdf55266" "checksum csv-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9b5cadb6b25c77aeff80ba701712494213f4a8418fcda2ee11b6560c3ad0bf4c" "checksum ctr 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "022cd691704491df67d25d006fe8eca083098253c4d43516c2206479c58c6736" "checksum ctrlc 3.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c7dfd2d8b4c82121dfdff120f818e09fc4380b0b7e17a742081a89b94853e87f" @@ -5208,7 +5219,7 @@ dependencies = [ "checksum ed25519-dalek 1.0.0-pre.3 (registry+https://github.com/rust-lang/crates.io-index)" = "978710b352437433c97b2bff193f2fb1dfd58a093f863dd95e225a19baa599a2" "checksum either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3" "checksum encoding_rs 0.8.22 (registry+https://github.com/rust-lang/crates.io-index)" = "cd8d03faa7fe0c1431609dfad7bbe827af30f82e1e2ae6f7ee4fca6bd764bc28" -"checksum enr 0.1.0 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)" = "" +"checksum enr 0.1.0 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)" = "" "checksum env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "aafcde04e90a5226a6443b7aabdb016ba2f8307c847d524724bd9b346dd1a2d3" "checksum env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36" "checksum error-chain 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3ab49e9dcb602294bc42f9a7dfc9bc6e936fca4418ea300dbfb84fe16de0b7d9" @@ -5237,13 +5248,13 @@ dependencies = [ "checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec" "checksum get_if_addrs 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "abddb55a898d32925f3148bd281174a68eeb68bbfd9a5938a57b18f506ee4ef7" "checksum get_if_addrs-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0d04f9fb746cf36b191c00f3ede8bde9c8e64f9f4b05ae2694a9ccf5e3f5ab48" -"checksum getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "e7db7ca94ed4cd01190ceee0d8a8052f08a247aa1b469a7f68c6a3b71afcf407" +"checksum getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb" "checksum h2 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)" = "a5b34c246847f938a410a03c5458c7fee2274436675e76d8b903c08efc29c462" "checksum hashbrown 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e1de41fb8dba9714efd92241565cdff73f78508c95697dd56787d3cba27e2353" "checksum hashbrown 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8e6073d0ca812575946eb5f35ff68dbe519907b25c42530389ff946dc84c6ead" "checksum heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1679e6ea370dee694f91f1dc469bf94cf8f52051d147aec3e1f9497c6fc22461" "checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" -"checksum hermit-abi 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f629dc602392d3ec14bfc8a09b5e644d7ffd725102b48b81e59f90f2633621d7" +"checksum hermit-abi 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "eff2656d88f158ce120947499e971d743c05dbcbed62e5bd2f38f1698bbc3772" "checksum hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77" "checksum hex 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "023b39be39e3a2da62a94feb433e91e8bcd37676fbc8bea371daf52b7a769a3e" "checksum hkdf 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3fa08a006102488bd9cd5b8013aabe84955cf5ae22e304c2caf655b633aefae3" @@ -5262,13 +5273,14 @@ dependencies = [ "checksum impl-codec 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1be51a921b067b0eaca2fad532d9400041561aa922221cc65f95a85641c6bf53" "checksum impl-rlp 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8f7a72f11830b52333f36e3b09a288333888bf54380fd0ac0790a3c31ab0f3c5" "checksum impl-serde 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "58e3cae7e99c7ff5a995da2cf78dd0a5383740eda71d98cf7b1910c301ac69b8" +"checksum impl-serde 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5bbe9ea9b182f0fb1cabbd61f4ff9b7b7b9197955e95a7e4c27de5055eb29ff8" "checksum indexmap 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712d7b3ea5827fcb9d4fda14bf4da5f136f0db2ae9c8f4bd4e2d1c6fde4e6db2" "checksum integer-sqrt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ea155abb3ba6f382a75f1418988c05fe82959ed9ce727de427f9cfd425b0c903" "checksum iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" "checksum ipnet 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f2f4b06b21db0228860c8dfd17d2106c49c7c6bd07477a4036985347d84def04" "checksum itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f56a2d0bc861f9165be4eb3442afd3c236d8a98afd426f65d92324ae1091a484" "checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f" -"checksum js-sys 0.3.33 (registry+https://github.com/rust-lang/crates.io-index)" = "367647c532db6f1555d7151e619540ec5f713328235b8c062c6b4f63e84adfe3" +"checksum js-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)" = "7889c7c36282151f6bf465be4700359318aef36baa951462382eae49e9577cf9" "checksum jsonrpc-core 11.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97b83fdc5e0218128d0d270f2f2e7a5ea716f3240c8518a58bc89e6716ba8581" "checksum keccak 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" @@ -5279,35 +5291,35 @@ dependencies = [ "checksum leveldb-sys 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "71f46429bb70612c3e939aaeed27ffd31a24a773d21728a1a426e4089d6778d2" "checksum libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)" = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558" "checksum libflate 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)" = "d9135df43b1f5d0e333385cb6e7897ecd1a43d7d11b91ac003f4d2c2d2401fdd" -"checksum libp2p 0.13.2 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)" = "" -"checksum libp2p-core 0.13.2 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)" = "" -"checksum libp2p-core-derive 0.13.0 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)" = "" -"checksum libp2p-deflate 0.5.0 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)" = "" -"checksum libp2p-discv5 0.1.0 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)" = "" -"checksum libp2p-dns 0.13.0 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)" = "" -"checksum libp2p-floodsub 0.13.1 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)" = "" -"checksum libp2p-gossipsub 0.1.0 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)" = "" -"checksum libp2p-identify 0.13.2 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)" = "" -"checksum libp2p-kad 0.13.2 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)" = "" -"checksum libp2p-mdns 0.13.1 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)" = "" -"checksum libp2p-mplex 0.13.0 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)" = "" -"checksum libp2p-noise 0.11.1 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)" = "" -"checksum libp2p-ping 0.13.1 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)" = "" -"checksum libp2p-plaintext 0.13.1 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)" = "" -"checksum libp2p-secio 0.13.1 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)" = "" -"checksum libp2p-swarm 0.3.0 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)" = "" -"checksum libp2p-tcp 0.13.0 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)" = "" -"checksum libp2p-uds 0.13.0 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)" = "" -"checksum libp2p-wasm-ext 0.6.0 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)" = "" -"checksum libp2p-websocket 0.13.0 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)" = "" -"checksum libp2p-yamux 0.13.0 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)" = "" +"checksum libp2p 0.13.2 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)" = "" +"checksum libp2p-core 0.13.2 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)" = "" +"checksum libp2p-core-derive 0.13.0 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)" = "" +"checksum libp2p-deflate 0.5.0 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)" = "" +"checksum libp2p-discv5 0.1.0 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)" = "" +"checksum libp2p-dns 0.13.0 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)" = "" +"checksum libp2p-floodsub 0.13.1 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)" = "" +"checksum libp2p-gossipsub 0.1.0 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)" = "" +"checksum libp2p-identify 0.13.2 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)" = "" +"checksum libp2p-kad 0.13.2 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)" = "" +"checksum libp2p-mdns 0.13.1 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)" = "" +"checksum libp2p-mplex 0.13.0 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)" = "" +"checksum libp2p-noise 0.11.1 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)" = "" +"checksum libp2p-ping 0.13.1 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)" = "" +"checksum libp2p-plaintext 0.13.1 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)" = "" +"checksum libp2p-secio 0.13.1 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)" = "" +"checksum libp2p-swarm 0.3.0 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)" = "" +"checksum libp2p-tcp 0.13.0 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)" = "" +"checksum libp2p-uds 0.13.0 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)" = "" +"checksum libp2p-wasm-ext 0.6.0 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)" = "" +"checksum libp2p-websocket 0.13.0 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)" = "" +"checksum libp2p-yamux 0.13.0 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)" = "" "checksum libsecp256k1 0.3.1 (git+https://github.com/SigP/libsecp256k1?branch=ecdh_generalise)" = "" "checksum libsecp256k1 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "df6edf84fd62aad1c93932b39324eaeda3912c1d26bc18dfaee6293848e49a50" "checksum libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "2eb5e43362e38e2bca2fd5f5134c4d4564a23a5c28e9b95411652021a8675ebe" "checksum linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83" "checksum lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c" "checksum lock_api 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ed946d4529956a20f2d63ebe1b69996d5a2137c91913fe3ebbeff957f5bca7ff" -"checksum lock_api 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e57b3997725d2b60dbec1297f6c2e2957cc383db1cebd6be812163f969c7d586" +"checksum lock_api 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "79b2de95ecb4691949fea4716ca53cdbcfccb2c612e19644a8bad05edcf9f47b" "checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" "checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" "checksum lru 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "5d8f669d42c72d18514dfca8115689c5f6370a17d980cb5bd777a67f404594c8" @@ -5318,14 +5330,14 @@ dependencies = [ "checksum memoffset 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "75189eb85871ea5c2e2c15abbdd541185f63b408415e5051f5cac122d8c774b9" "checksum milagro_bls 0.11.0 (git+https://github.com/sigp/milagro_bls?tag=v0.11.1)" = "" "checksum mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ba626b8a6de5da682e1caa06bdb42a335aee5a84db8e5046a3e8ab17ba0a3ae0" -"checksum mime 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "dd1d63acd1b78403cc0c325605908475dd9b9a3acbf65ed8bcab97e27014afcf" +"checksum mime 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)" = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" "checksum mime_guess 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1a0ed03949aef72dbdf3116a383d7b38b4768e6f960528cd6a6044aa9ed68599" "checksum miniz_oxide 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6f3f74f726ae935c3f514300cc6773a0c9492abc5e972d42ba0c0ebb88757625" "checksum mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)" = "302dec22bcf6bae6dfb69c647187f4b4d0fb6f535521f7bc022430ce8e12008f" "checksum mio-extras 2.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "52403fe290012ce777c4626790c8951324a2b9e3316b3143779c72b029742f19" "checksum mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125" "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" -"checksum multistream-select 0.6.1 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)" = "" +"checksum multistream-select 0.6.1 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)" = "" "checksum native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4b2df1a4c22fd44a62147fd8f13dd0f95c9d8ca7b2610299b2a2f9cf8964274e" "checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" "checksum nix 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6c722bee1037d430d0f8e687bbdbf222f27cc6e4e68d5caf630857bb2b6dbdce" @@ -5342,9 +5354,9 @@ dependencies = [ "checksum openssl-sys 0.9.53 (registry+https://github.com/rust-lang/crates.io-index)" = "465d16ae7fc0e313318f7de5cecf57b2fbe7511fd213978b457e1c96ff46736f" "checksum owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49a4b8ea2179e6a2e27411d3bca09ca6dd630821cf6894c6c7c8467a8ee7ef13" "checksum parity-codec 3.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "2b9df1283109f542d8852cd6b30e9341acc2137481eb6157d2e62af68b0afec9" -"checksum parity-multiaddr 0.6.0 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)" = "" -"checksum parity-multihash 0.2.0 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)" = "" -"checksum parity-scale-codec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f9f9d99dae413590a5f37e43cd99b94d4e62a244160562899126913ea7108673" +"checksum parity-multiaddr 0.6.0 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)" = "" +"checksum parity-multihash 0.2.0 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)" = "" +"checksum parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f747c06d9f3b2ad387ac881b9667298c81b1243aa9833f086e05996937c35507" "checksum parity-send-wrapper 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aa9777aa91b8ad9dd5aaa04a9b6bcb02c7f1deb952fca5a66034d5e63afc5c6f" "checksum parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ab41b4aed082705d1056416ae4468b6ea99d52599ecf3169b00088d43113e337" "checksum parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fa7767817701cce701d5585b9c4db3cdd02086398322c1d7e8bf5094a96a2ce7" @@ -5357,7 +5369,7 @@ dependencies = [ "checksum pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)" = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677" "checksum ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b" "checksum primitive-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2288eb2a39386c4bc817974cc413afe173010dc80e470fcb1e9a35580869f024" -"checksum primitive-types 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a0253db64c26d8b4e7896dd2063b516d2a1b9e0a5da26b5b78335f236d1e9522" +"checksum primitive-types 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e4336f4f5d5524fa60bcbd6fe626f9223d8142a50e7053e979acdf0da41ab975" "checksum proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)" = "ecd45702f76d6d3c75a80564378ae228a85f0b59d2f3ed43c91b4a69eb2ebfc5" "checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" "checksum proc-macro2 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "0319972dcae462681daf4da1adeeaa066e3ebd29c69be96c6abb1259d2ee2bcc" @@ -5407,7 +5419,7 @@ dependencies = [ "checksum rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "403bb3a286107a04825a5f82e1270acc1e14028d3d554d7a1e08914549575ab8" "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" "checksum rustls 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b25a18b1bf7387f0145e7f8324e700805aade3842dd3db2e74e4cdeb4677c09e" -"checksum rw-stream-sink 0.1.2 (git+https://github.com/SigP/rust-libp2p/?rev=c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e)" = "" +"checksum rw-stream-sink 0.1.2 (git+https://github.com/SigP/rust-libp2p/?rev=735313ebda6a98604929f6c4606aefac19e00760)" = "" "checksum ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8" "checksum safemem 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072" "checksum same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "585e8ddcedc187886a30fa705c47985c3fa88d06624095856b36ca0b82ff4421" @@ -5428,9 +5440,9 @@ dependencies = [ "checksum serde_repr 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "cd02c7587ec314570041b2754829f84d873ced14a96d1fd1823531e11db40573" "checksum serde_urlencoded 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "642dd69105886af2efd227f75a520ec9b44a820d65bc133a9131f7d229fd165a" "checksum serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)" = "691b17f19fc1ec9d94ec0b5864859290dff279dbd7b03f017afda54eb36c3c35" -"checksum sha-1 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "23962131a91661d643c98940b20fcaffe62d776a823247be80a48fcb8b6fce68" +"checksum sha-1 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df" "checksum sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" -"checksum sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b4d8bfd0e469f417657573d8451fb33d16cfe0989359b93baf3a1ffc639543d" +"checksum sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "27044adfd2e1f077f649f59deb9490d3941d674002f7d062870a60ebe9bd47a0" "checksum sha3 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd26bc0e7a2e3a7c959bc494caf58b72ee0c71d67704e9520f736ca7e4853ecf" "checksum simple_logger 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "109facdf91db4b79de557313b5e031f0f8a86373e316bf01158190aa68bcc74e" "checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23" @@ -5459,7 +5471,7 @@ dependencies = [ "checksum subtle 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" "checksum subtle 2.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c65d530b10ccaeac294f349038a597e435b18fb456aadd0840a623f83b9e941" "checksum syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)" = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" -"checksum syn 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)" = "ddc157159e2a7df58cd67b1cace10b8ed256a404fb0070593f137d8ba6bef4de" +"checksum syn 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1e4ff033220a41d1a57d8125eab57bf5263783dfdcc18688b1dacc6ce9651ef8" "checksum synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "02353edf96d6e4dc81aea2d8490a7e9db177bf8acb0e951c24940bf866cb313f" "checksum synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545" "checksum take_mut 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f764005d11ee5f36500a149ace24e00e3da98b0158b3e2d53a7495660d3f4d60" @@ -5484,7 +5496,7 @@ dependencies = [ "checksum tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "5090db468dad16e1a7a54c8c67280c5e4b544f3d3e018f0b913b400261f85926" "checksum tokio-io-timeout 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "135ce81f15cfd7982fac684f9057a1299eebeb79e98a8a709969b9aa51123129" "checksum tokio-reactor 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "6732fe6b53c8d11178dcb77ac6d9682af27fc6d4cb87789449152e5377377146" -"checksum tokio-rustls 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1df2fa53ac211c136832f530ccb081af9af891af22d685a9493e232c7a359bc2" +"checksum tokio-rustls 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2d7cf08f990090abd6c6a73cab46fed62f85e8aef8b99e4b918a9f4a637f0676" "checksum tokio-sync 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "d06554cce1ae4a50f42fba8023918afa931413aded705b560e29600ccf7c6d76" "checksum tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1d14b10654be682ac43efee27401d792507e30fd8d26389e1da3b185de2e4119" "checksum tokio-threadpool 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "f0c32ffea4827978e9aa392d2f743d973c1dfa3730a2ed3f22ce1e6984da848c" @@ -5516,7 +5528,7 @@ dependencies = [ "checksum unsigned-varint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a7f0023a96687fe169081e8adce3f65e3874426b7886e9234d490af2dc077959" "checksum untrusted 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "60369ef7a31de49bcb3f6ca728d4ba7300d9a1658f94c727d4cab8c8d9f4aece" "checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" -"checksum url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "75b414f6c464c879d7f9babf951f23bc3743fb7313c081b2e6ca719067ea9d61" +"checksum url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "829d4a8476c35c9bf0bbce5a3b23f4106f79728039b726d292bb93bc106787cb" "checksum uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "90dbc611eb48397705a6b0f6e917da23ae517e4d127123d2cf7674206627d32a" "checksum vcpkg 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3fc439f2794e98976c88a2a2dafce96b930fe8010b0a256b3c2199a773933168" "checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" @@ -5525,19 +5537,19 @@ dependencies = [ "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" "checksum walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9658c94fa8b940eab2250bd5a457f9c48b748420d71293b165c8cdbe2f55f71e" "checksum want 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b6395efa4784b027708f7451087e647ec73cc74f5d9bc2e418404248d679a230" -"checksum wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b89c3ce4ce14bdc6fb6beaf9ec7928ca331de5df7e5ea278375642a2f478570d" -"checksum wasm-bindgen 0.2.56 (registry+https://github.com/rust-lang/crates.io-index)" = "99de4b68939a880d530aed51289a7c7baee154e3ea8ac234b542c49da7134aaf" -"checksum wasm-bindgen-backend 0.2.56 (registry+https://github.com/rust-lang/crates.io-index)" = "b58e66a093a7b7571cb76409763c495b8741ac4319ac20acc2b798f6766d92ee" +"checksum wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)" = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" +"checksum wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "5205e9afdf42282b192e2310a5b463a6d1c1d774e30dc3c791ac37ab42d2616c" +"checksum wasm-bindgen-backend 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "11cdb95816290b525b32587d76419facd99662a07e59d3cdb560488a819d9a45" "checksum wasm-bindgen-futures 0.3.27 (registry+https://github.com/rust-lang/crates.io-index)" = "83420b37346c311b9ed822af41ec2e82839bfe99867ec6c54e2da43b7538771c" -"checksum wasm-bindgen-futures 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "3bf1b55e0dc85085cfab2c0c520b977afcf16ac5801ee0de8dde42a4f5649b2a" -"checksum wasm-bindgen-macro 0.2.56 (registry+https://github.com/rust-lang/crates.io-index)" = "a80f89daea7b0a67b11f6e9f911422ed039de9963dce00048a653b63d51194bf" -"checksum wasm-bindgen-macro-support 0.2.56 (registry+https://github.com/rust-lang/crates.io-index)" = "4f9dbc3734ad6cff6b76b75b7df98c06982becd0055f651465a08f769bca5c61" -"checksum wasm-bindgen-shared 0.2.56 (registry+https://github.com/rust-lang/crates.io-index)" = "d907984f8506b3554eab48b8efff723e764ddbf76d4cd4a3fe4196bc00c49a70" -"checksum wasm-bindgen-test 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "87d10750e72390ddfaad9420525f4e3ed565408586c859aa2bf91f8ebad65774" -"checksum wasm-bindgen-test-macro 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "5b84bb462de0772abdec0394671153f280483828f883cbaa12d71f6142196a01" -"checksum wasm-bindgen-webidl 0.2.56 (registry+https://github.com/rust-lang/crates.io-index)" = "f85a3825a459cf6a929d03bacb54dca37a614d43032ad1343ef2d4822972947d" +"checksum wasm-bindgen-futures 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8bbdd49e3e28b40dec6a9ba8d17798245ce32b019513a845369c641b275135d9" +"checksum wasm-bindgen-macro 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "574094772ce6921576fb6f2e3f7497b8a76273b6db092be18fc48a082de09dc3" +"checksum wasm-bindgen-macro-support 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "e85031354f25eaebe78bb7db1c3d86140312a911a106b2e29f9cc440ce3e7668" +"checksum wasm-bindgen-shared 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "f5e7e61fc929f4c0dddb748b102ebf9f632e2b8d739f2016542b4de2965a9601" +"checksum wasm-bindgen-test 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "98fd0ec352c44d1726b6c2bec524612b1c81e34a7d858f597a6c71f8e018c82e" +"checksum wasm-bindgen-test-macro 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "97837a6e83ab24a4b3a38d44a257e13335b54f4b4548b2c9d71edd0bf570cb4f" +"checksum wasm-bindgen-webidl 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "ef012a0d93fc0432df126a8eaf547b2dce25a8ce9212e1d3cbeef5c11157975d" "checksum wasm-timer 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "aa3e01d234bb71760e685cfafa5e2c96f8ad877c161a721646356651069e26ac" -"checksum web-sys 0.3.33 (registry+https://github.com/rust-lang/crates.io-index)" = "2fb60433d0dc12c803b9b017b3902d80c9451bab78d27bc3210bf2a7b96593f1" +"checksum web-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)" = "aaf97caf6aa8c2b1dac90faf0db529d9d63c93846cca4911856f78a83cebf53b" "checksum web3 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "076f34ed252d74a8521e3b013254b1a39f94a98f23aae7cfc85cda6e7b395664" "checksum webpki 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d7e664e770ac0110e2384769bcc59ed19e329d81f555916a6e072714957b81b4" "checksum webpki-roots 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)" = "91cd5736df7f12a964a5067a12c62fa38e1bd8080aff1f80bc29be7c80d19ab4" diff --git a/Dockerfile b/Dockerfile index 5fab5a6a73..1a19ddee3f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM rust:1.39.0 AS builder +FROM rust:1.40.0 AS builder COPY . lighthouse RUN cd lighthouse && make && cargo clean diff --git a/README.md b/README.md index 20f427f4f8..21e716db32 100644 --- a/README.md +++ b/README.md @@ -12,8 +12,8 @@ An open-source Ethereum 2.0 client, written in Rust and maintained by Sigma Prim [Book Link]: http://lighthouse-book.sigmaprime.io/ [RustDoc Status]:https://img.shields.io/badge/code--docs-master-orange [RustDoc Link]: http://lighthouse-docs.sigmaprime.io/ -[Swagger Badge]: https://img.shields.io/badge/Open%20API-0.2.0-success -[Swagger Link]: https://app.swaggerhub.com/apis-docs/spble/lighthouse_rest_api/0.2.0 +[Swagger Badge]: https://img.shields.io/badge/testnet--explorer-beaconcha.in-informational +[Swagger Link]: https://lighthouse-testnet3.beaconcha.in/ [Documentation](http://lighthouse-book.sigmaprime.io/) diff --git a/account_manager/src/lib.rs b/account_manager/src/lib.rs index e6d02d614c..b0f3525b17 100644 --- a/account_manager/src/lib.rs +++ b/account_manager/src/lib.rs @@ -130,6 +130,7 @@ fn run_new_validator_subcommand( &methods, deposit_value, &context.eth2_config.spec, + &env.core_context().log, )?; if matches.is_present("send-deposits") { @@ -249,6 +250,7 @@ fn make_validators( methods: &[KeygenMethod], deposit_value: u64, spec: &ChainSpec, + log: &Logger, ) -> Result, String> { methods .par_iter() @@ -262,11 +264,25 @@ fn make_validators( KeygenMethod::ThreadRandom => builder.thread_random_keypairs(), }; - builder + let validator = builder .create_directory(datadir.clone())? .write_keypair_files()? .write_eth1_data_file()? - .build() + .build()?; + + let pubkey = &validator + .voting_keypair + .as_ref() + .ok_or_else(|| "Generated validator must have voting keypair".to_string())? + .pk; + + info!( + log, + "Saved new validator to disk"; + "voting_pubkey" => format!("{:?}", pubkey) + ); + + Ok(validator) }) .collect() } diff --git a/beacon_node/beacon_chain/src/beacon_chain.rs b/beacon_node/beacon_chain/src/beacon_chain.rs index dda557b4d7..b00f39c6c2 100644 --- a/beacon_node/beacon_chain/src/beacon_chain.rs +++ b/beacon_node/beacon_chain/src/beacon_chain.rs @@ -7,8 +7,8 @@ use crate::fork_choice::{Error as ForkChoiceError, ForkChoice}; use crate::head_tracker::HeadTracker; use crate::metrics; use crate::persisted_beacon_chain::{PersistedBeaconChain, BEACON_CHAIN_DB_KEY}; +use crate::timeout_rw_lock::TimeoutRwLock; use operation_pool::{OperationPool, PersistedOperationPool}; -use parking_lot::RwLock; use slog::{debug, error, info, trace, warn, Logger}; use slot_clock::SlotClock; use ssz::Encode; @@ -22,6 +22,7 @@ use state_processing::per_block_processing::{ use state_processing::{ per_block_processing, per_slot_processing, BlockProcessingError, BlockSignatureStrategy, }; +use std::borrow::Cow; use std::fs; use std::io::prelude::*; use std::sync::Arc; @@ -29,7 +30,7 @@ use std::time::{Duration, Instant}; use store::iter::{ BlockRootsIterator, ReverseBlockRootIterator, ReverseStateRootIterator, StateRootsIterator, }; -use store::{Error as DBError, Migrate, Store}; +use store::{BlockRootTree, Error as DBError, Migrate, Store}; use tree_hash::TreeHash; use types::*; @@ -37,7 +38,7 @@ use types::*; // Must be 32-bytes or panic. // // |-------must be this long------| -pub const GRAFFITI: &str = "sigp/lighthouse-0.1.0-prerelease"; +pub const GRAFFITI: &str = "sigp/lighthouse-0.1.1-prerelease"; /// If true, everytime a block is processed the pre-state, post-state and block are written to SSZ /// files in the temp directory. @@ -48,6 +49,10 @@ const WRITE_BLOCK_PROCESSING_SSZ: bool = cfg!(feature = "write_ssz_files"); /// Maximum block slot number. Block with slots bigger than this constant will NOT be processed. const MAXIMUM_BLOCK_SLOT_NUMBER: u64 = 4_294_967_296; // 2^32 +/// The time-out before failure during an operation to take a read/write RwLock on the canonical +/// head. +const HEAD_LOCK_TIMEOUT: Duration = Duration::from_secs(1); + #[derive(Debug, PartialEq)] pub enum BlockProcessingOutcome { /// Block was valid and imported into the block graph. @@ -102,6 +107,7 @@ pub struct HeadInfo { pub block_root: Hash256, pub state_root: Hash256, pub finalized_checkpoint: types::Checkpoint, + pub fork: Fork, } pub trait BeaconChainTypes: Send + Sync + 'static { @@ -129,7 +135,7 @@ pub struct BeaconChain { /// Provides information from the Ethereum 1 (PoW) chain. pub eth1_chain: Option>, /// Stores a "snapshot" of the chain at the time the head-of-the-chain block was received. - pub(crate) canonical_head: RwLock>, + pub(crate) canonical_head: TimeoutRwLock>, /// The root of the genesis block. pub genesis_block_root: Hash256, /// A state-machine that is updated with information from the network and chooses a canonical @@ -141,6 +147,8 @@ pub struct BeaconChain { pub(crate) head_tracker: HeadTracker, /// Provides a small cache of `BeaconState` and `BeaconBlock`. pub(crate) checkpoint_cache: CheckPointCache, + /// Cache of block roots for all known forks post-finalization. + pub block_root_tree: Arc, /// Logging to CLI, etc. pub(crate) log: Logger, } @@ -152,7 +160,7 @@ impl BeaconChain { pub fn persist(&self) -> Result<(), Error> { let timer = metrics::start_timer(&metrics::PERSIST_CHAIN); - let canonical_head = self.head(); + let canonical_head = self.head()?; let finalized_checkpoint = { let beacon_block_root = canonical_head.beacon_state.finalized_checkpoint.root; @@ -162,8 +170,7 @@ impl BeaconChain { .ok_or_else(|| Error::MissingBeaconBlock(beacon_block_root))?; let beacon_state_root = beacon_block.state_root; let beacon_state = self - .store - .get_state(&beacon_state_root, Some(beacon_block.slot))? + .get_state_caching(&beacon_state_root, Some(beacon_block.slot))? .ok_or_else(|| Error::MissingBeaconState(beacon_state_root))?; CheckPoint { @@ -181,6 +188,7 @@ impl BeaconChain { genesis_block_root: self.genesis_block_root, ssz_head_tracker: self.head_tracker.to_ssz_container(), fork_choice: self.fork_choice.as_ssz_container(), + block_root_tree: self.block_root_tree.as_ssz_container(), }; let key = Hash256::from_slice(&BEACON_CHAIN_DB_KEY.as_bytes()); @@ -254,26 +262,32 @@ impl BeaconChain { /// - Iterator returns `(Hash256, Slot)`. /// - As this iterator starts at the `head` of the chain (viz., the best block), the first slot /// returned may be earlier than the wall-clock slot. - pub fn rev_iter_block_roots(&self) -> ReverseBlockRootIterator { - let head = self.head(); + pub fn rev_iter_block_roots( + &self, + ) -> Result, Error> { + let head = self.head()?; let iter = BlockRootsIterator::owned(self.store.clone(), head.beacon_state); - ReverseBlockRootIterator::new((head.beacon_block_root, head.beacon_block.slot), iter) + Ok(ReverseBlockRootIterator::new( + (head.beacon_block_root, head.beacon_block.slot), + iter, + )) } pub fn forwards_iter_block_roots( &self, start_slot: Slot, - ) -> >::ForwardsBlockRootsIterator { - let local_head = self.head(); - T::Store::forwards_block_roots_iterator( + ) -> Result<>::ForwardsBlockRootsIterator, Error> { + let local_head = self.head()?; + + Ok(T::Store::forwards_block_roots_iterator( self.store.clone(), start_slot, local_head.beacon_state, local_head.beacon_block_root, &self.spec, - ) + )) } /// Traverse backwards from `block_root` to find the block roots of its ancestors. @@ -323,13 +337,18 @@ impl BeaconChain { /// - Iterator returns `(Hash256, Slot)`. /// - As this iterator starts at the `head` of the chain (viz., the best block), the first slot /// returned may be earlier than the wall-clock slot. - pub fn rev_iter_state_roots(&self) -> ReverseStateRootIterator { - let head = self.head(); + pub fn rev_iter_state_roots( + &self, + ) -> Result, Error> { + let head = self.head()?; let slot = head.beacon_state.slot; let iter = StateRootsIterator::owned(self.store.clone(), head.beacon_state); - ReverseStateRootIterator::new((head.beacon_state_root, slot), iter) + Ok(ReverseStateRootIterator::new( + (head.beacon_state_root, slot), + iter, + )) } /// Returns the block at the given root, if any. @@ -351,7 +370,7 @@ impl BeaconChain { /// May return a database error. pub fn block_at_slot(&self, slot: Slot) -> Result>, Error> { let root = self - .rev_iter_block_roots() + .rev_iter_block_roots()? .find(|(_, this_slot)| *this_slot == slot) .map(|(root, _)| root); @@ -392,7 +411,7 @@ impl BeaconChain { /// ## Errors /// /// May return a database error. - fn get_block_caching( + pub fn get_block_caching( &self, block_root: &Hash256, ) -> Result>, Error> { @@ -408,7 +427,7 @@ impl BeaconChain { /// ## Errors /// /// May return a database error. - fn get_state_caching( + pub fn get_state_caching( &self, state_root: &Hash256, slot: Option, @@ -429,7 +448,7 @@ impl BeaconChain { /// ## Errors /// /// May return a database error. - fn get_state_caching_only_with_committee_caches( + pub fn get_state_caching_only_with_committee_caches( &self, state_root: &Hash256, slot: Option, @@ -450,22 +469,29 @@ impl BeaconChain { /// It is important to note that the `beacon_state` returned may not match the present slot. It /// is the state as it was when the head block was received, which could be some slots prior to /// now. - pub fn head(&self) -> CheckPoint { - self.canonical_head.read().clone() + pub fn head(&self) -> Result, Error> { + self.canonical_head + .try_read_for(HEAD_LOCK_TIMEOUT) + .ok_or_else(|| Error::CanonicalHeadLockTimeout) + .map(|v| v.clone()) } /// Returns info representing the head block and state. /// /// A summarized version of `Self::head` that involves less cloning. - pub fn head_info(&self) -> HeadInfo { - let head = self.canonical_head.read(); + pub fn head_info(&self) -> Result { + let head = self + .canonical_head + .try_read_for(HEAD_LOCK_TIMEOUT) + .ok_or_else(|| Error::CanonicalHeadLockTimeout)?; - HeadInfo { + Ok(HeadInfo { slot: head.beacon_block.slot, block_root: head.beacon_block_root, state_root: head.beacon_state_root, finalized_checkpoint: head.beacon_state.finalized_checkpoint.clone(), - } + fork: head.beacon_state.fork.clone(), + }) } /// Returns the current heads of the `BeaconChain`. For the canonical head, see `Self::head`. @@ -480,7 +506,7 @@ impl BeaconChain { /// Returns `None` when the state is not found in the database or there is an error skipping /// to a future state. pub fn state_at_slot(&self, slot: Slot) -> Result, Error> { - let head_state = self.head().beacon_state; + let head_state = self.head()?.beacon_state; if slot == head_state.slot { Ok(head_state) @@ -532,7 +558,7 @@ impl BeaconChain { Ok(state) } else { let state_root = self - .rev_iter_state_roots() + .rev_iter_state_roots()? .take_while(|(_root, current_slot)| *current_slot >= slot) .find(|(_root, current_slot)| *current_slot == slot) .map(|(root, _slot)| root) @@ -557,29 +583,33 @@ impl BeaconChain { } /// Returns the slot of the highest block in the canonical chain. - pub fn best_slot(&self) -> Slot { - self.canonical_head.read().beacon_block.slot + pub fn best_slot(&self) -> Result { + self.canonical_head + .try_read_for(HEAD_LOCK_TIMEOUT) + .map(|head| head.beacon_block.slot) + .ok_or_else(|| Error::CanonicalHeadLockTimeout) } /// Returns the validator index (if any) for the given public key. /// /// Information is retrieved from the present `beacon_state.validators`. - pub fn validator_index(&self, pubkey: &PublicKeyBytes) -> Option { - for (i, validator) in self.head().beacon_state.validators.iter().enumerate() { + pub fn validator_index(&self, pubkey: &PublicKeyBytes) -> Result, Error> { + for (i, validator) in self.head()?.beacon_state.validators.iter().enumerate() { if validator.pubkey == *pubkey { - return Some(i); + return Ok(Some(i)); } } - None + Ok(None) } /// Returns the block canonical root of the current canonical chain at a given slot. /// /// Returns None if a block doesn't exist at the slot. - pub fn root_at_slot(&self, target_slot: Slot) -> Option { - self.rev_iter_block_roots() + pub fn root_at_slot(&self, target_slot: Slot) -> Result, Error> { + Ok(self + .rev_iter_block_roots()? .find(|(_root, slot)| *slot == target_slot) - .map(|(root, _slot)| root) + .map(|(root, _slot)| root)) } /// Reads the slot clock (see `self.read_slot_clock()` and returns the number of slots since @@ -601,10 +631,10 @@ impl BeaconChain { /// present epoch is available. pub fn block_proposer(&self, slot: Slot) -> Result { let epoch = |slot: Slot| slot.epoch(T::EthSpec::slots_per_epoch()); - let head_state = &self.head().beacon_state; + let head_state = &self.head()?.beacon_state; let mut state = if epoch(slot) == epoch(head_state.slot) { - self.head().beacon_state.clone() + self.head()?.beacon_state.clone() } else { self.state_at_slot(slot)? }; @@ -634,10 +664,10 @@ impl BeaconChain { epoch: Epoch, ) -> Result, Error> { let as_epoch = |slot: Slot| slot.epoch(T::EthSpec::slots_per_epoch()); - let head_state = &self.head().beacon_state; + let head_state = &self.head()?.beacon_state; let mut state = if epoch == as_epoch(head_state.slot) { - self.head().beacon_state.clone() + self.head()?.beacon_state.clone() } else { self.state_at_slot(epoch.start_slot(T::EthSpec::slots_per_epoch()))? }; @@ -670,7 +700,7 @@ impl BeaconChain { index: CommitteeIndex, ) -> Result, Error> { let state = self.state_at_slot(slot)?; - let head = self.head(); + let head = self.head()?; let data = self.produce_attestation_data_for_block( index, @@ -697,7 +727,7 @@ impl BeaconChain { index: CommitteeIndex, ) -> Result { let state = self.state_at_slot(slot)?; - let head = self.head(); + let head = self.head()?; self.produce_attestation_data_for_block( index, @@ -858,37 +888,40 @@ impl BeaconChain { let result = if let Some(attestation_head_block) = self.get_block_caching(&attestation.data.beacon_block_root)? { - // Use the `data.beacon_block_root` to load the state from the latest non-skipped - // slot preceding the attestation's creation. - // - // This state is guaranteed to be in the same chain as the attestation, but it's - // not guaranteed to be from the same slot or epoch as the attestation. - let mut state: BeaconState = self - .get_state_caching_only_with_committee_caches( - &attestation_head_block.state_root, - Some(attestation_head_block.slot), - )? - .ok_or_else(|| Error::MissingBeaconState(attestation_head_block.state_root))?; - - // Ensure the state loaded from the database matches the state of the attestation - // head block. - // - // The state needs to be advanced from the current slot through to the epoch in - // which the attestation was created in. It would be an error to try and use - // `state.get_attestation_data_slot(..)` because the state matching the - // `data.beacon_block_root` isn't necessarily in a nearby epoch to the attestation - // (e.g., if there were lots of skip slots since the head of the chain and the - // epoch creation epoch). - for _ in state.slot.as_u64() - ..attestation - .data - .target - .epoch - .start_slot(T::EthSpec::slots_per_epoch()) - .as_u64() + // If the attestation points to a block in the same epoch in which it was made, + // then it is sufficient to load the state from that epoch's boundary, because + // the epoch-variable fields like the justified checkpoints cannot have changed + // between the epoch boundary and when the attestation was made. If conversely, + // the attestation points to a block in a prior epoch, then it is necessary to + // load the full state corresponding to its block, and transition it to the + // attestation's epoch. + let attestation_epoch = attestation.data.target.epoch; + let slots_per_epoch = T::EthSpec::slots_per_epoch(); + let mut state = if attestation_epoch + == attestation_head_block.slot.epoch(slots_per_epoch) { - per_slot_processing(&mut state, None, &self.spec)?; - } + self.store + .load_epoch_boundary_state(&attestation_head_block.state_root)? + .ok_or_else(|| Error::MissingBeaconState(attestation_head_block.state_root))? + } else { + let mut state = self + .store + .get_state( + &attestation_head_block.state_root, + Some(attestation_head_block.slot), + )? + .ok_or_else(|| Error::MissingBeaconState(attestation_head_block.state_root))?; + + // Fastforward the state to the epoch in which the attestation was made. + // NOTE: this looks like a potential DoS vector, we should probably limit + // the amount we're willing to fastforward without a valid signature. + for _ in state.slot.as_u64()..attestation_epoch.start_slot(slots_per_epoch).as_u64() + { + per_slot_processing(&mut state, None, &self.spec)?; + } + + state + }; state.build_committee_cache(RelativeEpoch::Current, &self.spec)?; @@ -913,7 +946,7 @@ impl BeaconChain { // // This is likely overly restrictive, we could store the attestation for later // processing. - let head_epoch = self.head_info().slot.epoch(T::EthSpec::slots_per_epoch()); + let head_epoch = self.head_info()?.slot.epoch(T::EthSpec::slots_per_epoch()); let attestation_epoch = attestation.data.slot.epoch(T::EthSpec::slots_per_epoch()); // Only log a warning if our head is in a reasonable place to verify this attestation. @@ -975,7 +1008,7 @@ impl BeaconChain { // - The highest valid finalized epoch we've ever seen (i.e., the head). // - The finalized epoch that this attestation was created against. let finalized_epoch = std::cmp::max( - self.head_info().finalized_checkpoint.epoch, + self.head_info()?.finalized_checkpoint.epoch, state.finalized_checkpoint.epoch, ); @@ -1172,7 +1205,7 @@ impl BeaconChain { let full_timer = metrics::start_timer(&metrics::BLOCK_PROCESSING_TIMES); let finalized_slot = self - .head_info() + .head_info()? .finalized_checkpoint .epoch .start_slot(T::EthSpec::slots_per_epoch()); @@ -1211,14 +1244,16 @@ impl BeaconChain { }); } + // Check if the block is already known. We know it is post-finalization, so it is + // sufficient to check the block root tree. + if self.block_root_tree.is_known_block_root(&block_root) { + return Ok(BlockProcessingOutcome::BlockIsAlreadyKnown); + } + // Records the time taken to load the block and state from the database during block // processing. let db_read_timer = metrics::start_timer(&metrics::BLOCK_PROCESSING_DB_READ); - if self.store.exists::>(&block_root)? { - return Ok(BlockProcessingOutcome::BlockIsAlreadyKnown); - } - // Load the blocks parent block from the database, returning invalid if that block is not // found. let parent_block: BeaconBlock = @@ -1350,6 +1385,9 @@ impl BeaconChain { metrics::stop_timer(db_write_timer); + self.block_root_tree + .add_block_root(block_root, block.parent_root, block.slot)?; + self.head_tracker.register_block(block_root, &block); let fork_choice_register_timer = @@ -1380,12 +1418,12 @@ impl BeaconChain { // // A block that was just imported is likely to be referenced by the next block that we // import. - self.checkpoint_cache.insert(&CheckPoint { + self.checkpoint_cache.insert(Cow::Owned(CheckPoint { beacon_block_root: block_root, beacon_block: block, beacon_state_root: state_root, beacon_state: state, - }); + })); metrics::stop_timer(full_timer); @@ -1514,7 +1552,7 @@ impl BeaconChain { let beacon_block_root = self.fork_choice.find_head(&self)?; // If a new head was chosen. - let result = if beacon_block_root != self.head_info().block_root { + let result = if beacon_block_root != self.head_info()?.block_root { metrics::inc_counter(&metrics::FORK_CHOICE_CHANGED_HEAD); let beacon_block: BeaconBlock = self @@ -1526,15 +1564,15 @@ impl BeaconChain { .get_state_caching(&beacon_state_root, Some(beacon_block.slot))? .ok_or_else(|| Error::MissingBeaconState(beacon_state_root))?; - let previous_slot = self.head_info().slot; + let previous_slot = self.head_info()?.slot; let new_slot = beacon_block.slot; // Note: this will declare a re-org if we skip `SLOTS_PER_HISTORICAL_ROOT` blocks // between calls to fork choice without swapping between chains. This seems like an // extreme-enough scenario that a warning is fine. - let is_reorg = self.head_info().block_root + let is_reorg = self.head_info()?.block_root != beacon_state - .get_block_root(self.head_info().slot) + .get_block_root(self.head_info()?.slot) .map(|root| *root) .unwrap_or_else(|_| Hash256::random()); @@ -1544,7 +1582,7 @@ impl BeaconChain { warn!( self.log, "Beacon chain re-org"; - "previous_head" => format!("{}", self.head_info().block_root), + "previous_head" => format!("{}", self.head_info()?.block_root), "previous_slot" => previous_slot, "new_head_parent" => format!("{}", beacon_block.parent_root), "new_head" => format!("{}", beacon_block_root), @@ -1563,7 +1601,7 @@ impl BeaconChain { ); }; - let old_finalized_epoch = self.head_info().finalized_checkpoint.epoch; + let old_finalized_epoch = self.head_info()?.finalized_checkpoint.epoch; let new_finalized_epoch = beacon_state.finalized_checkpoint.epoch; let finalized_root = beacon_state.finalized_checkpoint.root; @@ -1574,7 +1612,11 @@ impl BeaconChain { new_epoch: new_finalized_epoch, }) } else { - let previous_head_beacon_block_root = self.canonical_head.read().beacon_block_root; + let previous_head_beacon_block_root = self + .canonical_head + .try_read_for(HEAD_LOCK_TIMEOUT) + .ok_or_else(|| Error::CanonicalHeadLockTimeout)? + .beacon_block_root; let current_head_beacon_block_root = beacon_block_root; let mut new_head = CheckPoint { @@ -1591,11 +1633,14 @@ impl BeaconChain { // Store the head in the checkpoint cache. // // The head block is likely to be referenced by the next imported block. - self.checkpoint_cache.insert(&new_head); + self.checkpoint_cache.insert(Cow::Borrowed(&new_head)); // Update the checkpoint that stores the head of the chain at the time it received the // block. - *self.canonical_head.write() = new_head; + *self + .canonical_head + .try_write_for(HEAD_LOCK_TIMEOUT) + .ok_or_else(|| Error::CanonicalHeadLockTimeout)? = new_head; metrics::stop_timer(timer); @@ -1653,8 +1698,10 @@ impl BeaconChain { .process_finalization(&finalized_block, finalized_block_root)?; let finalized_state = self - .store - .get_state(&finalized_block.state_root, Some(finalized_block.slot))? + .get_state_caching_only_with_committee_caches( + &finalized_block.state_root, + Some(finalized_block.slot), + )? .ok_or_else(|| Error::MissingBeaconState(finalized_block.state_root))?; self.op_pool.prune_all(&finalized_state, &self.spec); @@ -1667,6 +1714,12 @@ impl BeaconChain { max_finality_distance, ); + // Prune in-memory block root tree. + self.block_root_tree.prune_to( + finalized_block_root, + self.heads().into_iter().map(|(block_root, _)| block_root), + ); + let _ = self.event_handler.register(EventKind::BeaconFinalization { epoch: new_finalized_epoch, root: finalized_block_root, @@ -1691,10 +1744,10 @@ impl BeaconChain { let mut dump = vec![]; let mut last_slot = CheckPoint { - beacon_block: self.head().beacon_block.clone(), - beacon_block_root: self.head().beacon_block_root, - beacon_state: self.head().beacon_state.clone(), - beacon_state_root: self.head().beacon_state_root, + beacon_block: self.head()?.beacon_block.clone(), + beacon_block_root: self.head()?.beacon_block_root, + beacon_state: self.head()?.beacon_state.clone(), + beacon_state_root: self.head()?.beacon_state_root, }; dump.push(last_slot.clone()); diff --git a/beacon_node/beacon_chain/src/builder.rs b/beacon_node/beacon_chain/src/builder.rs index 885965ca53..43992262e8 100644 --- a/beacon_node/beacon_chain/src/builder.rs +++ b/beacon_node/beacon_chain/src/builder.rs @@ -3,20 +3,20 @@ use crate::eth1_chain::CachingEth1Backend; use crate::events::NullEventHandler; use crate::head_tracker::HeadTracker; use crate::persisted_beacon_chain::{PersistedBeaconChain, BEACON_CHAIN_DB_KEY}; +use crate::timeout_rw_lock::TimeoutRwLock; use crate::{ BeaconChain, BeaconChainTypes, CheckPoint, Eth1Chain, Eth1ChainBackend, EventHandler, ForkChoice, }; use eth1::Config as Eth1Config; use operation_pool::OperationPool; -use parking_lot::RwLock; use proto_array_fork_choice::ProtoArrayForkChoice; use slog::{info, Logger}; use slot_clock::{SlotClock, TestingSlotClock}; use std::marker::PhantomData; use std::sync::Arc; use std::time::Duration; -use store::Store; +use store::{BlockRootTree, Store}; use types::{BeaconBlock, BeaconState, ChainSpec, EthSpec, Hash256, Slot}; /// An empty struct used to "witness" all the `BeaconChainTypes` traits. It has no user-facing @@ -72,6 +72,7 @@ pub struct BeaconChainBuilder { slot_clock: Option, persisted_beacon_chain: Option>, head_tracker: Option, + block_root_tree: Option>, spec: ChainSpec, log: Option, } @@ -105,6 +106,7 @@ where slot_clock: None, persisted_beacon_chain: None, head_tracker: None, + block_root_tree: None, spec: TEthSpec::default_spec(), log: None, } @@ -187,6 +189,7 @@ where HeadTracker::from_ssz_container(&p.ssz_head_tracker) .map_err(|e| format!("Failed to decode head tracker for database: {:?}", e))?, ); + self.block_root_tree = Some(Arc::new(p.block_root_tree.clone().into())); self.persisted_beacon_chain = Some(p); Ok(self) @@ -229,6 +232,11 @@ where ) })?; + self.block_root_tree = Some(Arc::new(BlockRootTree::new( + beacon_block_root, + beacon_block.slot, + ))); + self.finalized_checkpoint = Some(CheckPoint { beacon_block_root, beacon_block, @@ -319,7 +327,7 @@ where .op_pool .ok_or_else(|| "Cannot build without op pool".to_string())?, eth1_chain: self.eth1_chain, - canonical_head: RwLock::new(canonical_head), + canonical_head: TimeoutRwLock::new(canonical_head), genesis_block_root: self .genesis_block_root .ok_or_else(|| "Cannot build without a genesis block root".to_string())?, @@ -330,16 +338,23 @@ where .event_handler .ok_or_else(|| "Cannot build without an event handler".to_string())?, head_tracker: self.head_tracker.unwrap_or_default(), + block_root_tree: self + .block_root_tree + .ok_or_else(|| "Cannot build without a block root tree".to_string())?, checkpoint_cache: CheckPointCache::default(), log: log.clone(), }; + let head = beacon_chain + .head() + .map_err(|e| format!("Failed to get head: {:?}", e))?; + info!( log, "Beacon chain initialized"; - "head_state" => format!("{}", beacon_chain.head().beacon_state_root), - "head_block" => format!("{}", beacon_chain.head().beacon_block_root), - "head_slot" => format!("{}", beacon_chain.head().beacon_block.slot), + "head_state" => format!("{}", head.beacon_state_root), + "head_block" => format!("{}", head.beacon_block_root), + "head_slot" => format!("{}", head.beacon_block.slot), ); Ok(beacon_chain) @@ -563,7 +578,8 @@ mod test { .build() .expect("should build"); - let head = chain.head(); + let head = chain.head().expect("should get head"); + let state = head.beacon_state; let block = head.beacon_block; diff --git a/beacon_node/beacon_chain/src/checkpoint_cache.rs b/beacon_node/beacon_chain/src/checkpoint_cache.rs index 73e9746ae9..3832182e9b 100644 --- a/beacon_node/beacon_chain/src/checkpoint_cache.rs +++ b/beacon_node/beacon_chain/src/checkpoint_cache.rs @@ -1,6 +1,7 @@ use crate::checkpoint::CheckPoint; use crate::metrics; use parking_lot::RwLock; +use std::borrow::Cow; use types::{BeaconBlock, BeaconState, EthSpec, Hash256}; const CACHE_SIZE: usize = 4; @@ -34,7 +35,7 @@ impl Default for CheckPointCache { } impl CheckPointCache { - pub fn insert(&self, checkpoint: &CheckPoint) { + pub fn insert(&self, checkpoint: Cow>) { if self .inner .read() @@ -50,10 +51,10 @@ impl CheckPointCache { let mut inner = self.inner.write(); if inner.checkpoints.len() < inner.limit { - inner.checkpoints.push(checkpoint.clone()) + inner.checkpoints.push(checkpoint.into_owned()) } else { let i = inner.oldest; // to satisfy the borrow checker. - inner.checkpoints[i] = checkpoint.clone(); + inner.checkpoints[i] = checkpoint.into_owned(); inner.oldest += 1; inner.oldest %= inner.limit; } diff --git a/beacon_node/beacon_chain/src/errors.rs b/beacon_node/beacon_chain/src/errors.rs index 1dae2ff197..809fb1d600 100644 --- a/beacon_node/beacon_chain/src/errors.rs +++ b/beacon_node/beacon_chain/src/errors.rs @@ -5,6 +5,7 @@ use state_processing::per_block_processing::errors::AttestationValidationError; use state_processing::BlockProcessingError; use state_processing::SlotProcessingError; use std::time::Duration; +use store::block_root_tree::BlockRootTreeError; use types::*; macro_rules! easy_from_to { @@ -48,11 +49,14 @@ pub enum BeaconChainError { /// Returned when an internal check fails, indicating corrupt data. InvariantViolated(String), SszTypesError(SszTypesError), + CanonicalHeadLockTimeout, + BlockRootTreeError(BlockRootTreeError), } easy_from_to!(SlotProcessingError, BeaconChainError); easy_from_to!(AttestationValidationError, BeaconChainError); easy_from_to!(SszTypesError, BeaconChainError); +easy_from_to!(BlockRootTreeError, BeaconChainError); #[derive(Debug, PartialEq)] pub enum BlockProductionError { diff --git a/beacon_node/beacon_chain/src/fork_choice.rs b/beacon_node/beacon_chain/src/fork_choice.rs index 018412a116..5f8b32a9f1 100644 --- a/beacon_node/beacon_chain/src/fork_choice.rs +++ b/beacon_node/beacon_chain/src/fork_choice.rs @@ -94,8 +94,16 @@ impl JustificationManager { ) -> Result<()> { let new_checkpoint = &state.current_justified_checkpoint; - // Only proceeed if the new checkpoint is better than our best checkpoint. - if new_checkpoint.epoch > self.best_justified_checkpoint.epoch { + // TODO: add check about block.slot <= justified epoch start slot. + + // Only proceeed if the new checkpoint is better than our current checkpoint. + if new_checkpoint.epoch > self.justified_checkpoint.epoch { + let new_checkpoint_balances = CheckpointBalances { + epoch: state.current_justified_checkpoint.epoch, + root: state.current_justified_checkpoint.root, + balances: state.balances.clone().into(), + }; + // From the given state, read the block root at first slot of // `self.justified_checkpoint.epoch`. If that root matches, then // `new_justified_checkpoint` is a descendant of `self.justified_checkpoint` and we may @@ -109,12 +117,15 @@ impl JustificationManager { .start_slot(T::EthSpec::slots_per_epoch()), )?; + // If the new justified checkpoint is an ancestor of the current justified checkpoint, + // it is always safe to change it. if new_checkpoint_ancestor == Some(self.justified_checkpoint.root) { - self.best_justified_checkpoint = CheckpointBalances { - epoch: state.current_justified_checkpoint.epoch, - root: state.current_justified_checkpoint.root, - balances: state.balances.clone().into(), - }; + self.justified_checkpoint = new_checkpoint_balances.clone() + } + + if new_checkpoint.epoch > self.best_justified_checkpoint.epoch { + // Always update the best checkpoint, if it's better. + self.best_justified_checkpoint = new_checkpoint_balances; } } @@ -201,6 +212,14 @@ impl ForkChoice { pub fn find_head(&self, chain: &BeaconChain) -> Result { let timer = metrics::start_timer(&metrics::FORK_CHOICE_FIND_HEAD_TIMES); + let remove_alias = |root| { + if root == Hash256::zero() { + self.genesis_block_root + } else { + root + } + }; + self.justification_manager.write().update(chain)?; let justified_checkpoint = self @@ -214,9 +233,9 @@ impl ForkChoice { .backend .find_head( justified_checkpoint.epoch, - justified_checkpoint.root, + remove_alias(justified_checkpoint.root), finalized_checkpoint.epoch, - finalized_checkpoint.root, + remove_alias(finalized_checkpoint.root), &justified_checkpoint.balances, ) .map_err(Into::into); @@ -244,6 +263,12 @@ impl ForkChoice { .process_state(state, chain)?; self.justification_manager.write().update(chain)?; + // TODO: be more stringent about changing the finalized checkpoint (i.e., check for + // reversion and stuff). + if state.finalized_checkpoint.epoch > self.finalized_checkpoint.read().epoch { + *self.finalized_checkpoint.write() = state.finalized_checkpoint.clone(); + } + // Note: we never count the block as a latest message, only attestations. for attestation in &block.body.attestations { // If the `data.beacon_block_root` block is not known to the fork choice, simply ignore @@ -332,12 +357,19 @@ impl ForkChoice { finalized_block: &BeaconBlock, finalized_block_root: Hash256, ) -> Result<()> { - self.backend - .update_finalized_root( - finalized_block.slot.epoch(T::EthSpec::slots_per_epoch()), - finalized_block_root, - ) - .map_err(Into::into) + // Only prune if it won't remove our current justified epoch. + if self.justification_manager.read().justified_checkpoint.epoch + >= finalized_block.slot.epoch(T::EthSpec::slots_per_epoch()) + { + self.backend + .update_finalized_root( + finalized_block.slot.epoch(T::EthSpec::slots_per_epoch()), + finalized_block_root, + ) + .map_err(Into::into) + } else { + Ok(()) + } } /// Returns a `SszForkChoice` which contains the current state of `Self`. diff --git a/beacon_node/beacon_chain/src/lib.rs b/beacon_node/beacon_chain/src/lib.rs index 291af59437..3a02745b7b 100644 --- a/beacon_node/beacon_chain/src/lib.rs +++ b/beacon_node/beacon_chain/src/lib.rs @@ -14,6 +14,7 @@ mod head_tracker; mod metrics; mod persisted_beacon_chain; pub mod test_utils; +mod timeout_rw_lock; pub use self::beacon_chain::{ AttestationProcessingOutcome, BeaconChain, BeaconChainTypes, BlockProcessingOutcome, diff --git a/beacon_node/beacon_chain/src/metrics.rs b/beacon_node/beacon_chain/src/metrics.rs index 81e47ca42f..7ad92bf151 100644 --- a/beacon_node/beacon_chain/src/metrics.rs +++ b/beacon_node/beacon_chain/src/metrics.rs @@ -199,10 +199,9 @@ lazy_static! { /// Scrape the `beacon_chain` for metrics that are not constantly updated (e.g., the present slot, /// head state info, etc) and update the Prometheus `DEFAULT_REGISTRY`. pub fn scrape_for_metrics(beacon_chain: &BeaconChain) { - scrape_head_state::( - &beacon_chain.head().beacon_state, - beacon_chain.head().beacon_state_root, - ); + if let Ok(head) = beacon_chain.head() { + scrape_head_state::(&head.beacon_state, head.beacon_state_root) + } } /// Scrape the given `state` assuming it's the head state, updating the `DEFAULT_REGISTRY`. diff --git a/beacon_node/beacon_chain/src/persisted_beacon_chain.rs b/beacon_node/beacon_chain/src/persisted_beacon_chain.rs index 08b75420d2..7f42466e22 100644 --- a/beacon_node/beacon_chain/src/persisted_beacon_chain.rs +++ b/beacon_node/beacon_chain/src/persisted_beacon_chain.rs @@ -4,7 +4,7 @@ use crate::{BeaconChainTypes, CheckPoint}; use operation_pool::PersistedOperationPool; use ssz::{Decode, Encode}; use ssz_derive::{Decode, Encode}; -use store::{DBColumn, Error as StoreError, SimpleStoreItem}; +use store::{DBColumn, Error as StoreError, SimpleStoreItem, SszBlockRootTree}; use types::Hash256; /// 32-byte key for accessing the `PersistedBeaconChain`. @@ -18,6 +18,7 @@ pub struct PersistedBeaconChain { pub genesis_block_root: Hash256, pub ssz_head_tracker: SszHeadTracker, pub fork_choice: SszForkChoice, + pub block_root_tree: SszBlockRootTree, } impl SimpleStoreItem for PersistedBeaconChain { diff --git a/beacon_node/beacon_chain/src/test_utils.rs b/beacon_node/beacon_chain/src/test_utils.rs index 364843aede..8598b4d5bd 100644 --- a/beacon_node/beacon_chain/src/test_utils.rs +++ b/beacon_node/beacon_chain/src/test_utils.rs @@ -459,7 +459,12 @@ where honest_fork_blocks: usize, faulty_fork_blocks: usize, ) -> (Hash256, Hash256) { - let initial_head_slot = self.chain.head().beacon_block.slot; + let initial_head_slot = self + .chain + .head() + .expect("should get head") + .beacon_block + .slot; // Move to the next slot so we may produce some more blocks on the head. self.advance_slot(); diff --git a/beacon_node/beacon_chain/src/timeout_rw_lock.rs b/beacon_node/beacon_chain/src/timeout_rw_lock.rs new file mode 100644 index 0000000000..19d3c3d4fa --- /dev/null +++ b/beacon_node/beacon_chain/src/timeout_rw_lock.rs @@ -0,0 +1,20 @@ +use parking_lot::{RwLock, RwLockReadGuard, RwLockWriteGuard}; +use std::time::Duration; + +/// A simple wrapper around `parking_lot::RwLock` that only permits read/write access with a +/// time-out (i.e., no indefinitely-blocking operations). +pub struct TimeoutRwLock(RwLock); + +impl TimeoutRwLock { + pub fn new(inner: T) -> Self { + Self(RwLock::new(inner)) + } + + pub fn try_read_for(&self, timeout: Duration) -> Option> { + self.0.try_read_for(timeout) + } + + pub fn try_write_for(&self, timeout: Duration) -> Option> { + self.0.try_write_for(timeout) + } +} diff --git a/beacon_node/beacon_chain/tests/persistence_tests.rs b/beacon_node/beacon_chain/tests/persistence_tests.rs index c88bbcb951..8afe570c17 100644 --- a/beacon_node/beacon_chain/tests/persistence_tests.rs +++ b/beacon_node/beacon_chain/tests/persistence_tests.rs @@ -59,7 +59,14 @@ fn finalizes_after_resuming_from_db() { ); assert!( - harness.chain.head().beacon_state.finalized_checkpoint.epoch > 0, + harness + .chain + .head() + .expect("should read head") + .beacon_state + .finalized_checkpoint + .epoch + > 0, "the chain should have already finalized" ); @@ -95,7 +102,11 @@ fn finalizes_after_resuming_from_db() { AttestationStrategy::AllValidators, ); - let state = &resumed_harness.chain.head().beacon_state; + let state = &resumed_harness + .chain + .head() + .expect("should read head") + .beacon_state; assert_eq!( state.slot, num_blocks_produced, "head should be at the current slot" diff --git a/beacon_node/beacon_chain/tests/store_tests.rs b/beacon_node/beacon_chain/tests/store_tests.rs index 2484062dd9..06d096c9b4 100644 --- a/beacon_node/beacon_chain/tests/store_tests.rs +++ b/beacon_node/beacon_chain/tests/store_tests.rs @@ -6,6 +6,7 @@ extern crate lazy_static; use beacon_chain::test_utils::{ AttestationStrategy, BeaconChainHarness, BlockStrategy, DiskHarnessType, }; +use beacon_chain::AttestationProcessingOutcome; use rand::Rng; use sloggers::{null::NullLoggerBuilder, Build}; use std::sync::Arc; @@ -96,7 +97,7 @@ fn randomised_skips() { } } - let state = &harness.chain.head().beacon_state; + let state = &harness.chain.head().expect("should get head").beacon_state; assert_eq!(state.slot, num_slots, "head should be at the current slot"); @@ -166,6 +167,7 @@ fn randao_genesis_storage() { let genesis_value = *harness .chain .head() + .expect("should get head") .beacon_state .get_randao_mix(Epoch::new(0)) .expect("randao mix ok"); @@ -181,6 +183,7 @@ fn randao_genesis_storage() { assert!(harness .chain .head() + .expect("should get head") .beacon_state .randao_mixes .iter() @@ -197,6 +200,7 @@ fn randao_genesis_storage() { assert!(harness .chain .head() + .expect("should get head") .beacon_state .randao_mixes .iter() @@ -236,9 +240,89 @@ fn split_slot_restore() { assert_eq!(store.get_split_slot(), split_slot); } +// Check attestation processing and `load_epoch_boundary_state` in the presence of a split DB. +// This is a bit of a monster test in that it tests lots of different things, but until they're +// tested elsewhere, this is as good a place as any. +#[test] +fn epoch_boundary_state_attestation_processing() { + let num_blocks_produced = E::slots_per_epoch() * 5; + let db_path = tempdir().unwrap(); + let store = get_store(&db_path); + let harness = get_harness(store.clone(), VALIDATOR_COUNT); + + let late_validators = vec![0, 1]; + let timely_validators = (2..VALIDATOR_COUNT).collect::>(); + + let mut late_attestations = vec![]; + + for _ in 0..num_blocks_produced { + harness.extend_chain( + 1, + BlockStrategy::OnCanonicalHead, + AttestationStrategy::SomeValidators(timely_validators.clone()), + ); + + let head = harness.chain.head().expect("head ok"); + late_attestations.extend(harness.get_free_attestations( + &AttestationStrategy::SomeValidators(late_validators.clone()), + &head.beacon_state, + head.beacon_block_root, + head.beacon_block.slot, + )); + + harness.advance_slot(); + } + + check_finalization(&harness, num_blocks_produced); + check_split_slot(&harness, store.clone()); + check_chain_dump(&harness, num_blocks_produced + 1); + check_iterators(&harness); + + let mut checked_pre_fin = false; + + for attestation in late_attestations { + // load_epoch_boundary_state is idempotent! + let block_root = attestation.data.beacon_block_root; + let block: BeaconBlock = store.get(&block_root).unwrap().expect("block exists"); + let epoch_boundary_state = store + .load_epoch_boundary_state(&block.state_root) + .expect("no error") + .expect("epoch boundary state exists"); + let ebs_of_ebs = store + .load_epoch_boundary_state(&epoch_boundary_state.canonical_root()) + .expect("no error") + .expect("ebs of ebs exists"); + assert_eq!(epoch_boundary_state, ebs_of_ebs); + + // If the attestation is pre-finalization it should be rejected. + let finalized_epoch = harness + .chain + .head_info() + .expect("head ok") + .finalized_checkpoint + .epoch; + let res = harness + .chain + .process_attestation_internal(attestation.clone()); + if attestation.data.slot <= finalized_epoch.start_slot(E::slots_per_epoch()) { + checked_pre_fin = true; + assert_eq!( + res, + Ok(AttestationProcessingOutcome::FinalizedSlot { + attestation: attestation.data.target.epoch, + finalized: finalized_epoch, + }) + ); + } else { + assert_eq!(res, Ok(AttestationProcessingOutcome::Processed)); + } + } + assert!(checked_pre_fin); +} + /// Check that the head state's slot matches `expected_slot`. fn check_slot(harness: &TestHarness, expected_slot: u64) { - let state = &harness.chain.head().beacon_state; + let state = &harness.chain.head().expect("should get head").beacon_state; assert_eq!( state.slot, expected_slot, @@ -248,7 +332,7 @@ fn check_slot(harness: &TestHarness, expected_slot: u64) { /// Check that the chain has finalized under best-case assumptions, and check the head slot. fn check_finalization(harness: &TestHarness, expected_slot: u64) { - let state = &harness.chain.head().beacon_state; + let state = &harness.chain.head().expect("should get head").beacon_state; check_slot(harness, expected_slot); @@ -271,6 +355,7 @@ fn check_split_slot(harness: &TestHarness, store: Arc>) { harness .chain .head() + .expect("should get head") .beacon_state .finalized_checkpoint .epoch @@ -314,7 +399,7 @@ fn check_chain_dump(harness: &TestHarness, expected_len: u64) { .map(|checkpoint| (checkpoint.beacon_block_root, checkpoint.beacon_block.slot)) .collect::>(); - let head = harness.chain.head(); + let head = harness.chain.head().expect("should get head"); let mut forward_block_roots = Store::forwards_block_roots_iterator( harness.chain.store.clone(), Slot::new(0), @@ -343,6 +428,7 @@ fn check_iterators(harness: &TestHarness) { harness .chain .rev_iter_state_roots() + .expect("should get iter") .last() .map(|(_, slot)| slot), Some(Slot::new(0)) @@ -351,6 +437,7 @@ fn check_iterators(harness: &TestHarness) { harness .chain .rev_iter_block_roots() + .expect("should get iter") .last() .map(|(_, slot)| slot), Some(Slot::new(0)) diff --git a/beacon_node/beacon_chain/tests/tests.rs b/beacon_node/beacon_chain/tests/tests.rs index 76756d528e..c88fcf4d14 100644 --- a/beacon_node/beacon_chain/tests/tests.rs +++ b/beacon_node/beacon_chain/tests/tests.rs @@ -37,7 +37,7 @@ fn get_harness(validator_count: usize) -> BeaconChainHarness = harness.chain.rev_iter_block_roots().collect(); - let state_roots: Vec<(Hash256, Slot)> = harness.chain.rev_iter_state_roots().collect(); + let block_roots: Vec<(Hash256, Slot)> = harness + .chain + .rev_iter_block_roots() + .expect("should get iter") + .collect(); + let state_roots: Vec<(Hash256, Slot)> = harness + .chain + .rev_iter_state_roots() + .expect("should get iter") + .collect(); assert_eq!( block_roots.len(), @@ -109,7 +117,7 @@ fn iterators() { ) }); - let head = &harness.chain.head(); + let head = &harness.chain.head().expect("should get head"); assert_eq!( *block_roots.first().expect("should have some block roots"), @@ -154,7 +162,7 @@ fn chooses_fork() { assert!(honest_head != faulty_head, "forks should be distinct"); - let state = &harness.chain.head().beacon_state; + let state = &harness.chain.head().expect("should get head").beacon_state; assert_eq!( state.slot, @@ -163,7 +171,11 @@ fn chooses_fork() { ); assert_eq!( - harness.chain.head().beacon_block_root, + harness + .chain + .head() + .expect("should get head") + .beacon_block_root, honest_head, "the honest chain should be the canonical chain" ); @@ -181,7 +193,7 @@ fn finalizes_with_full_participation() { AttestationStrategy::AllValidators, ); - let state = &harness.chain.head().beacon_state; + let state = &harness.chain.head().expect("should get head").beacon_state; assert_eq!( state.slot, num_blocks_produced, @@ -219,7 +231,7 @@ fn finalizes_with_two_thirds_participation() { AttestationStrategy::SomeValidators(attesters), ); - let state = &harness.chain.head().beacon_state; + let state = &harness.chain.head().expect("should get head").beacon_state; assert_eq!( state.slot, num_blocks_produced, @@ -263,7 +275,7 @@ fn does_not_finalize_with_less_than_two_thirds_participation() { AttestationStrategy::SomeValidators(attesters), ); - let state = &harness.chain.head().beacon_state; + let state = &harness.chain.head().expect("should get head").beacon_state; assert_eq!( state.slot, num_blocks_produced, @@ -296,7 +308,7 @@ fn does_not_finalize_without_attestation() { AttestationStrategy::SomeValidators(vec![]), ); - let state = &harness.chain.head().beacon_state; + let state = &harness.chain.head().expect("should get head").beacon_state; assert_eq!( state.slot, num_blocks_produced, @@ -357,7 +369,7 @@ fn free_attestations_added_to_fork_choice_some_none() { AttestationStrategy::AllValidators, ); - let state = &harness.chain.head().beacon_state; + let state = &harness.chain.head().expect("should get head").beacon_state; let fork_choice = &harness.chain.fork_choice; let validator_slots: Vec<(usize, Slot)> = (0..VALIDATOR_COUNT) @@ -409,12 +421,23 @@ fn attestations_with_increasing_slots() { AttestationStrategy::SomeValidators(vec![]), ); - attestations.append(&mut harness.get_free_attestations( - &AttestationStrategy::AllValidators, - &harness.chain.head().beacon_state, - harness.chain.head().beacon_block_root, - harness.chain.head().beacon_block.slot, - )); + attestations.append( + &mut harness.get_free_attestations( + &AttestationStrategy::AllValidators, + &harness.chain.head().expect("should get head").beacon_state, + harness + .chain + .head() + .expect("should get head") + .beacon_block_root, + harness + .chain + .head() + .expect("should get head") + .beacon_block + .slot, + ), + ); harness.advance_slot(); } @@ -439,7 +462,7 @@ fn free_attestations_added_to_fork_choice_all_updated() { AttestationStrategy::AllValidators, ); - let state = &harness.chain.head().beacon_state; + let state = &harness.chain.head().expect("should get head").beacon_state; let fork_choice = &harness.chain.fork_choice; let validators: Vec = (0..VALIDATOR_COUNT).collect(); @@ -496,17 +519,39 @@ fn run_skip_slot_test(skip_slots: u64) { ); assert_eq!( - harness_a.chain.head().beacon_block.slot, + harness_a + .chain + .head() + .expect("should get head") + .beacon_block + .slot, Slot::new(skip_slots + 1) ); - assert_eq!(harness_b.chain.head().beacon_block.slot, Slot::new(0)); - assert_eq!( harness_b .chain - .process_block(harness_a.chain.head().beacon_block.clone()), + .head() + .expect("should get head") + .beacon_block + .slot, + Slot::new(0) + ); + + assert_eq!( + harness_b.chain.process_block( + harness_a + .chain + .head() + .expect("should get head") + .beacon_block + .clone() + ), Ok(BlockProcessingOutcome::Processed { - block_root: harness_a.chain.head().beacon_block_root + block_root: harness_a + .chain + .head() + .expect("should get head") + .beacon_block_root }) ); @@ -516,7 +561,12 @@ fn run_skip_slot_test(skip_slots: u64) { .expect("should run fork choice"); assert_eq!( - harness_b.chain.head().beacon_block.slot, + harness_b + .chain + .head() + .expect("should get head") + .beacon_block + .slot, Slot::new(skip_slots + 1) ); } diff --git a/beacon_node/client/src/notifier.rs b/beacon_node/client/src/notifier.rs index cd23f9b47b..3785821003 100644 --- a/beacon_node/client/src/notifier.rs +++ b/beacon_node/client/src/notifier.rs @@ -37,6 +37,7 @@ pub fn spawn_notifier( ) -> Result { let log_1 = context.log.clone(); let log_2 = context.log.clone(); + let log_3 = context.log.clone(); let slot_duration = Duration::from_millis(milliseconds_per_slot); let duration_to_next_slot = beacon_chain @@ -69,7 +70,12 @@ pub fn spawn_notifier( usize::max_value() }; - let head = beacon_chain.head(); + let head = beacon_chain.head() + .map_err(|e| error!( + log, + "Failed to get beacon chain head"; + "error" => format!("{:?}", e) + ))?; let head_slot = head.beacon_block.slot; let head_epoch = head_slot.epoch(T::EthSpec::slots_per_epoch()); @@ -117,9 +123,9 @@ pub fn spawn_notifier( log, "Syncing"; "peers" => peer_count_pretty(connected_peer_count), - "est_time" => estimated_time_pretty(speedo.estimated_time_till_slot(current_slot)), + "distance" => distance, "speed" => sync_speed_pretty(speedo.slots_per_second()), - "distance" => distance + "est_time" => estimated_time_pretty(speedo.estimated_time_till_slot(current_slot)), ); return Ok(()); @@ -156,6 +162,16 @@ pub fn spawn_notifier( }; Ok(()) + }) + .then(move |result| { + match result { + Ok(()) => Ok(()), + Err(e) => Ok(error!( + log_3, + "Notifier failed to notify"; + "error" => format!("{:?}", e) + )) + } }); let (exit_signal, exit) = exit_future::signal(); diff --git a/beacon_node/eth1/src/service.rs b/beacon_node/eth1/src/service.rs index 7cfd060a32..e6a763abf6 100644 --- a/beacon_node/eth1/src/service.rs +++ b/beacon_node/eth1/src/service.rs @@ -316,13 +316,13 @@ impl Service { match update_result { Err(e) => error!( log_a, - "Failed to update eth1 genesis cache"; + "Failed to update eth1 cache"; "retry_millis" => update_interval.as_millis(), "error" => e, ), Ok((deposit, block)) => debug!( log_a, - "Updated eth1 genesis cache"; + "Updated eth1 cache"; "retry_millis" => update_interval.as_millis(), "blocks" => format!("{:?}", block), "deposits" => format!("{:?}", deposit), diff --git a/beacon_node/eth2-libp2p/Cargo.toml b/beacon_node/eth2-libp2p/Cargo.toml index fab2f6fd11..f8180711e7 100644 --- a/beacon_node/eth2-libp2p/Cargo.toml +++ b/beacon_node/eth2-libp2p/Cargo.toml @@ -8,8 +8,8 @@ edition = "2018" hex = "0.3" # rust-libp2p is presently being sourced from a Sigma Prime fork of the # `libp2p/rust-libp2p` repository. -libp2p = { git = "https://github.com/SigP/rust-libp2p", rev = "c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e" } -enr = { git = "https://github.com/SigP/rust-libp2p/", rev = "c0c71fa4d7e6621cafe2c087d1aa1bc60dd9116e", features = ["serde"] } +libp2p = { git = "https://github.com/SigP/rust-libp2p", rev = "735313ebda6a98604929f6c4606aefac19e00760" } +enr = { git = "https://github.com/SigP/rust-libp2p/", rev = "735313ebda6a98604929f6c4606aefac19e00760", features = ["serde"] } types = { path = "../../eth2/types" } serde = "1.0.102" serde_derive = "1.0.102" diff --git a/beacon_node/eth2-libp2p/src/rpc/handler.rs b/beacon_node/eth2-libp2p/src/rpc/handler.rs index 31a0ba3e1e..19c752a7b8 100644 --- a/beacon_node/eth2-libp2p/src/rpc/handler.rs +++ b/beacon_node/eth2-libp2p/src/rpc/handler.rs @@ -1,7 +1,7 @@ #![allow(clippy::type_complexity)] #![allow(clippy::cognitive_complexity)] -use super::methods::{RPCErrorResponse, RequestId}; +use super::methods::{ErrorMessage, RPCErrorResponse, RequestId, ResponseTermination}; use super::protocol::{RPCError, RPCProtocol, RPCRequest}; use super::RPCEvent; use crate::rpc::protocol::{InboundFramed, OutboundFramed}; @@ -28,7 +28,8 @@ pub const RESPONSE_TIMEOUT: u64 = 10; /// The number of times to retry an outbound upgrade in the case of IO errors. const IO_ERROR_RETRIES: u8 = 3; -/// Inbound requests are given a sequential `RequestId` to keep track of. +/// Inbound requests are given a sequential `RequestId` to keep track of. All inbound streams are +/// identified by their substream ID which is identical to the RPC Id. type InboundRequestId = RequestId; /// Outbound requests are associated with an id that is given by the application that sent the /// request. @@ -72,8 +73,8 @@ where /// Map of outbound items that are queued as the stream processes them. queued_outbound_items: FnvHashMap>, - /// Sequential Id for waiting substreams. - current_substream_id: RequestId, + /// Sequential ID for waiting substreams. For inbound substreams, this is also the inbound request ID. + current_inbound_substream_id: RequestId, /// Maximum number of concurrent outbound substreams being opened. Value is never modified. max_dial_negotiated: u32, @@ -153,7 +154,7 @@ where outbound_substreams: FnvHashMap::default(), inbound_substreams_delay: DelayQueue::new(), outbound_substreams_delay: DelayQueue::new(), - current_substream_id: 1, + current_inbound_substream_id: 1, max_dial_negotiated: 8, keep_alive: KeepAlive::Yes, inactive_timeout, @@ -226,16 +227,18 @@ where // New inbound request. Store the stream and tag the output. let delay_key = self.inbound_substreams_delay.insert( - self.current_substream_id, + self.current_inbound_substream_id, Duration::from_secs(RESPONSE_TIMEOUT), ); let awaiting_stream = InboundSubstreamState::ResponseIdle(substream); - self.inbound_substreams - .insert(self.current_substream_id, (awaiting_stream, delay_key)); + self.inbound_substreams.insert( + self.current_inbound_substream_id, + (awaiting_stream, delay_key), + ); self.events_out - .push(RPCEvent::Request(self.current_substream_id, req)); - self.current_substream_id += 1; + .push(RPCEvent::Request(self.current_inbound_substream_id, req)); + self.current_inbound_substream_id += 1; } fn inject_fully_negotiated_outbound( @@ -306,11 +309,10 @@ where if res_is_multiple => { // the stream is in use, add the request to a pending queue - (*self - .queued_outbound_items + self.queued_outbound_items .entry(rpc_id) - .or_insert_with(Vec::new)) - .push(response); + .or_insert_with(Vec::new) + .push(response); // return the state *substream_state = InboundSubstreamState::ResponsePendingSend { @@ -431,13 +433,57 @@ where self.events_out.shrink_to_fit(); } - // purge expired inbound substreams + // purge expired inbound substreams and send an error while let Async::Ready(Some(stream_id)) = self .inbound_substreams_delay .poll() .map_err(|_| ProtocolsHandlerUpgrErr::Timer)? { - self.inbound_substreams.remove(stream_id.get_ref()); + let rpc_id = stream_id.get_ref(); + + // handle a stream timeout for various states + if let Some((substream_state, _)) = self.inbound_substreams.get_mut(rpc_id) { + // When terminating a stream, report the stream termination to the requesting user via + // an RPC error + let error = RPCErrorResponse::ServerError(ErrorMessage { + error_message: "Request timed out".as_bytes().to_vec(), + }); + // The stream termination type is irrelevant, this will terminate the + // stream + let stream_termination = + RPCErrorResponse::StreamTermination(ResponseTermination::BlocksByRange); + + match std::mem::replace(substream_state, InboundSubstreamState::Poisoned) { + InboundSubstreamState::ResponsePendingSend { substream, closing } => { + if !closing { + // if the stream is not closing, add an error to the stream queue and exit + let queue = self + .queued_outbound_items + .entry(*rpc_id) + .or_insert_with(Vec::new); + queue.push(error); + queue.push(stream_termination); + } + // if the stream is closing after the send, allow it to finish + + *substream_state = + InboundSubstreamState::ResponsePendingSend { substream, closing } + } + InboundSubstreamState::ResponseIdle(substream) => { + *substream_state = InboundSubstreamState::ResponsePendingSend { + substream: substream.send(error), + closing: true, + }; + } + InboundSubstreamState::Closing(substream) => { + // let the stream close + *substream_state = InboundSubstreamState::Closing(substream); + } + InboundSubstreamState::Poisoned => { + unreachable!("Coding error: Timeout poisoned substream") + } + }; + } } // purge expired outbound substreams @@ -555,7 +601,7 @@ where request, } => match substream.poll() { Ok(Async::Ready(Some(response))) => { - if request.multiple_responses() { + if request.multiple_responses() && !response.is_error() { entry.get_mut().0 = OutboundSubstreamState::RequestPendingResponse { substream, @@ -565,10 +611,13 @@ where self.outbound_substreams_delay .reset(delay_key, Duration::from_secs(RESPONSE_TIMEOUT)); } else { + // either this is a single response request or we received an + // error trace!(self.log, "Closing single stream request"); // only expect a single response, close the stream entry.get_mut().0 = OutboundSubstreamState::Closing(substream); } + return Ok(Async::Ready(ProtocolsHandlerEvent::Custom( RPCEvent::Response(request_id, response), ))); diff --git a/beacon_node/network/src/message_processor.rs b/beacon_node/network/src/message_processor.rs index 2df8fda7a5..21b28f68dd 100644 --- a/beacon_node/network/src/message_processor.rs +++ b/beacon_node/network/src/message_processor.rs @@ -45,9 +45,9 @@ impl From for PeerSyncInfo { } } -impl From<&Arc>> for PeerSyncInfo { - fn from(chain: &Arc>) -> PeerSyncInfo { - Self::from(status_message(chain)) +impl PeerSyncInfo { + pub fn from_chain(chain: &Arc>) -> Option { + Some(Self::from(status_message(chain)?)) } } @@ -119,8 +119,10 @@ impl MessageProcessor { /// /// Sends a `Status` message to the peer. pub fn on_connect(&mut self, peer_id: PeerId) { - self.network - .send_rpc_request(peer_id, RPCRequest::Status(status_message(&self.chain))); + if let Some(status_message) = status_message(&self.chain) { + self.network + .send_rpc_request(peer_id, RPCRequest::Status(status_message)); + } } /// Handle a `Status` request. @@ -135,12 +137,14 @@ impl MessageProcessor { // ignore status responses if we are shutting down trace!(self.log, "StatusRequest"; "peer" => format!("{:?}", peer_id)); - // Say status back. - self.network.send_rpc_response( - peer_id.clone(), - request_id, - RPCResponse::Status(status_message(&self.chain)), - ); + if let Some(status_message) = status_message(&self.chain) { + // Say status back. + self.network.send_rpc_response( + peer_id.clone(), + request_id, + RPCResponse::Status(status_message), + ); + } self.process_status(peer_id, status); } @@ -158,7 +162,16 @@ impl MessageProcessor { /// Disconnects the peer if required. fn process_status(&mut self, peer_id: PeerId, status: StatusMessage) { let remote = PeerSyncInfo::from(status); - let local = PeerSyncInfo::from(&self.chain); + let local = match PeerSyncInfo::from_chain(&self.chain) { + Some(local) => local, + None => { + return error!( + self.log, + "Failed to get peer sync info"; + "msg" => "likely due to head lock contention" + ) + } + }; let start_slot = |epoch: Epoch| epoch.start_slot(T::EthSpec::slots_per_epoch()); @@ -191,8 +204,11 @@ impl MessageProcessor { } else if remote.finalized_epoch <= local.finalized_epoch && remote.finalized_root != Hash256::zero() && local.finalized_root != Hash256::zero() - && (self.chain.root_at_slot(start_slot(remote.finalized_epoch)) - != Some(remote.finalized_root)) + && self + .chain + .root_at_slot(start_slot(remote.finalized_epoch)) + .map(|root_opt| root_opt != Some(remote.finalized_root)) + .unwrap_or_else(|_| false) { // The remotes finalized epoch is less than or greater than ours, but the block root is // different to the one in our chain. @@ -321,9 +337,21 @@ impl MessageProcessor { return; } - let mut block_roots = self + let forwards_block_root_iter = match self .chain .forwards_iter_block_roots(Slot::from(req.start_slot)) + { + Ok(iter) => iter, + Err(e) => { + return error!( + self.log, + "Unable to obtain root iter"; + "error" => format!("{:?}", e) + ) + } + }; + + let mut block_roots = forwards_block_root_iter .take_while(|(_root, slot)| slot.as_u64() < req.start_slot + req.count * req.step) .step_by(req.step as usize) .map(|(root, _slot)| root) @@ -356,7 +384,7 @@ impl MessageProcessor { } if blocks_sent < (req.count as usize) { - trace!( + debug!( self.log, "BlocksByRange Response Sent"; "peer" => format!("{:?}", peer_id), @@ -366,7 +394,7 @@ impl MessageProcessor { "requested" => req.count, "returned" => blocks_sent); } else { - trace!( + debug!( self.log, "Sending BlocksByRange Response"; "peer" => format!("{:?}", peer_id), @@ -552,16 +580,18 @@ impl MessageProcessor { } /// Build a `StatusMessage` representing the state of the given `beacon_chain`. -pub(crate) fn status_message(beacon_chain: &BeaconChain) -> StatusMessage { - let state = &beacon_chain.head().beacon_state; +pub(crate) fn status_message( + beacon_chain: &BeaconChain, +) -> Option { + let head_info = beacon_chain.head_info().ok()?; - StatusMessage { - fork_version: state.fork.current_version, - finalized_root: state.finalized_checkpoint.root, - finalized_epoch: state.finalized_checkpoint.epoch, - head_root: beacon_chain.head().beacon_block_root, - head_slot: state.slot, - } + Some(StatusMessage { + fork_version: head_info.fork.current_version, + finalized_root: head_info.finalized_checkpoint.root, + finalized_epoch: head_info.finalized_checkpoint.epoch, + head_root: head_info.block_root, + head_slot: head_info.slot, + }) } /// Wraps a Network Channel to employ various RPC related network functionality for the message diff --git a/beacon_node/network/src/sync/manager.rs b/beacon_node/network/src/sync/manager.rs index f39d91da5c..3883f27396 100644 --- a/beacon_node/network/src/sync/manager.rs +++ b/beacon_node/network/src/sync/manager.rs @@ -229,7 +229,16 @@ impl SyncManager { } }; - let local = PeerSyncInfo::from(&chain); + let local = match PeerSyncInfo::from_chain(&chain) { + Some(local) => local, + None => { + return error!( + self.log, + "Failed to get peer sync info"; + "msg" => "likely due to head lock contention" + ) + } + }; // If a peer is within SLOT_IMPORT_TOLERANCE from our head slot, ignore a batch/range sync, // consider it a fully-sync'd peer. diff --git a/beacon_node/network/src/sync/network_context.rs b/beacon_node/network/src/sync/network_context.rs index 67d53a0954..e885332605 100644 --- a/beacon_node/network/src/sync/network_context.rs +++ b/beacon_node/network/src/sync/network_context.rs @@ -43,7 +43,9 @@ impl SyncNetworkContext { "peer" => format!("{:?}", peer_id) ); if let Some(chain) = chain.upgrade() { - let _ = self.send_rpc_request(peer_id, RPCRequest::Status(status_message(&chain))); + if let Some(status_message) = status_message(&chain) { + let _ = self.send_rpc_request(peer_id, RPCRequest::Status(status_message)); + } } } diff --git a/beacon_node/network/src/sync/range_sync/chain.rs b/beacon_node/network/src/sync/range_sync/chain.rs index 52b47f1086..fac2d82230 100644 --- a/beacon_node/network/src/sync/range_sync/chain.rs +++ b/beacon_node/network/src/sync/range_sync/chain.rs @@ -564,6 +564,9 @@ impl SyncingChain { ) -> ProcessingResult { batch.retries += 1; + // TODO: Handle partially downloaded batches. Update this when building a new batch + // processor thread. + if batch.retries > MAX_BATCH_RETRIES { // chain is unrecoverable, remove it ProcessingResult::RemoveChain diff --git a/beacon_node/network/src/sync/range_sync/chain_collection.rs b/beacon_node/network/src/sync/range_sync/chain_collection.rs index c8704c773e..68c0c9a26c 100644 --- a/beacon_node/network/src/sync/range_sync/chain_collection.rs +++ b/beacon_node/network/src/sync/range_sync/chain_collection.rs @@ -8,7 +8,7 @@ use crate::message_processor::PeerSyncInfo; use crate::sync::network_context::SyncNetworkContext; use beacon_chain::{BeaconChain, BeaconChainTypes}; use eth2_libp2p::PeerId; -use slog::{debug, warn}; +use slog::{debug, error, warn}; use std::sync::Weak; use types::EthSpec; use types::{Hash256, Slot}; @@ -103,9 +103,22 @@ impl ChainCollection { /// updates the state of the collection. pub fn update_finalized(&mut self, network: &mut SyncNetworkContext, log: &slog::Logger) { let local_slot = match self.beacon_chain.upgrade() { - Some(chain) => PeerSyncInfo::from(&chain) - .finalized_epoch - .start_slot(T::EthSpec::slots_per_epoch()), + Some(chain) => { + let local = match PeerSyncInfo::from_chain(&chain) { + Some(local) => local, + None => { + return error!( + log, + "Failed to get peer sync info"; + "msg" => "likely due to head lock contention" + ) + } + }; + + local + .finalized_epoch + .start_slot(T::EthSpec::slots_per_epoch()) + } None => { warn!(log, "Beacon chain dropped. Chains not updated"); return; @@ -113,7 +126,7 @@ impl ChainCollection { }; // Remove any outdated finalized chains - self.purge_outdated_chains(network); + self.purge_outdated_chains(network, log); // Check if any chains become the new syncing chain if let Some(index) = self.finalized_syncing_index() { @@ -248,14 +261,23 @@ impl ChainCollection { /// /// This removes chains with no peers, or chains whose start block slot is less than our current /// finalized block slot. - pub fn purge_outdated_chains(&mut self, network: &mut SyncNetworkContext) { + pub fn purge_outdated_chains(&mut self, network: &mut SyncNetworkContext, log: &slog::Logger) { // Remove any chains that have no peers self.finalized_chains .retain(|chain| !chain.peer_pool.is_empty()); self.head_chains.retain(|chain| !chain.peer_pool.is_empty()); let local_info = match self.beacon_chain.upgrade() { - Some(chain) => PeerSyncInfo::from(&chain), + Some(chain) => match PeerSyncInfo::from_chain(&chain) { + Some(local) => local, + None => { + return error!( + log, + "Failed to get peer sync info"; + "msg" => "likely due to head lock contention" + ) + } + }, None => { return; } diff --git a/beacon_node/network/src/sync/range_sync/range.rs b/beacon_node/network/src/sync/range_sync/range.rs index 750eb5ef98..35309f75df 100644 --- a/beacon_node/network/src/sync/range_sync/range.rs +++ b/beacon_node/network/src/sync/range_sync/range.rs @@ -46,7 +46,7 @@ use crate::sync::network_context::SyncNetworkContext; use beacon_chain::{BeaconChain, BeaconChainTypes}; use eth2_libp2p::rpc::RequestId; use eth2_libp2p::PeerId; -use slog::{debug, trace, warn}; +use slog::{debug, error, trace, warn}; use std::collections::HashSet; use std::sync::Weak; use types::{BeaconBlock, EthSpec}; @@ -106,7 +106,16 @@ impl RangeSync { // determine if we need to run a sync to the nearest finalized state or simply sync to // its current head let local_info = match self.beacon_chain.upgrade() { - Some(chain) => PeerSyncInfo::from(&chain), + Some(chain) => match PeerSyncInfo::from_chain(&chain) { + Some(local) => local, + None => { + return error!( + self.log, + "Failed to get peer sync info"; + "msg" => "likely due to head lock contention" + ) + } + }, None => { warn!(self.log, "Beacon chain dropped. Peer not considered for sync"; @@ -127,7 +136,7 @@ impl RangeSync { self.remove_peer(network, &peer_id); // remove any out-of-date chains - self.chains.purge_outdated_chains(network); + self.chains.purge_outdated_chains(network, &self.log); if remote_finalized_slot > local_info.head_slot { debug!(self.log, "Finalization sync peer joined"; "peer_id" => format!("{:?}", peer_id)); diff --git a/beacon_node/rest_api/src/beacon.rs b/beacon_node/rest_api/src/beacon.rs index 8b54381000..5bb67dd800 100644 --- a/beacon_node/rest_api/src/beacon.rs +++ b/beacon_node/rest_api/src/beacon.rs @@ -33,7 +33,7 @@ pub fn get_head( req: Request, beacon_chain: Arc>, ) -> ApiResult { - let chain_head = beacon_chain.head(); + let chain_head = beacon_chain.head()?; let head = CanonicalHeadResponse { slot: chain_head.beacon_state.slot, @@ -106,7 +106,7 @@ pub fn get_block( ("slot", value) => { let target = parse_slot(&value)?; - block_root_at_slot(&beacon_chain, target).ok_or_else(|| { + block_root_at_slot(&beacon_chain, target)?.ok_or_else(|| { ApiError::NotFound(format!("Unable to find BeaconBlock for slot {:?}", target)) })? } @@ -140,7 +140,7 @@ pub fn get_block_root( let slot_string = UrlQuery::from_request(&req)?.only_one("slot")?; let target = parse_slot(&slot_string)?; - let root = block_root_at_slot(&beacon_chain, target).ok_or_else(|| { + let root = block_root_at_slot(&beacon_chain, target)?.ok_or_else(|| { ApiError::NotFound(format!("Unable to find BeaconBlock for slot {:?}", target)) })?; @@ -152,7 +152,7 @@ pub fn get_fork( req: Request, beacon_chain: Arc>, ) -> ApiResult { - ResponseBuilder::new(&req)?.body(&beacon_chain.head().beacon_state.fork) + ResponseBuilder::new(&req)?.body(&beacon_chain.head()?.beacon_state.fork) } #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, Encode, Decode)] @@ -302,7 +302,7 @@ fn get_state_from_root_opt( })? .ok_or_else(|| ApiError::NotFound(format!("No state exists with root: {}", state_root))) } else { - Ok(beacon_chain.head().beacon_state) + Ok(beacon_chain.head()?.beacon_state) } } @@ -417,7 +417,7 @@ pub fn get_state( req: Request, beacon_chain: Arc>, ) -> ApiResult { - let head_state = beacon_chain.head().beacon_state; + let head_state = beacon_chain.head()?.beacon_state; let (key, value) = match UrlQuery::from_request(&req) { Ok(query) => { @@ -491,5 +491,5 @@ pub fn get_genesis_time( req: Request, beacon_chain: Arc>, ) -> ApiResult { - ResponseBuilder::new(&req)?.body(&beacon_chain.head().beacon_state.genesis_time) + ResponseBuilder::new(&req)?.body(&beacon_chain.head()?.beacon_state.genesis_time) } diff --git a/beacon_node/rest_api/src/error.rs b/beacon_node/rest_api/src/error.rs index 9f815a7d3b..dc8f4c91ea 100644 --- a/beacon_node/rest_api/src/error.rs +++ b/beacon_node/rest_api/src/error.rs @@ -60,6 +60,12 @@ impl From for ApiError { } } +impl From for ApiError { + fn from(e: beacon_chain::BeaconChainError) -> ApiError { + ApiError::ServerError(format!("BeaconChainError error: {:?}", e)) + } +} + impl From for ApiError { fn from(e: state_processing::per_slot_processing::Error) -> ApiError { ApiError::ServerError(format!("PerSlotProcessing error: {:?}", e)) diff --git a/beacon_node/rest_api/src/helpers.rs b/beacon_node/rest_api/src/helpers.rs index b0c8723aa9..e64c1e459b 100644 --- a/beacon_node/rest_api/src/helpers.rs +++ b/beacon_node/rest_api/src/helpers.rs @@ -120,12 +120,12 @@ pub fn parse_pubkey_bytes(string: &str) -> Result { pub fn block_root_at_slot( beacon_chain: &BeaconChain, target: Slot, -) -> Option { - beacon_chain - .rev_iter_block_roots() +) -> Result, ApiError> { + Ok(beacon_chain + .rev_iter_block_roots()? .take_while(|(_root, slot)| *slot >= target) .find(|(_root, slot)| *slot == target) - .map(|(root, _slot)| root) + .map(|(root, _slot)| root)) } /// Returns a `BeaconState` and it's root in the canonical chain of `beacon_chain` at the given @@ -137,15 +137,15 @@ pub fn state_at_slot( beacon_chain: &BeaconChain, slot: Slot, ) -> Result<(Hash256, BeaconState), ApiError> { - let head_state = &beacon_chain.head().beacon_state; + let head_state = &beacon_chain.head()?.beacon_state; if head_state.slot == slot { // The request slot is the same as the best block (head) slot. // I'm not sure if this `.clone()` will be optimized out. If not, it seems unnecessary. Ok(( - beacon_chain.head().beacon_state_root, - beacon_chain.head().beacon_state.clone(), + beacon_chain.head()?.beacon_state_root, + beacon_chain.head()?.beacon_state.clone(), )) } else { let root = state_root_at_slot(beacon_chain, slot)?; @@ -168,7 +168,7 @@ pub fn state_root_at_slot( beacon_chain: &BeaconChain, slot: Slot, ) -> Result { - let head_state = &beacon_chain.head().beacon_state; + let head_state = &beacon_chain.head()?.beacon_state; let current_slot = beacon_chain .slot() .map_err(|_| ApiError::ServerError("Unable to read slot clock".to_string()))?; @@ -192,7 +192,7 @@ pub fn state_root_at_slot( // 2. The request slot is the same as the best block (head) slot. // // The head state root is stored in memory, return a reference. - Ok(beacon_chain.head().beacon_state_root) + Ok(beacon_chain.head()?.beacon_state_root) } else if head_state.slot > slot { // 3. The request slot is prior to the head slot. // @@ -209,7 +209,7 @@ pub fn state_root_at_slot( // // Use `per_slot_processing` to advance the head state to the present slot, // assuming that all slots do not contain a block (i.e., they are skipped slots). - let mut state = beacon_chain.head().beacon_state.clone(); + let mut state = beacon_chain.head()?.beacon_state.clone(); let spec = &T::EthSpec::default_spec(); for _ in state.slot.as_u64()..slot.as_u64() { diff --git a/beacon_node/rest_api/src/validator.rs b/beacon_node/rest_api/src/validator.rs index 3276dd64cd..09565e3338 100644 --- a/beacon_node/rest_api/src/validator.rs +++ b/beacon_node/rest_api/src/validator.rs @@ -122,10 +122,10 @@ pub fn get_state_for_epoch( epoch: Epoch, ) -> Result, ApiError> { let slots_per_epoch = T::EthSpec::slots_per_epoch(); - let head_epoch = beacon_chain.head().beacon_state.current_epoch(); + let head_epoch = beacon_chain.head()?.beacon_state.current_epoch(); if RelativeEpoch::from_epoch(head_epoch, epoch).is_ok() { - Ok(beacon_chain.head().beacon_state) + Ok(beacon_chain.head()?.beacon_state) } else { let slot = if epoch > head_epoch { // Move to the first slot of the epoch prior to the request. @@ -308,7 +308,7 @@ pub fn publish_beacon_block( // - Excessive time between block produce and publish. // - A validator is using another beacon node to produce blocks and // submitting them here. - if beacon_chain.head().beacon_block_root != block_root { + if beacon_chain.head()?.beacon_block_root != block_root { warn!( log, "Block from validator is not head"; diff --git a/beacon_node/rest_api/tests/test.rs b/beacon_node/rest_api/tests/test.rs index 81f0c3bee4..987b8e3264 100644 --- a/beacon_node/rest_api/tests/test.rs +++ b/beacon_node/rest_api/tests/test.rs @@ -43,7 +43,12 @@ fn get_randao_reveal( slot: Slot, spec: &ChainSpec, ) -> Signature { - let fork = beacon_chain.head().beacon_state.fork.clone(); + let fork = beacon_chain + .head() + .expect("should get head") + .beacon_state + .fork + .clone(); let proposer_index = beacon_chain .block_proposer(slot) .expect("should get proposer index"); @@ -60,7 +65,12 @@ fn sign_block( block: &mut BeaconBlock, spec: &ChainSpec, ) { - let fork = beacon_chain.head().beacon_state.fork.clone(); + let fork = beacon_chain + .head() + .expect("should get head") + .beacon_state + .fork + .clone(); let proposer_index = beacon_chain .block_proposer(block.slot) .expect("should get proposer index"); @@ -81,7 +91,11 @@ fn validator_produce_attestation() { .client .beacon_chain() .expect("client should have beacon chain"); - let state = beacon_chain.head().beacon_state.clone(); + let state = beacon_chain + .head() + .expect("should get head") + .beacon_state + .clone(); let validator_index = 0; let duties = state @@ -182,6 +196,7 @@ fn validator_duties() { let validators = beacon_chain .head() + .expect("should get head") .beacon_state .validators .iter() @@ -534,6 +549,7 @@ fn genesis_time() { .beacon_chain() .expect("should have beacon chain") .head() + .expect("should get head") .beacon_state .genesis_time, genesis_time, @@ -558,6 +574,7 @@ fn fork() { .beacon_chain() .expect("should have beacon chain") .head() + .expect("should get head") .beacon_state .fork, fork, @@ -623,6 +640,7 @@ fn get_genesis_state_root() { .beacon_chain() .expect("should have beacon chain") .rev_iter_state_roots() + .expect("should get iter") .find(|(_cur_root, cur_slot)| slot == *cur_slot) .map(|(cur_root, _)| cur_root) .expect("chain should have state root at slot"); @@ -649,6 +667,7 @@ fn get_genesis_block_root() { .beacon_chain() .expect("should have beacon chain") .rev_iter_block_roots() + .expect("should get iter") .find(|(_cur_root, cur_slot)| slot == *cur_slot) .map(|(cur_root, _)| cur_root) .expect("chain should have state root at slot"); @@ -666,7 +685,7 @@ fn get_validators() { .client .beacon_chain() .expect("node should have beacon chain"); - let state = &chain.head().beacon_state; + let state = &chain.head().expect("should get head").beacon_state; let validators = state.validators.iter().take(2).collect::>(); let pubkeys = validators @@ -695,7 +714,7 @@ fn get_all_validators() { .client .beacon_chain() .expect("node should have beacon chain"); - let state = &chain.head().beacon_state; + let state = &chain.head().expect("should get head").beacon_state; let result = env .runtime() @@ -718,7 +737,7 @@ fn get_active_validators() { .client .beacon_chain() .expect("node should have beacon chain"); - let state = &chain.head().beacon_state; + let state = &chain.head().expect("should get head").beacon_state; let result = env .runtime() @@ -764,6 +783,7 @@ fn get_committees() { let expected = chain .head() + .expect("should get head") .beacon_state .get_beacon_committees_at_epoch(RelativeEpoch::Current) .expect("should get committees") diff --git a/beacon_node/src/cli.rs b/beacon_node/src/cli.rs index de0f7ff29e..bdd4a1b1a2 100644 --- a/beacon_node/src/cli.rs +++ b/beacon_node/src/cli.rs @@ -1,5 +1,4 @@ use clap::{App, Arg, SubCommand}; -use store::StoreConfig; pub fn cli_app<'a, 'b>() -> App<'a, 'b> { App::new("beacon_node") @@ -189,21 +188,15 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> { .value_name("HTTP-ENDPOINT") .help("Specifies the server for a web3 connection to the Eth1 chain.") .takes_value(true) - .default_value("https://goerli.public.sigp.io") + .default_value("http://127.0.0.1:8545") ) .arg( Arg::with_name("slots-per-restore-point") .long("slots-per-restore-point") .value_name("SLOT_COUNT") .help("Specifies how often a freezer DB restore point should be stored. \ - DO NOT CHANGE AFTER INITIALIZATION.") + DO NOT DECREASE AFTER INITIALIZATION. [default: 2048 (mainnet) or 64 (minimal)]") .takes_value(true) - .default_value( - Box::leak( - format!("{}", StoreConfig::default().slots_per_restore_point) - .into_boxed_str() - ) - ) ) /* * The "testnet" sub-command. diff --git a/beacon_node/src/config.rs b/beacon_node/src/config.rs index 6b700259fd..61d6f7db36 100644 --- a/beacon_node/src/config.rs +++ b/beacon_node/src/config.rs @@ -258,6 +258,11 @@ pub fn get_configs( client_config.store.slots_per_restore_point = slots_per_restore_point .parse() .map_err(|_| "slots-per-restore-point is not a valid integer".to_string())?; + } else { + client_config.store.slots_per_restore_point = std::cmp::min( + E::slots_per_historical_root() as u64, + store::config::DEFAULT_SLOTS_PER_RESTORE_POINT, + ); } if eth2_config.spec_constants != client_config.spec_constants { @@ -357,6 +362,13 @@ fn init_new_client( let spec = &mut eth2_config.spec; + // For now, assume that all networks will use the lighthouse genesis fork. + spec.genesis_fork = Fork { + previous_version: [0, 0, 0, 0], + current_version: [1, 3, 3, 7], + epoch: Epoch::new(0), + }; + client_config.eth1.deposit_contract_address = format!("{:?}", eth2_testnet_config.deposit_contract_address()?); client_config.eth1.deposit_contract_deploy_block = diff --git a/beacon_node/store/Cargo.toml b/beacon_node/store/Cargo.toml index bc4b684c0e..d36cd28f25 100644 --- a/beacon_node/store/Cargo.toml +++ b/beacon_node/store/Cargo.toml @@ -18,6 +18,7 @@ rayon = "1.2.0" db-key = "0.0.5" leveldb = "0.8.4" parking_lot = "0.9.0" +itertools = "0.8" eth2_ssz = "0.1.2" eth2_ssz_derive = "0.1.0" tree_hash = "0.1.0" diff --git a/beacon_node/store/examples/ssz_encode_state.rs b/beacon_node/store/examples/ssz_encode_state_container.rs similarity index 100% rename from beacon_node/store/examples/ssz_encode_state.rs rename to beacon_node/store/examples/ssz_encode_state_container.rs diff --git a/beacon_node/store/src/block_root_tree.rs b/beacon_node/store/src/block_root_tree.rs new file mode 100644 index 0000000000..76950069c9 --- /dev/null +++ b/beacon_node/store/src/block_root_tree.rs @@ -0,0 +1,364 @@ +use itertools::Itertools; +use parking_lot::RwLock; +use ssz_derive::{Decode, Encode}; +use std::collections::{HashMap, HashSet}; +use std::iter::{self, FromIterator}; +use types::{Hash256, Slot}; + +/// In-memory cache of all block roots post-finalization. Includes short-lived forks. +/// +/// Used by fork choice to avoid reconstructing hot states just for their block roots. +// NOTE: could possibly be streamlined by combining with the head tracker and/or fork choice +#[derive(Debug)] +pub struct BlockRootTree { + nodes: RwLock>, +} + +impl Clone for BlockRootTree { + fn clone(&self) -> Self { + Self { + nodes: RwLock::new(self.nodes.read().clone()), + } + } +} + +#[derive(Debug, PartialEq)] +pub enum BlockRootTreeError { + PrevUnknown(Hash256), +} + +/// Data for a single `block_root` in the tree. +#[derive(Debug, Clone, Encode, Decode)] +struct Node { + /// Hash of the preceding block (should be the parent block). + /// + /// A `previous` of `Hash256::zero` indicates the root of the tree. + previous: Hash256, + /// Slot of this node's block. + slot: Slot, +} + +impl BlockRootTree { + /// Create a new block root tree where `(root_hash, root_slot)` is considered finalized. + /// + /// All subsequent blocks added should descend from the root block. + pub fn new(root_hash: Hash256, root_slot: Slot) -> Self { + Self { + nodes: RwLock::new(HashMap::from_iter(iter::once(( + root_hash, + Node { + previous: Hash256::zero(), + slot: root_slot, + }, + )))), + } + } + + /// Check if `block_root` exists in the tree. + pub fn is_known_block_root(&self, block_root: &Hash256) -> bool { + self.nodes.read().contains_key(block_root) + } + + /// Add a new `block_root` to the tree. + /// + /// Will return an error if `prev_block_root` doesn't exist in the tree. + pub fn add_block_root( + &self, + block_root: Hash256, + prev_block_root: Hash256, + block_slot: Slot, + ) -> Result<(), BlockRootTreeError> { + let mut nodes = self.nodes.write(); + if nodes.contains_key(&prev_block_root) { + nodes.insert( + block_root, + Node { + previous: prev_block_root, + slot: block_slot, + }, + ); + Ok(()) + } else { + Err(BlockRootTreeError::PrevUnknown(prev_block_root)) + } + } + + /// Create a reverse iterator from `block_root` (inclusive). + /// + /// Will skip slots, see `every_slot_iter_from` for a non-skipping variant. + pub fn iter_from(&self, block_root: Hash256) -> BlockRootTreeIter { + BlockRootTreeIter { + tree: self, + current_block_root: block_root, + } + } + + /// Create a reverse iterator that yields a block root for every slot. + /// + /// E.g. if slot 6 is skipped, this iterator will return the block root from slot 5 at slot 6. + pub fn every_slot_iter_from<'a>( + &'a self, + block_root: Hash256, + ) -> impl Iterator + 'a { + let mut block_roots = self.iter_from(block_root).peekable(); + + // Include the value for the first `block_root` if any, then fill in the skipped slots + // between each pair of previous block roots by duplicating the older root. + block_roots + .peek() + .cloned() + .into_iter() + .chain(block_roots.tuple_windows().flat_map( + |((_, high_slot), (low_hash, low_slot))| { + (low_slot.as_u64()..high_slot.as_u64()) + .rev() + .map(move |slot| (low_hash, Slot::new(slot))) + }, + )) + } + + /// Prune the tree. + /// + /// Only keep block roots descended from `finalized_root`, which lie on a chain leading + /// to one of the heads contained in `heads`. + pub fn prune_to(&self, finalized_root: Hash256, heads: impl IntoIterator) { + let mut keep = HashSet::new(); + keep.insert(finalized_root); + + for head_block_root in heads.into_iter() { + // Iterate backwards until we reach a portion of the chain that we've already decided + // to keep. This also discards the pre-finalization block roots. + let mut keep_head = false; + + let head_blocks = self + .iter_from(head_block_root) + .map(|(block_root, _)| block_root) + .inspect(|block_root| { + if block_root == &finalized_root { + keep_head = true; + } + }) + .take_while(|block_root| !keep.contains(&block_root)) + .collect::>(); + + // If the head descends from the finalized root, keep it. Else throw it out. + if keep_head { + keep.extend(head_blocks); + } + } + + self.nodes + .write() + .retain(|block_root, _| keep.contains(block_root)); + } + + pub fn as_ssz_container(&self) -> SszBlockRootTree { + SszBlockRootTree { + nodes: Vec::from_iter(self.nodes.read().clone()), + } + } +} + +/// Simple (skipping) iterator for `BlockRootTree`. +#[derive(Debug)] +pub struct BlockRootTreeIter<'a> { + tree: &'a BlockRootTree, + current_block_root: Hash256, +} + +impl<'a> Iterator for BlockRootTreeIter<'a> { + type Item = (Hash256, Slot); + + fn next(&mut self) -> Option { + // Genesis + if self.current_block_root.is_zero() { + None + } else { + let block_root = self.current_block_root; + self.tree.nodes.read().get(&block_root).map(|node| { + self.current_block_root = node.previous; + (block_root, node.slot) + }) + } + } +} + +/// Serializable version of `BlockRootTree` that can be persisted to disk. +#[derive(Debug, Clone, Encode, Decode)] +pub struct SszBlockRootTree { + nodes: Vec<(Hash256, Node)>, +} + +impl Into for SszBlockRootTree { + fn into(self) -> BlockRootTree { + BlockRootTree { + nodes: RwLock::new(HashMap::from_iter(self.nodes)), + } + } +} + +#[cfg(test)] +mod test { + use super::*; + + fn int_hash(x: u64) -> Hash256 { + Hash256::from_low_u64_be(x) + } + + fn check_iter_from( + block_tree: &BlockRootTree, + start_block_root: Hash256, + expected: &[(Hash256, Slot)], + ) { + assert_eq!( + &block_tree.iter_from(start_block_root).collect::>()[..], + expected + ); + } + + fn check_every_slot_iter_from( + block_tree: &BlockRootTree, + start_block_root: Hash256, + expected: &[(Hash256, Slot)], + ) { + assert_eq!( + &block_tree + .every_slot_iter_from(start_block_root) + .collect::>()[..], + expected + ); + } + + #[test] + fn single_chain() { + let block_tree = BlockRootTree::new(int_hash(1), Slot::new(1)); + for i in 2..100 { + block_tree + .add_block_root(int_hash(i), int_hash(i - 1), Slot::new(i)) + .expect("add_block_root ok"); + + let expected = (1..i + 1) + .rev() + .map(|j| (int_hash(j), Slot::new(j))) + .collect::>(); + + check_iter_from(&block_tree, int_hash(i), &expected); + check_every_slot_iter_from(&block_tree, int_hash(i), &expected); + + // Still OK after pruning. + block_tree.prune_to(int_hash(1), vec![int_hash(i)]); + + check_iter_from(&block_tree, int_hash(i), &expected); + check_every_slot_iter_from(&block_tree, int_hash(i), &expected); + } + } + + #[test] + fn skips_of_2() { + let block_tree = BlockRootTree::new(int_hash(1), Slot::new(1)); + let step_length = 2u64; + for i in (1 + step_length..100).step_by(step_length as usize) { + block_tree + .add_block_root(int_hash(i), int_hash(i - step_length), Slot::new(i)) + .expect("add_block_root ok"); + + let sparse_expected = (1..i + 1) + .rev() + .step_by(step_length as usize) + .map(|j| (int_hash(j), Slot::new(j))) + .collect_vec(); + let every_slot_expected = (1..i + 1) + .rev() + .map(|j| { + let nearest = 1 + (j - 1) / step_length * step_length; + (int_hash(nearest), Slot::new(j)) + }) + .collect_vec(); + + check_iter_from(&block_tree, int_hash(i), &sparse_expected); + check_every_slot_iter_from(&block_tree, int_hash(i), &every_slot_expected); + + // Still OK after pruning. + block_tree.prune_to(int_hash(1), vec![int_hash(i)]); + + check_iter_from(&block_tree, int_hash(i), &sparse_expected); + check_every_slot_iter_from(&block_tree, int_hash(i), &every_slot_expected); + } + } + + #[test] + fn prune_small_fork() { + let tree = BlockRootTree::new(int_hash(1), Slot::new(1)); + // Space between fork hash values + let offset = 1000; + let num_blocks = 50; + + let fork1_start = 2; + let fork2_start = 2 + offset; + + tree.add_block_root(int_hash(fork1_start), int_hash(1), Slot::new(2)) + .expect("add first block of left fork"); + tree.add_block_root(int_hash(fork2_start), int_hash(1), Slot::new(2)) + .expect("add first block of right fork"); + + for i in 3..num_blocks { + tree.add_block_root(int_hash(i), int_hash(i - 1), Slot::new(i)) + .expect("add block to left fork"); + tree.add_block_root(int_hash(i + offset), int_hash(i + offset - 1), Slot::new(i)) + .expect("add block to right fork"); + } + + let root = (int_hash(1), Slot::new(1)); + + let (all_fork1_blocks, all_fork2_blocks): (Vec<_>, Vec<_>) = (2..num_blocks) + .rev() + .map(|i| { + ( + (int_hash(i), Slot::new(i)), + (int_hash(i + offset), Slot::new(i)), + ) + }) + .chain(iter::once((root, root))) + .unzip(); + + let fork1_head = int_hash(num_blocks - 1); + let fork2_head = int_hash(num_blocks + offset - 1); + + // Check that pruning with both heads preserves both chains. + let both_tree = tree.clone(); + both_tree.prune_to(root.0, vec![fork1_head, fork2_head]); + check_iter_from(&both_tree, fork1_head, &all_fork1_blocks); + check_iter_from(&both_tree, fork2_head, &all_fork2_blocks); + + // Check that pruning to either of the single chains leaves just that chain in the tree. + let fork1_tree = tree.clone(); + fork1_tree.prune_to(root.0, vec![fork1_head]); + check_iter_from(&fork1_tree, fork1_head, &all_fork1_blocks); + check_iter_from(&fork1_tree, fork2_head, &[]); + + let fork2_tree = tree.clone(); + fork2_tree.prune_to(root.0, vec![fork2_head]); + check_iter_from(&fork2_tree, fork1_head, &[]); + check_iter_from(&fork2_tree, fork2_head, &all_fork2_blocks); + + // Check that advancing the finalized root onto one side completely removes the other + // side. + let fin_tree = tree.clone(); + let prune_point = num_blocks / 2; + let remaining_fork1_blocks = all_fork1_blocks + .clone() + .into_iter() + .take_while(|(_, slot)| *slot >= prune_point) + .collect_vec(); + fin_tree.prune_to(int_hash(prune_point), vec![fork1_head, fork2_head]); + check_iter_from(&fin_tree, fork1_head, &remaining_fork1_blocks); + check_iter_from(&fin_tree, fork2_head, &[]); + } + + #[test] + fn iter_zero() { + let block_tree = BlockRootTree::new(int_hash(0), Slot::new(0)); + assert_eq!(block_tree.iter_from(int_hash(0)).count(), 0); + assert_eq!(block_tree.every_slot_iter_from(int_hash(0)).count(), 0); + } +} diff --git a/beacon_node/store/src/config.rs b/beacon_node/store/src/config.rs index 4693942eb9..36e2934a4a 100644 --- a/beacon_node/store/src/config.rs +++ b/beacon_node/store/src/config.rs @@ -5,6 +5,9 @@ use types::{EthSpec, MinimalEthSpec}; /// Default directory name for the freezer database under the top-level data dir. const DEFAULT_FREEZER_DB_DIR: &str = "freezer_db"; +/// Default value for the freezer DB's restore point frequency. +pub const DEFAULT_SLOTS_PER_RESTORE_POINT: u64 = 2048; + #[derive(Debug, Clone, Serialize, Deserialize)] pub struct StoreConfig { /// Name of the directory inside the data directory where the main "hot" DB is located. @@ -20,6 +23,7 @@ impl Default for StoreConfig { Self { db_name: "chain_db".to_string(), freezer_db_path: None, + // Safe default for tests, shouldn't ever be read by a CLI node. slots_per_restore_point: MinimalEthSpec::slots_per_historical_root() as u64, } } diff --git a/beacon_node/store/src/errors.rs b/beacon_node/store/src/errors.rs index 70cc327a78..8a03d00c3c 100644 --- a/beacon_node/store/src/errors.rs +++ b/beacon_node/store/src/errors.rs @@ -1,5 +1,5 @@ use crate::chunked_vector::ChunkError; -use crate::hot_cold_store::HotColdDbError; +use crate::hot_cold_store::HotColdDBError; use ssz::DecodeError; use types::BeaconStateError; @@ -9,7 +9,7 @@ pub enum Error { VectorChunkError(ChunkError), BeaconStateError(BeaconStateError), PartialBeaconStateError, - HotColdDbError(HotColdDbError), + HotColdDBError(HotColdDBError), DBError { message: String }, } @@ -25,9 +25,9 @@ impl From for Error { } } -impl From for Error { - fn from(e: HotColdDbError) -> Error { - Error::HotColdDbError(e) +impl From for Error { + fn from(e: HotColdDBError) -> Error { + Error::HotColdDBError(e) } } diff --git a/beacon_node/store/src/hot_cold_store.rs b/beacon_node/store/src/hot_cold_store.rs index a07810bb0f..c9acf76314 100644 --- a/beacon_node/store/src/hot_cold_store.rs +++ b/beacon_node/store/src/hot_cold_store.rs @@ -50,7 +50,10 @@ pub struct HotColdDB { } #[derive(Debug, PartialEq)] -pub enum HotColdDbError { +pub enum HotColdDBError { + /// Recoverable error indicating that the database freeze point couldn't be updated + /// due to the finalized block not lying on an epoch boundary (should be infrequent). + FreezeSlotUnaligned(Slot), FreezeSlotError { current_split_slot: Slot, proposed_split_slot: Slot, @@ -58,19 +61,19 @@ pub enum HotColdDbError { MissingStateToFreeze(Hash256), MissingRestorePointHash(u64), MissingRestorePoint(Hash256), - MissingStateSlot(Hash256), + MissingColdStateSummary(Hash256), + MissingHotStateSummary(Hash256), + MissingEpochBoundaryState(Hash256), MissingSplitState(Hash256, Slot), + HotStateSummaryError(BeaconStateError), RestorePointDecodeError(ssz::DecodeError), - RestorePointReplayFailure { - expected_state_root: Hash256, - observed_state_root: Hash256, - }, BlockReplayBeaconError(BeaconStateError), BlockReplaySlotError(SlotProcessingError), BlockReplayBlockError(BlockProcessingError), InvalidSlotsPerRestorePoint { slots_per_restore_point: u64, slots_per_historical_root: u64, + slots_per_epoch: u64, }, RestorePointBlockHashError(BeaconStateError), } @@ -98,9 +101,9 @@ impl Store for HotColdDB { /// Store a state in the store. fn put_state(&self, state_root: &Hash256, state: &BeaconState) -> Result<(), Error> { if state.slot < self.get_split_slot() { - self.store_archive_state(state_root, state) + self.store_cold_state(state_root, state) } else { - self.hot_db.put_state(state_root, state) + self.store_hot_state(state_root, state) } } @@ -112,20 +115,14 @@ impl Store for HotColdDB { ) -> Result>, Error> { if let Some(slot) = slot { if slot < self.get_split_slot() { - self.load_archive_state(state_root, slot).map(Some) + self.load_cold_state_by_slot(slot).map(Some) } else { - self.hot_db.get_state(state_root, None) + self.load_hot_state(state_root) } } else { - match self.hot_db.get_state(state_root, None)? { + match self.load_hot_state(state_root)? { Some(state) => Ok(Some(state)), - None => { - // Look-up the state in the freezer DB. We don't know the slot, so we must - // look it up separately and then use it to reconstruct the state from a - // restore point. - let slot = self.load_state_slot(state_root)?; - self.load_archive_state(state_root, slot).map(Some) - } + None => self.load_cold_state(state_root), } } } @@ -142,17 +139,24 @@ impl Store for HotColdDB { "slot" => frozen_head.slot ); - // 1. Copy all of the states between the head and the split slot, from the hot DB - // to the cold DB. + // 0. Check that the migration is sensible. + // The new frozen head must increase the current split slot, and lie on an epoch + // boundary (in order for the hot state summary scheme to work). let current_split_slot = store.get_split_slot(); if frozen_head.slot < current_split_slot { - Err(HotColdDbError::FreezeSlotError { + Err(HotColdDBError::FreezeSlotError { current_split_slot, proposed_split_slot: frozen_head.slot, })?; } + if frozen_head.slot % E::slots_per_epoch() != 0 { + Err(HotColdDBError::FreezeSlotUnaligned(frozen_head.slot))?; + } + + // 1. Copy all of the states between the head and the split slot, from the hot DB + // to the cold DB. let state_root_iter = StateRootsIterator::new(store.clone(), frozen_head); let mut to_delete = vec![]; @@ -163,16 +167,20 @@ impl Store for HotColdDB { let state: BeaconState = store .hot_db .get_state(&state_root, None)? - .ok_or_else(|| HotColdDbError::MissingStateToFreeze(state_root))?; + .ok_or_else(|| HotColdDBError::MissingStateToFreeze(state_root))?; - store.store_archive_state(&state_root, &state)?; + store.store_cold_state(&state_root, &state)?; } // Store a pointer from this state root to its slot, so we can later reconstruct states // from their state root alone. - store.store_state_slot(&state_root, slot)?; + store.store_cold_state_slot(&state_root, slot)?; - to_delete.push(state_root); + // Delete the old summary, and the full state if we lie on an epoch boundary. + to_delete.push((DBColumn::BeaconStateSummary, state_root)); + if slot % E::slots_per_epoch() == 0 { + to_delete.push((DBColumn::BeaconState, state_root)); + } } // 2. Update the split slot @@ -183,10 +191,10 @@ impl Store for HotColdDB { store.store_split()?; // 3. Delete from the hot DB - for state_root in to_delete { + for (column, state_root) in to_delete { store .hot_db - .key_delete(DBColumn::BeaconState.into(), state_root.as_bytes())?; + .key_delete(column.into(), state_root.as_bytes())?; } debug!( @@ -207,6 +215,38 @@ impl Store for HotColdDB { ) -> Self::ForwardsBlockRootsIterator { HybridForwardsBlockRootsIterator::new(store, start_slot, end_state, end_block_root, spec) } + + /// Load an epoch boundary state by using the hot state summary look-up. + /// + /// Will fall back to the cold DB if a hot state summary is not found. + fn load_epoch_boundary_state( + &self, + state_root: &Hash256, + ) -> Result>, Error> { + if let Some(HotStateSummary { + epoch_boundary_state_root, + .. + }) = self.load_hot_state_summary(state_root)? + { + let state = self + .hot_db + .get_state(&epoch_boundary_state_root, None)? + .ok_or_else(|| { + HotColdDBError::MissingEpochBoundaryState(epoch_boundary_state_root) + })?; + Ok(Some(state)) + } else { + // Try the cold DB + match self.load_cold_state_slot(state_root)? { + Some(state_slot) => { + let epoch_boundary_slot = + state_slot / E::slots_per_epoch() * E::slots_per_epoch(); + self.load_cold_state_by_slot(epoch_boundary_slot).map(Some) + } + None => Ok(None), + } + } + } } impl HotColdDB { @@ -240,10 +280,69 @@ impl HotColdDB { Ok(db) } + /// Store a post-finalization state efficiently in the hot database. + /// + /// On an epoch boundary, store a full state. On an intermediate slot, store + /// just a backpointer to the nearest epoch boundary. + pub fn store_hot_state( + &self, + state_root: &Hash256, + state: &BeaconState, + ) -> Result<(), Error> { + // On the epoch boundary, store the full state. + if state.slot % E::slots_per_epoch() == 0 { + trace!( + self.log, + "Storing full state on epoch boundary"; + "slot" => state.slot.as_u64(), + "state_root" => format!("{:?}", state_root) + ); + self.hot_db.put_state(state_root, state)?; + } + + // Store a summary of the state. + // We store one even for the epoch boundary states, as we may need their slots + // when doing a look up by state root. + self.store_hot_state_summary(state_root, state)?; + + Ok(()) + } + + /// Load a post-finalization state from the hot database. + /// + /// Will replay blocks from the nearest epoch boundary. + pub fn load_hot_state(&self, state_root: &Hash256) -> Result>, Error> { + if let Some(HotStateSummary { + slot, + latest_block_root, + epoch_boundary_state_root, + }) = self.load_hot_state_summary(state_root)? + { + let state: BeaconState = self + .hot_db + .get_state(&epoch_boundary_state_root, None)? + .ok_or_else(|| { + HotColdDBError::MissingEpochBoundaryState(epoch_boundary_state_root) + })?; + + // Optimization to avoid even *thinking* about replaying blocks if we're already + // on an epoch boundary. + if slot % E::slots_per_epoch() == 0 { + Ok(Some(state)) + } else { + let blocks = self.load_blocks_to_replay(state.slot, slot, latest_block_root)?; + self.replay_blocks(state, blocks, slot).map(Some) + } + } else { + Ok(None) + } + } + /// Store a pre-finalization state in the freezer database. /// - /// Will return an error if the state does not lie on a restore point boundary. - pub fn store_archive_state( + /// Will log a warning and not store anything if the state does not lie on a restore point + /// boundary. + pub fn store_cold_state( &self, state_root: &Hash256, state: &BeaconState, @@ -283,25 +382,32 @@ impl HotColdDB { Ok(()) } + /// Try to load a pre-finalization state from the freezer database. + /// + /// Return `None` if no state with `state_root` lies in the freezer. + pub fn load_cold_state(&self, state_root: &Hash256) -> Result>, Error> { + match self.load_cold_state_slot(state_root)? { + Some(slot) => self.load_cold_state_by_slot(slot).map(Some), + None => Ok(None), + } + } + /// Load a pre-finalization state from the freezer database. /// /// Will reconstruct the state if it lies between restore points. - pub fn load_archive_state( - &self, - state_root: &Hash256, - slot: Slot, - ) -> Result, Error> { + pub fn load_cold_state_by_slot(&self, slot: Slot) -> Result, Error> { if slot % self.slots_per_restore_point == 0 { - self.load_restore_point(state_root) + let restore_point_idx = slot.as_u64() / self.slots_per_restore_point; + self.load_restore_point_by_index(restore_point_idx) } else { - self.load_intermediate_state(state_root, slot) + self.load_cold_intermediate_state(slot) } } /// Load a restore point state by its `state_root`. fn load_restore_point(&self, state_root: &Hash256) -> Result, Error> { let mut partial_state = PartialBeaconState::db_get(&self.cold_db, state_root)? - .ok_or_else(|| HotColdDbError::MissingRestorePoint(*state_root))?; + .ok_or_else(|| HotColdDBError::MissingRestorePoint(*state_root))?; // Fill in the fields of the partial state. partial_state.load_block_roots(&self.cold_db, &self.spec)?; @@ -321,12 +427,8 @@ impl HotColdDB { self.load_restore_point(&state_root) } - /// Load a state that lies between restore points. - fn load_intermediate_state( - &self, - state_root: &Hash256, - slot: Slot, - ) -> Result, Error> { + /// Load a frozen state that lies between restore points. + fn load_cold_intermediate_state(&self, slot: Slot) -> Result, Error> { // 1. Load the restore points either side of the intermediate state. let low_restore_point_idx = slot.as_u64() / self.slots_per_restore_point; let high_restore_point_idx = low_restore_point_idx + 1; @@ -341,7 +443,7 @@ impl HotColdDB { >= split.slot.as_u64() { self.get_state(&split.state_root, Some(split.slot))? - .ok_or_else(|| HotColdDbError::MissingSplitState(split.state_root, split.slot))? + .ok_or_else(|| HotColdDBError::MissingSplitState(split.state_root, split.slot))? } else { self.load_restore_point_by_index(high_restore_point_idx)? }; @@ -354,22 +456,7 @@ impl HotColdDB { )?; // 3. Replay the blocks on top of the low restore point. - let mut state = self.replay_blocks(low_restore_point, blocks, slot)?; - - // 4. Check that the state root is correct (should be quick with the cache already built). - // TODO: we could optimise out *all* the tree hashing when replaying blocks, - // in which case we could also drop this check. - let observed_state_root = state.update_tree_hash_cache()?; - - if observed_state_root == *state_root { - Ok(state) - } else { - Err(HotColdDbError::RestorePointReplayFailure { - expected_state_root: *state_root, - observed_state_root, - } - .into()) - } + self.replay_blocks(low_restore_point, blocks, slot) } /// Get a suitable block root for backtracking from `high_restore_point` to the state at `slot`. @@ -379,12 +466,12 @@ impl HotColdDB { &self, high_restore_point: &BeaconState, slot: Slot, - ) -> Result { + ) -> Result { high_restore_point .get_block_root(slot) .or_else(|_| high_restore_point.get_oldest_block_root()) .map(|x| *x) - .map_err(HotColdDbError::RestorePointBlockHashError) + .map_err(HotColdDBError::RestorePointBlockHashError) } /// Load the blocks between `start_slot` and `end_slot` by backtracking from `end_block_hash`. @@ -398,6 +485,7 @@ impl HotColdDB { end_block_hash: Hash256, ) -> Result>, Error> { let mut blocks = ParentRootBlockIterator::new(self, end_block_hash) + .map(|(_, block)| block) // Include the block at the end slot (if any), it needs to be // replayed in order to construct the canonical state at `end_slot`. .filter(|block| block.slot <= end_slot) @@ -411,21 +499,32 @@ impl HotColdDB { /// Replay `blocks` on top of `state` until `target_slot` is reached. /// - /// Will skip slots as necessary. + /// Will skip slots as necessary. The returned state is not guaranteed + /// to have any caches built, beyond those immediately required by block processing. fn replay_blocks( &self, mut state: BeaconState, blocks: Vec>, target_slot: Slot, ) -> Result, Error> { - state - .build_all_caches(&self.spec) - .map_err(HotColdDbError::BlockReplayBeaconError)?; + let state_root_from_prev_block = |i: usize, state: &BeaconState| { + if i > 0 { + let prev_block = &blocks[i - 1]; + if prev_block.slot == state.slot { + Some(prev_block.state_root) + } else { + None + } + } else { + None + } + }; - for block in blocks { + for (i, block) in blocks.iter().enumerate() { while state.slot < block.slot { - per_slot_processing(&mut state, None, &self.spec) - .map_err(HotColdDbError::BlockReplaySlotError)?; + let state_root = state_root_from_prev_block(i, &state); + per_slot_processing(&mut state, state_root, &self.spec) + .map_err(HotColdDBError::BlockReplaySlotError)?; } per_block_processing( &mut state, @@ -434,12 +533,13 @@ impl HotColdDB { BlockSignatureStrategy::NoVerification, &self.spec, ) - .map_err(HotColdDbError::BlockReplayBlockError)?; + .map_err(HotColdDBError::BlockReplayBlockError)?; } while state.slot < target_slot { - per_slot_processing(&mut state, None, &self.spec) - .map_err(HotColdDbError::BlockReplaySlotError)?; + let state_root = state_root_from_prev_block(blocks.len(), &state); + per_slot_processing(&mut state, state_root, &self.spec) + .map_err(HotColdDBError::BlockReplaySlotError)?; } Ok(state) @@ -452,7 +552,7 @@ impl HotColdDB { /// Fetch the slot of the most recently stored restore point. pub fn get_latest_restore_point_slot(&self) -> Slot { - self.get_split_slot() / self.slots_per_restore_point * self.slots_per_restore_point + (self.get_split_slot() - 1) / self.slots_per_restore_point * self.slots_per_restore_point } /// Load the split point from disk. @@ -474,7 +574,7 @@ impl HotColdDB { let key = Self::restore_point_key(restore_point_index); RestorePointHash::db_get(&self.cold_db, &key)? .map(|r| r.state_root) - .ok_or(HotColdDbError::MissingRestorePointHash(restore_point_index).into()) + .ok_or(HotColdDBError::MissingRestorePointHash(restore_point_index).into()) } /// Store the state root of a restore point. @@ -495,39 +595,85 @@ impl HotColdDB { } /// Load a frozen state's slot, given its root. - fn load_state_slot(&self, state_root: &Hash256) -> Result { - StateSlot::db_get(&self.cold_db, state_root)? - .map(|s| s.slot) - .ok_or_else(|| HotColdDbError::MissingStateSlot(*state_root).into()) + fn load_cold_state_slot(&self, state_root: &Hash256) -> Result, Error> { + Ok(ColdStateSummary::db_get(&self.cold_db, state_root)?.map(|s| s.slot)) } /// Store the slot of a frozen state. - fn store_state_slot(&self, state_root: &Hash256, slot: Slot) -> Result<(), Error> { - StateSlot { slot } + fn store_cold_state_slot(&self, state_root: &Hash256, slot: Slot) -> Result<(), Error> { + ColdStateSummary { slot } .db_put(&self.cold_db, state_root) .map_err(Into::into) } - /// Check that the restore point frequency is a divisor of the slots per historical root. + /// Load a hot state's summary, given its root. + pub fn load_hot_state_summary( + &self, + state_root: &Hash256, + ) -> Result, Error> { + HotStateSummary::db_get(&self.hot_db, state_root) + } + + /// Store a summary of a hot database state. + fn store_hot_state_summary( + &self, + state_root: &Hash256, + state: &BeaconState, + ) -> Result<(), Error> { + // Fill in the state root on the latest block header if necessary (this happens on all + // slots where there isn't a skip). + let latest_block_root = state.get_latest_block_root(*state_root); + let epoch_boundary_slot = state.slot / E::slots_per_epoch() * E::slots_per_epoch(); + let epoch_boundary_state_root = if epoch_boundary_slot == state.slot { + *state_root + } else { + *state + .get_state_root(epoch_boundary_slot) + .map_err(HotColdDBError::HotStateSummaryError)? + }; + + HotStateSummary { + slot: state.slot, + latest_block_root, + epoch_boundary_state_root, + } + .db_put(&self.hot_db, state_root) + .map_err(Into::into) + } + + /// Check that the restore point frequency is valid. /// - /// This ensures that we have at least one restore point within range of our state + /// Specifically, check that it is: + /// (1) A divisor of the number of slots per historical root, and + /// (2) Divisible by the number of slots per epoch + /// + /// + /// (1) ensures that we have at least one restore point within range of our state /// root history when iterating backwards (and allows for more frequent restore points if /// desired). - fn verify_slots_per_restore_point(slots_per_restore_point: u64) -> Result<(), HotColdDbError> { + /// + /// (2) ensures that restore points align with hot state summaries, making it + /// quick to migrate hot to cold. + fn verify_slots_per_restore_point(slots_per_restore_point: u64) -> Result<(), HotColdDBError> { let slots_per_historical_root = E::SlotsPerHistoricalRoot::to_u64(); - if slots_per_restore_point > 0 && slots_per_historical_root % slots_per_restore_point == 0 { + let slots_per_epoch = E::slots_per_epoch(); + if slots_per_restore_point > 0 + && slots_per_historical_root % slots_per_restore_point == 0 + && slots_per_restore_point % slots_per_epoch == 0 + { Ok(()) } else { - Err(HotColdDbError::InvalidSlotsPerRestorePoint { + Err(HotColdDBError::InvalidSlotsPerRestorePoint { slots_per_restore_point, slots_per_historical_root, + slots_per_epoch, }) } } } /// Struct for storing the split slot and state root in the database. -#[derive(Clone, Copy, Default, Encode, Decode)] +#[derive(Debug, Clone, Copy, Default, Encode, Decode)] struct Split { slot: Slot, state_root: Hash256, @@ -547,15 +693,39 @@ impl SimpleStoreItem for Split { } } -/// Struct for storing the slot of a state root in the database. -#[derive(Clone, Copy, Default, Encode, Decode)] -struct StateSlot { +/// Struct for summarising a state in the hot database. +/// +/// Allows full reconstruction by replaying blocks. +#[derive(Debug, Clone, Copy, Default, Encode, Decode)] +pub struct HotStateSummary { + slot: Slot, + latest_block_root: Hash256, + epoch_boundary_state_root: Hash256, +} + +impl SimpleStoreItem for HotStateSummary { + fn db_column() -> DBColumn { + DBColumn::BeaconStateSummary + } + + fn as_store_bytes(&self) -> Vec { + self.as_ssz_bytes() + } + + fn from_store_bytes(bytes: &[u8]) -> Result { + Ok(Self::from_ssz_bytes(bytes)?) + } +} + +/// Struct for summarising a state in the freezer database. +#[derive(Debug, Clone, Copy, Default, Encode, Decode)] +struct ColdStateSummary { slot: Slot, } -impl SimpleStoreItem for StateSlot { +impl SimpleStoreItem for ColdStateSummary { fn db_column() -> DBColumn { - DBColumn::BeaconStateSlot + DBColumn::BeaconStateSummary } fn as_store_bytes(&self) -> Vec { @@ -568,7 +738,7 @@ impl SimpleStoreItem for StateSlot { } /// Struct for storing the state root of a restore point in the database. -#[derive(Clone, Copy, Default, Encode, Decode)] +#[derive(Debug, Clone, Copy, Default, Encode, Decode)] struct RestorePointHash { state_root: Hash256, } diff --git a/beacon_node/store/src/iter.rs b/beacon_node/store/src/iter.rs index e1e6386570..07078aceea 100644 --- a/beacon_node/store/src/iter.rs +++ b/beacon_node/store/src/iter.rs @@ -120,7 +120,7 @@ impl<'a, E: EthSpec, S: Store> ParentRootBlockIterator<'a, E, S> { } impl<'a, E: EthSpec, S: Store> Iterator for ParentRootBlockIterator<'a, E, S> { - type Item = BeaconBlock; + type Item = (Hash256, BeaconBlock); fn next(&mut self) -> Option { // Stop once we reach the zero parent, otherwise we'll keep returning the genesis @@ -128,9 +128,10 @@ impl<'a, E: EthSpec, S: Store> Iterator for ParentRootBlockIterator<'a, E, S> if self.next_block_root.is_zero() { None } else { - let block: BeaconBlock = self.store.get(&self.next_block_root).ok()??; + let block_root = self.next_block_root; + let block: BeaconBlock = self.store.get(&block_root).ok()??; self.next_block_root = block.parent_root; - Some(block) + Some((block_root, block)) } } } diff --git a/beacon_node/store/src/lib.rs b/beacon_node/store/src/lib.rs index 29a38fe8dd..b15477e0ef 100644 --- a/beacon_node/store/src/lib.rs +++ b/beacon_node/store/src/lib.rs @@ -11,6 +11,7 @@ extern crate lazy_static; mod block_at_slot; +pub mod block_root_tree; pub mod chunked_iter; pub mod chunked_vector; pub mod config; @@ -28,6 +29,7 @@ pub mod migrate; use std::sync::Arc; +pub use self::block_root_tree::{BlockRootTree, SszBlockRootTree}; pub use self::config::StoreConfig; pub use self::hot_cold_store::HotColdDB as DiskStore; pub use self::leveldb_store::LevelDB as SimpleDiskStore; @@ -128,6 +130,29 @@ pub trait Store: Sync + Send + Sized + 'static { end_block_root: Hash256, spec: &ChainSpec, ) -> Self::ForwardsBlockRootsIterator; + + /// Load the most recent ancestor state of `state_root` which lies on an epoch boundary. + /// + /// If `state_root` corresponds to an epoch boundary state, then that state itself should be + /// returned. + fn load_epoch_boundary_state( + &self, + state_root: &Hash256, + ) -> Result>, Error> { + // The default implementation is not very efficient, but isn't used in prod. + // See `HotColdDB` for the optimized implementation. + if let Some(state) = self.get_state(state_root, None)? { + let epoch_boundary_slot = state.slot / E::slots_per_epoch() * E::slots_per_epoch(); + if state.slot == epoch_boundary_slot { + Ok(Some(state)) + } else { + let epoch_boundary_state_root = state.get_state_root(epoch_boundary_slot)?; + self.get_state(epoch_boundary_state_root, Some(epoch_boundary_slot)) + } + } else { + Ok(None) + } + } } /// A unique column identifier. @@ -140,8 +165,8 @@ pub enum DBColumn { BeaconChain, /// For the table mapping restore point numbers to state roots. BeaconRestorePoint, - /// For the mapping from state roots to their slots. - BeaconStateSlot, + /// For the mapping from state roots to their slots or summaries. + BeaconStateSummary, BeaconBlockRoots, BeaconStateRoots, BeaconHistoricalRoots, @@ -157,7 +182,7 @@ impl Into<&'static str> for DBColumn { DBColumn::BeaconState => "ste", DBColumn::BeaconChain => "bch", DBColumn::BeaconRestorePoint => "brp", - DBColumn::BeaconStateSlot => "bss", + DBColumn::BeaconStateSummary => "bss", DBColumn::BeaconBlockRoots => "bbr", DBColumn::BeaconStateRoots => "bsr", DBColumn::BeaconHistoricalRoots => "bhr", diff --git a/beacon_node/store/src/migrate.rs b/beacon_node/store/src/migrate.rs index 7aa54f6205..2d6cd604b2 100644 --- a/beacon_node/store/src/migrate.rs +++ b/beacon_node/store/src/migrate.rs @@ -1,6 +1,8 @@ -use crate::{DiskStore, MemoryStore, SimpleDiskStore, Store}; +use crate::{ + hot_cold_store::HotColdDBError, DiskStore, Error, MemoryStore, SimpleDiskStore, Store, +}; use parking_lot::Mutex; -use slog::warn; +use slog::{info, warn}; use std::mem; use std::sync::mpsc; use std::sync::Arc; @@ -127,12 +129,22 @@ impl BackgroundMigrator { let (tx, rx) = mpsc::channel(); let thread = thread::spawn(move || { while let Ok((state_root, state)) = rx.recv() { - if let Err(e) = DiskStore::freeze_to_state(db.clone(), state_root, &state) { - warn!( - db.log, - "Database migration failed"; - "error" => format!("{:?}", e) - ); + match DiskStore::freeze_to_state(db.clone(), state_root, &state) { + Ok(()) => {} + Err(Error::HotColdDBError(HotColdDBError::FreezeSlotUnaligned(slot))) => { + info!( + db.log, + "Database migration postponed, unaligned finalized block"; + "slot" => slot.as_u64() + ); + } + Err(e) => { + warn!( + db.log, + "Database migration failed"; + "error" => format!("{:?}", e) + ); + } } } }); diff --git a/book/src/SUMMARY.md b/book/src/SUMMARY.md index 096a572709..8253cd0630 100644 --- a/book/src/SUMMARY.md +++ b/book/src/SUMMARY.md @@ -2,6 +2,8 @@ * [Introduction](./intro.md) * [Become a Validator](./become-a-validator.md) + * [Using Docker](./become-a-validator-docker.md) + * [Building from Source](./become-a-validator-source.md) * [Installation](./installation.md) * [Docker](./docker.md) * [CLI](./cli.md) diff --git a/book/src/become-a-validator-docker.md b/book/src/become-a-validator-docker.md new file mode 100644 index 0000000000..7fb03845da --- /dev/null +++ b/book/src/become-a-validator-docker.md @@ -0,0 +1,76 @@ +# Become a Validator: Using Docker + +Sigma Prime maintains the +[sigp/lighthouse-docker](https://github.com/sigp/lighthouse-docker) repository +which provides an easy way to run Lighthouse without building the Lighthouse +binary yourself. + +> Note: when you're running the Docker Hub image you're relying upon a +> pre-built binary instead of building from source. If you want the highest +> assurance you're running the _real_ Lighthouse, +> [build the docker image yourself](./docker.md) instead. You'll need some +> experience with docker-compose to integrate your locally built docker image +> with the docker-compose environment. + +### 1. Clone the repository + +Once you have docker-compose +[installed](https://docs.docker.com/compose/install/), clone the +[sigp/lighthouse-docker](https://github.com/sigp/lighthouse-docker) repository. + +```bash +$ git clone https://github.com/sigp/lighthouse-docker +$ cd lighthouse-docker +``` + +### 2. Configure the docker environment + +Then, create a file named `.env` with the following contents (these values are +documented +[here](https://github.com/sigp/lighthouse-docker/blob/master/default.env)): + +```bash +DEBUG_LEVEL=info +START_GETH=true +START_VALIDATOR=true +VALIDATOR_COUNT=1 +VOTING_ETH1_NODE=http://geth:8545 +DEPOSIT_VALUE=3200000000 +``` + +_This `.env` file should live in the `lighthouse-docker` directory alongside the +`docker-compose.yml` file_. + +### 3. Start Lighthouse + +Start the docker-compose environment (you may need to use `sudo`): + +```bash +$ docker-compose up +``` + +Watch the output of this command for the `Saved new validator to disk` log, as +the `voting_pubkey` is the primary identifier for your new validator. This is +useful for finding your validator in block explorers. Here's an example of the +log: + +```bash +validator_client_1 | Jan 10 12:06:05.632 INFO Saved new validator to disk voting_pubkey: 0x8fc28504448783b10b0a7f5a321505b07ad2ad8d6a8430b8868a0fcdedee43766bee725855506626085776e020dfa472 +``` + +> Note: the docker-compose setup includes a fast-synced geth node. You can +> expect the `beacon_node` to log some eth1-related errors whilst the geth node +> boots and becomes synced. This will only happen on the first start of the +> compose environment or if geth loses sync. + +### Installation complete! + +In the next step you'll need to locate your `eth1_deposit_data.rlp` file from +your `.lighthouse/validators` directory. + +The `./lighthouse` directory is in the root of the `lighthouse-docker` +repository. For example, if you ran Step 1 in `/home/karlm/` then you can find +your validator directory in +`/home/karlm/lighthouse-docker/.lighthouse/validators/`. + +You can now go to [Become a Validator: Step 2](become-a-validator.html#2-submit-your-deposit-to-goerli). diff --git a/book/src/become-a-validator-source.md b/book/src/become-a-validator-source.md new file mode 100644 index 0000000000..d0555f0f34 --- /dev/null +++ b/book/src/become-a-validator-source.md @@ -0,0 +1,135 @@ +# Become an Validator: Building from Source + +## 1. Download and install Lighthouse + +If you already have Rust installed, you can install Lighthouse with the +following three commands: + +- `$ git clone https://github.com/sigp/lighthouse.git` +- `$ cd lighthouse` +- `$ make` + +You've completed this step when you can run `$ lighthouse --help` and see the +help menu. + +> - If you're not familiar with Rust or you'd like more detailed instructions, +> see the [Installation Guide](./installation.md) which contains a +> [Troubleshooting](installation.html#troubleshooting) section. + +## 2. Start an Eth1 client + +As Eth2 relies upon the Eth1 chain for validator on-boarding and eventually +Eth1 may use the Eth2 chain as a finality gadget, all Eth2 validators must have +a connection to an Eth1 node. + +We provide instructions for using Geth (this is, by chance, what we ended up +testing with), but you could use any client that implements the JSON RPC via +HTTP. At least for Geth, a fast-synced node is sufficient. + +### Starting Geth + +[Install geth](https://github.com/ethereum/go-ethereum/wiki/Installing-Geth) +and then use this command (or equivalent) to start your Eth1 node: + +```bash +$ geth --goerli --rpc +``` + +## 3. Start your Beacon Node + +The beacon node is the core component of Eth2, it connects to other peers over +the Internet and maintains a view of the chain. + +Start your beacon node with: + +```bash +$ lighthouse beacon --eth1 --http +``` + +Your beacon node has started syncing when you see the following (truncated) +log: + +``` +Dec 09 12:57:18.026 INFO Syncing est_time: 2 hrs ... +``` + +The `distance` value reports the time since eth2 genesis, whilst the `est_time` +reports an estimate of how long it will take your node to become synced. + +It has finished syncing once you see the following (truncated) log: + +``` +Dec 09 12:27:06.010 INFO Synced slot: 16835, ... +``` + +> - The `--http` flag enables the HTTP API for the validator client. +> - The `--eth1` flag tells the beacon node that it should sync with an Ethereum +> 1 node (e.g., Geth). This is only required if you wish to run a validator. + +## 4. Generate your validator key + +Generate new validator BLS keypairs using: + +```shell +$ lighthouse account validator new random +``` + +Take note of the `voting_pubkey` of the new validator. This will be the primary +identifier of the validator. This is how you can find your validator in block +explorers. + +You've completed this step when you see the equivalent line: + +``` +Dec 02 21:42:01.337 INFO Generated validator directories count: 1, base_path: "/home/karl/.lighthouse/validators" +``` + +> - This will generate a new _validator directory_ in the `.lighthouse/validators` +> directory. Your validator directory will be identified by it's public key, +> which looks something like `0xc483de...`. You'll need to find this directory +> for the next step. +> - These keys are good enough for the Lighthouse testnet, however they shouldn't +> be considered secure until we've undergone a security audit (planned Jan +> 2020). + +## 5. Start your validator client + +For security reasons, the validator client runs separately to the beacon node. +The validator client stores private keys and signs messages generated by the +beacon node. + +You'll need both your beacon node _and_ validator client running if you want to +stake. + +Start the validator client with: + +```bash +$ lighthouse validator +``` + +The validator client is running and has found your validator keys from step 3 +when you see the following log: + +``` +Dec 09 13:08:59.171 INFO Loaded validator keypair store voting_validators: 1 +Dec 09 13:09:09.000 INFO Awaiting activation slot: 17787, ... +``` + +If your beacon node hasn't finished syncing yet, you'll see some `ERRO` +messages indicating that your node isn't synced yet. It is safest to wait for +your node to sync before moving onto the next step, otherwise your validator +may activate before you're able to produce blocks and attestations. However, it +generally takes 4-8+ hours after deposit for a validator to become active. If +your `est_time` is less than 4 hours, you _should_ be fine to just move to the +next step. After all, this is a testnet and you're only risking Goerli ETH. + +## Installation complete! + +In the next step you'll need to locate your `eth1_deposit_data.rlp` file from +your `.lighthouse/validators` directory. + +The `./lighthouse` directory is in your `$HOME` directory. For example, if +you're in Linux and your user is `karlm`, you can find your validator directory +in `/home/karlm/.lighthouse/validators/`. + +You can now go to [Become a Validator: Step 2](become-a-validator.html#2-submit-your-deposit-to-goerli). diff --git a/book/src/become-a-validator.md b/book/src/become-a-validator.md index 7b67632e23..a3d6e14cb4 100644 --- a/book/src/become-a-validator.md +++ b/book/src/become-a-validator.md @@ -1,135 +1,33 @@ # Become an Ethereum 2.0 Validator* ---- - -**The lighthouse testnet is currently down, we expect to raise a new one -before the 22nd of December. See [Lighthouse Update #20](https://lighthouse.sigmaprime.io/update-20.html) -for more information.** - ---- - _* Testnet validator_ Running Lighthouse validator is easy if you're familiar with the terminal. It -runs on Linux, MacOS and Windows. +runs on Linux, MacOS and Windows and we have a Docker work-flow. Before you start, you'll need [Metamask](https://metamask.io/) and 3.2 gETH (Goerli ETH). We recommend the [mudit.blog faucet](https://faucet.goerli.mudit.blog/) for those familiar with Goerli, or [goerli.net](https://goerli.net/) for an overview of the testnet. -### 1. Download and install Lighthouse +## 1. Install and start Lighthouse -If you already have Rust installed, you can install Lighthouse with the -following three commands: +There are two, different ways to install and start a Lighthouse validator: -- `$ git clone https://github.com/sigp/lighthouse.git` -- `$ cd lighthouse` -- `$ make` +- [Using `docker-compose`](./become-a-validator-docker.md): this is the easiest method. +- [Building from source](./become-a-validator-source.md): this is a little more involved, however it + gives a more hands-on experience. -You've completed this step when you can run `$ lighthouse --help` and see the -help menu. +Once you have completed **only one** of these steps, move onto the next step. -> - If you're not familiar with Rust or you'd like more detailed instructions, see -> the [Installation Guide](./installation.md). -> - The [Docker Guide](./docker.md) is great if you have Docker installed and would -> like to avoid installing Rust. - -### 2. Start your Beacon Node - -The beacon node is the core component of Eth2, it connects to other peers over -the Internet and maintains a view of the chain. - -Start your beacon node with: - -```bash -$ lighthouse beacon --eth1 --http -``` - -Your beacon node has started syncing when you see the following (truncated) -log: - -``` -Dec 09 12:57:18.026 INFO Syncing distance: 16837 slots (2 days 8 hrs), ... -``` - -Don't be overly concerned about the "distance" because "est_time" for syncing will be much lower. - -It has finished syncing once you see the following (truncated) log: - -``` -Dec 09 12:27:06.010 INFO Synced slot: 16835, ... -``` - -> - The `--http` flag enables the HTTP API for the validator client. -> - The `--eth1` flag tells the beacon node that it should sync with an Ethereum -> 1 node (e.g., Geth). This is only required if you wish to run a validator. -> - We are hosting a public Goerli archive node and have set this as the -> default, but you can specify your own Eth1 node using the `--eth1-endpoint` -> flag. Presently we require the node to be a full archive node, but we're -> working to [fix](https://github.com/sigp/lighthouse/issues/637) this. - -### 3. Generate your validator key - -Generate new validator BLS keypairs using: - -```shell -$ lighthouse account validator new random -``` - - -You've completed this step when you see the equivalent line: - -``` -Dec 02 21:42:01.337 INFO Generated validator directories count: 1, base_path: "/home/karl/.lighthouse/validators" -``` - -> - This will generate a new _validator directory_ in the `.lighthouse/validators` -> directory. Your validator directory will be identified by it's public key, -> which looks something like `0xc483de...`. You'll need to find this directory -> for the next step. -> - These keys are good enough for the Lighthouse testnet, however they shouldn't -> be considered secure until we've undergone a security audit (planned Jan -> 2020). - -### 4. Start your validator client - -For security reasons, the validator client runs separately to the beacon node. -The validator client stores private keys and signs messages generated by the -beacon node. - -You'll need both your beacon node _and_ validator client running if you want to -stake. - -Start the validator client with: - -```bash -$ lighthouse validator -``` - -The validator client is running and has found your validator keys from step 3 -when you see the following log: - -``` -Dec 09 13:08:59.171 INFO Loaded validator keypair store voting_validators: 1 -Dec 09 13:09:09.000 INFO Awaiting activation slot: 17787, ... -``` - -If your beacon node hasn't finished syncing yet, you'll see some `ERRO` -messages indicating that your node isn't synced yet. It is safest to wait for -your node to sync before moving onto the next step, otherwise your validator -may activate before you're able to produce blocks and attestations. However, it -generally takes 4-8+ hours after deposit for a validator to become active. If -your `est_time` is less than 4 hours, you _should_ be fine to just move to the -next step. After all, this is a testnet and you're only risking Goerli ETH. - -### 5. Submit your deposit +## 2. Submit your deposit to Goerli