mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-08 03:01:41 +00:00
Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
371e1c1d5d | ||
|
|
a17f74896a | ||
|
|
49ab414594 | ||
|
|
2074beccdc | ||
|
|
e5fc6bab48 | ||
|
|
c9596fcf0e | ||
|
|
c6abc56113 | ||
|
|
7f1b936905 | ||
|
|
810de2f8b7 | ||
|
|
0525876882 | ||
|
|
d79366c503 | ||
|
|
b19cf02d2d | ||
|
|
dfe507715d |
191
Cargo.lock
generated
191
Cargo.lock
generated
@@ -2,7 +2,7 @@
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "account_manager"
|
||||
version = "0.2.9"
|
||||
version = "0.2.10"
|
||||
dependencies = [
|
||||
"account_utils",
|
||||
"bls",
|
||||
@@ -370,7 +370,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "beacon_node"
|
||||
version = "0.2.9"
|
||||
version = "0.2.10"
|
||||
dependencies = [
|
||||
"beacon_chain",
|
||||
"clap",
|
||||
@@ -534,7 +534,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "boot_node"
|
||||
version = "0.2.9"
|
||||
version = "0.2.10"
|
||||
dependencies = [
|
||||
"beacon_node",
|
||||
"clap",
|
||||
@@ -623,6 +623,27 @@ version = "0.5.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38"
|
||||
|
||||
[[package]]
|
||||
name = "bzip2"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42b7c3cbf0fa9c1b82308d57191728ca0256cb821220f4e2fd410a72ade26e3b"
|
||||
dependencies = [
|
||||
"bzip2-sys",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bzip2-sys"
|
||||
version = "0.1.9+1.0.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ad3b39a260062fca31f7b0b12f207e8f2590a67d32ec7d59c20484b07ea7285e"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"pkg-config",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "c_linked_list"
|
||||
version = "1.1.1"
|
||||
@@ -756,7 +777,7 @@ dependencies = [
|
||||
"sloggers",
|
||||
"slot_clock",
|
||||
"store",
|
||||
"time 0.2.18",
|
||||
"time 0.2.20",
|
||||
"timer",
|
||||
"tokio 0.2.22",
|
||||
"toml",
|
||||
@@ -1163,9 +1184,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "derive_more"
|
||||
version = "0.99.9"
|
||||
version = "0.99.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "298998b1cf6b5b2c8a7b023dfd45821825ce3ba8a8af55c921a0e734e4653f76"
|
||||
checksum = "1dcfabdab475c16a93d669dddfc393027803e347d09663f524447f642fbb84ba"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -1262,9 +1283,9 @@ checksum = "134951f4028bdadb9b84baf4232681efbf277da25144b9b0ad65df75946c422b"
|
||||
|
||||
[[package]]
|
||||
name = "ed25519"
|
||||
version = "1.0.1"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bf038a7b6fd7ef78ad3348b63f3a17550877b0e28f8d68bcc94894d1412158bc"
|
||||
checksum = "07dfc993ea376e864fe29a4099a61ca0bb994c6d7745a61bf60ddb3d64e05237"
|
||||
dependencies = [
|
||||
"signature",
|
||||
]
|
||||
@@ -1308,9 +1329,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.6.0"
|
||||
version = "1.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cd56b59865bce947ac5958779cfa508f6c3b9497cc762b7e24a12d11ccde2c4f"
|
||||
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
|
||||
|
||||
[[package]]
|
||||
name = "encoding_rs"
|
||||
@@ -1521,6 +1542,7 @@ dependencies = [
|
||||
"lru",
|
||||
"parking_lot 0.11.0",
|
||||
"rand 0.7.3",
|
||||
"regex",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"sha2 0.9.1",
|
||||
@@ -1578,13 +1600,11 @@ dependencies = [
|
||||
"enr",
|
||||
"eth2_config",
|
||||
"eth2_ssz",
|
||||
"handlebars",
|
||||
"reqwest",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_yaml",
|
||||
"tempdir",
|
||||
"types",
|
||||
"zip",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1996,9 +2016,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.1.14"
|
||||
version = "0.1.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb"
|
||||
checksum = "fc587bc0ec293155d5bfa6b9891ec18a1e330c234f896ea47fbada4cadbe47e6"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
@@ -2091,20 +2111,6 @@ version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d36fab90f82edc3c747f9d438e06cf0a491055896f2a279638bb5beed6c40177"
|
||||
|
||||
[[package]]
|
||||
name = "handlebars"
|
||||
version = "3.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5deefd4816fb852b1ff3cb48f6c41da67be2d0e1d20b26a7a3b076da11f064b1"
|
||||
dependencies = [
|
||||
"log 0.4.11",
|
||||
"pest",
|
||||
"pest_derive",
|
||||
"quick-error 2.0.0",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.6.3"
|
||||
@@ -2262,7 +2268,7 @@ version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f"
|
||||
dependencies = [
|
||||
"quick-error 1.2.3",
|
||||
"quick-error",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2440,9 +2446,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "integer-sqrt"
|
||||
version = "0.1.4"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d3038ef3da477fd70e6161006ef37f919c24bfe7244062f67a69defe72c02aa"
|
||||
checksum = "276ec31bcb4a9ee45f58bec6f9ec700ae4cf4f4f8f2fa7e06cb406bd5ffdd770"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
@@ -2547,7 +2553,7 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
|
||||
|
||||
[[package]]
|
||||
name = "lcli"
|
||||
version = "0.2.9"
|
||||
version = "0.2.10"
|
||||
dependencies = [
|
||||
"bls",
|
||||
"clap",
|
||||
@@ -2600,9 +2606,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.76"
|
||||
version = "0.2.77"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "755456fae044e6fa1ebbbd1b3e902ae19e73097ed4ed87bb79934a867c007bc3"
|
||||
checksum = "f2f96b10ec2560088a8e76961b00d47107b3a625fecb76dedb29ee7ccbf98235"
|
||||
|
||||
[[package]]
|
||||
name = "libflate"
|
||||
@@ -2905,7 +2911,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "lighthouse"
|
||||
version = "0.2.9"
|
||||
version = "0.2.10"
|
||||
dependencies = [
|
||||
"account_manager",
|
||||
"account_utils",
|
||||
@@ -3123,11 +3129,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.4.1"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4d7559a8a40d0f97e1edea3220f698f78b1c5ab67532e49f68fde3910323b722"
|
||||
checksum = "c60c0dfe32c10b43a144bad8fc83538c52f58302c92300ea7ec7bf7b38d5a7b9"
|
||||
dependencies = [
|
||||
"adler",
|
||||
"autocfg 1.0.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3675,49 +3682,6 @@ version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
|
||||
|
||||
[[package]]
|
||||
name = "pest"
|
||||
version = "2.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53"
|
||||
dependencies = [
|
||||
"ucd-trie",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pest_derive"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "833d1ae558dc601e9a60366421196a8d94bc0ac980476d0b67e1d0988d72b2d0"
|
||||
dependencies = [
|
||||
"pest",
|
||||
"pest_generator",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pest_generator"
|
||||
version = "2.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "99b8db626e31e5b81787b9783425769681b347011cc59471e33ea46d2ea0cf55"
|
||||
dependencies = [
|
||||
"pest",
|
||||
"pest_meta",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pest_meta"
|
||||
version = "2.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "54be6e404f5317079812fc8f9f5279de376d8856929e21c184ecf6bbd692a11d"
|
||||
dependencies = [
|
||||
"maplit",
|
||||
"pest",
|
||||
"sha-1 0.8.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "petgraph"
|
||||
version = "0.5.1"
|
||||
@@ -3784,6 +3748,12 @@ dependencies = [
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "podio"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b18befed8bc2b61abc79a457295e7e838417326da1586050b919414073977f19"
|
||||
|
||||
[[package]]
|
||||
name = "poly1305"
|
||||
version = "0.6.0"
|
||||
@@ -3836,9 +3806,9 @@ checksum = "eba180dafb9038b050a4c280019bbedf9f2467b61e5d892dcad585bb57aadc5a"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.20"
|
||||
version = "1.0.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "175c513d55719db99da20232b06cda8bab6b83ec2d04e3283edf0213c37c1a29"
|
||||
checksum = "36e28516df94f3dd551a587da5357459d9b36d945a7c37c3557928c1c2ff2a2c"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
@@ -3963,12 +3933,6 @@ version = "1.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
|
||||
|
||||
[[package]]
|
||||
name = "quick-error"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3ac73b1112776fc109b2e61909bc46c7e1bf0d7f690ffb1676553acce16d5cda"
|
||||
|
||||
[[package]]
|
||||
name = "quickcheck"
|
||||
version = "0.9.2"
|
||||
@@ -4598,9 +4562,9 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.115"
|
||||
version = "1.0.116"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e54c9a88f2da7238af84b5101443f0c0d0a3bbdc455e34a5c9497b1903ed55d5"
|
||||
checksum = "96fe57af81d28386a513cbc6858332abc6117cfdb5999647c6444b8f43a370a5"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
@@ -4617,9 +4581,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.115"
|
||||
version = "1.0.116"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "609feed1d0a73cc36a0182a840a9b37b4a82f0b1150369f0536a9e3f2a31dc48"
|
||||
checksum = "f630a6370fd8e457873b4bd2ffdae75408bc291ba72be773772a4c2a065d9ae8"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -4996,9 +4960,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "socket2"
|
||||
version = "0.3.12"
|
||||
version = "0.3.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "03088793f677dce356f3ccc2edb1b314ad191ab702a5de3faf49304f7e104918"
|
||||
checksum = "b1fa70dc5c8104ec096f4fe7ede7a221d35ae13dcd19ba1ad9a81d2cab9a1c44"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
@@ -5201,9 +5165,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.40"
|
||||
version = "1.0.41"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "963f7d3cc59b59b9325165add223142bbf1df27655d07789f109896d353d8350"
|
||||
checksum = "6690e3e9f692504b941dc6c3b188fd28df054f7fb8469ab40680df52fdcc842b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -5345,9 +5309,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.2.18"
|
||||
version = "0.2.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "12785163ae8a1cbb52a5db39af4a5baabd3fe49f07f76f952f89d7e89e5ce531"
|
||||
checksum = "0d4953c513c9bf1b97e9cdd83f11d60c4b0a83462880a360d80d96953a953fee"
|
||||
dependencies = [
|
||||
"const_fn",
|
||||
"libc",
|
||||
@@ -5904,12 +5868,6 @@ dependencies = [
|
||||
"tree_hash_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ucd-trie"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c"
|
||||
|
||||
[[package]]
|
||||
name = "uhttp_sse"
|
||||
version = "0.5.1"
|
||||
@@ -6068,7 +6026,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "validator_client"
|
||||
version = "0.2.9"
|
||||
version = "0.2.10"
|
||||
dependencies = [
|
||||
"account_utils",
|
||||
"bls",
|
||||
@@ -6523,21 +6481,34 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "zeroize"
|
||||
version = "1.1.0"
|
||||
version = "1.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3cbac2ed2ba24cc90f5e06485ac8c7c1e5449fe8911aef4d8877218af021a5b8"
|
||||
checksum = "05f33972566adbd2d3588b0491eb94b98b43695c4ef897903470ede4f3f5a28a"
|
||||
dependencies = [
|
||||
"zeroize_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zeroize_derive"
|
||||
version = "1.0.0"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "de251eec69fc7c1bc3923403d18ececb929380e016afe103da75f396704f8ca2"
|
||||
checksum = "c3f369ddb18862aba61aa49bf31e74d29f0f162dec753063200e1dc084345d16"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"synstructure",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zip"
|
||||
version = "0.5.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "58287c28d78507f5f91f2a4cf1e8310e2c76fd4c6932f93ac60fd1ceb402db7d"
|
||||
dependencies = [
|
||||
"bzip2",
|
||||
"crc32fast",
|
||||
"flate2",
|
||||
"podio",
|
||||
"time 0.1.44",
|
||||
]
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
An open-source Ethereum 2.0 client, written in Rust and maintained by Sigma Prime.
|
||||
|
||||
[![Build Status]][Build Link] [![Book Status]][Book Link] [![RustDoc Status]][RustDoc Link] [![Chat Badge]][Chat Link]
|
||||
[![Build Status]][Build Link] [![Book Status]][Book Link] [![Chat Badge]][Chat Link]
|
||||
|
||||
[Build Status]: https://github.com/sigp/lighthouse/workflows/test-suite/badge.svg?branch=master
|
||||
[Build Link]: https://github.com/sigp/lighthouse/actions
|
||||
@@ -10,8 +10,6 @@ An open-source Ethereum 2.0 client, written in Rust and maintained by Sigma Prim
|
||||
[Chat Link]: https://discord.gg/cyAszAh
|
||||
[Book Status]:https://img.shields.io/badge/user--docs-master-informational
|
||||
[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/
|
||||
|
||||
[Documentation](http://lighthouse-book.sigmaprime.io/)
|
||||
|
||||
@@ -59,9 +57,6 @@ Current development overview:
|
||||
The [Lighthouse Book](http://lighthouse-book.sigmaprime.io/) contains information
|
||||
for testnet users and developers.
|
||||
|
||||
Code documentation is generated via `cargo doc` and hosted at
|
||||
[lighthouse-docs.sigmaprime.io](http://lighthouse-docs.sigmaprime.io/).
|
||||
|
||||
If you'd like some background on Sigma Prime, please see the [Lighthouse Update
|
||||
\#00](https://lighthouse.sigmaprime.io/update-00.html) blog post or
|
||||
[sigmaprime.io](https://sigmaprime.io).
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "account_manager"
|
||||
version = "0.2.9"
|
||||
version = "0.2.10"
|
||||
authors = ["Paul Hauner <paul@paulhauner.com>", "Luke Anderson <luke@sigmaprime.io>"]
|
||||
edition = "2018"
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "beacon_node"
|
||||
version = "0.2.9"
|
||||
version = "0.2.10"
|
||||
authors = ["Paul Hauner <paul@paulhauner.com>", "Age Manning <Age@AgeManning.com"]
|
||||
edition = "2018"
|
||||
|
||||
|
||||
@@ -980,14 +980,17 @@ fn load_parent<T: BeaconChainTypes>(
|
||||
// exist in fork choice but not in the database yet. In such a case we simply
|
||||
// indicate that we don't yet know the parent.
|
||||
let root = block.parent_root();
|
||||
let parent_block = if let Some(block) = chain
|
||||
let parent_block = chain
|
||||
.get_block(&block.parent_root())
|
||||
.map_err(BlockError::BeaconChainError)?
|
||||
{
|
||||
block
|
||||
} else {
|
||||
return Err(BlockError::ParentUnknown(Box::new(block)));
|
||||
};
|
||||
.ok_or_else(|| {
|
||||
// Return a `MissingBeaconBlock` error instead of a `ParentUnknown` error since
|
||||
// we've already checked fork choice for this block.
|
||||
//
|
||||
// It's an internal error if the block exists in fork choice but not in the
|
||||
// database.
|
||||
BlockError::from(BeaconChainError::MissingBeaconBlock(block.parent_root()))
|
||||
})?;
|
||||
|
||||
// Load the parent blocks state from the database, returning an error if it is not found.
|
||||
// It is an error because if we know the parent block we should also know the parent state.
|
||||
|
||||
@@ -37,6 +37,7 @@ tiny-keccak = "2.0.2"
|
||||
environment = { path = "../../lighthouse/environment" }
|
||||
# TODO: Remove rand crate for mainnet
|
||||
rand = "0.7.3"
|
||||
regex = "1.3.9"
|
||||
|
||||
[dependencies.libp2p]
|
||||
#version = "0.23.0"
|
||||
|
||||
@@ -85,13 +85,9 @@ impl Default for Config {
|
||||
];
|
||||
|
||||
// The function used to generate a gossipsub message id
|
||||
// We use base64(SHA256(data)) for content addressing
|
||||
let gossip_message_id = |message: &GossipsubMessage| {
|
||||
MessageId::from(base64::encode_config(
|
||||
&Sha256::digest(&message.data),
|
||||
base64::URL_SAFE_NO_PAD,
|
||||
))
|
||||
};
|
||||
// We use the first 8 bytes of SHA256(data) for content addressing
|
||||
let gossip_message_id =
|
||||
|message: &GossipsubMessage| MessageId::from(&Sha256::digest(&message.data)[..8]);
|
||||
|
||||
// gossipsub configuration
|
||||
// Note: The topics by default are sent as plain strings. Hashes are an optional
|
||||
@@ -107,7 +103,7 @@ impl Default for Config {
|
||||
.history_length(6)
|
||||
.history_gossip(3)
|
||||
.validate_messages() // require validation before propagation
|
||||
.validation_mode(ValidationMode::Permissive)
|
||||
.validation_mode(ValidationMode::Anonymous)
|
||||
// prevent duplicates for 550 heartbeats(700millis * 550) = 385 secs
|
||||
.duplicate_cache_time(Duration::from_secs(385))
|
||||
.message_id_fn(gossip_message_id)
|
||||
|
||||
@@ -31,12 +31,12 @@ use tokio::sync::mpsc;
|
||||
use types::{EnrForkId, EthSpec, SubnetId};
|
||||
|
||||
mod subnet_predicate;
|
||||
use subnet_predicate::subnet_predicate;
|
||||
pub use subnet_predicate::subnet_predicate;
|
||||
|
||||
/// Local ENR storage filename.
|
||||
pub const ENR_FILENAME: &str = "enr.dat";
|
||||
/// Target number of peers we'd like to have connected to a given long-lived subnet.
|
||||
const TARGET_SUBNET_PEERS: usize = 3;
|
||||
pub const TARGET_SUBNET_PEERS: usize = 3;
|
||||
/// Target number of peers to search for given a grouped subnet query.
|
||||
const TARGET_PEERS_FOR_GROUPED_QUERY: usize = 6;
|
||||
/// Number of times to attempt a discovery request.
|
||||
@@ -287,6 +287,11 @@ impl<TSpec: EthSpec> Discovery<TSpec> {
|
||||
self.discv5.local_enr()
|
||||
}
|
||||
|
||||
/// Return the cached enrs.
|
||||
pub fn cached_enrs(&self) -> impl Iterator<Item = (&PeerId, &Enr)> {
|
||||
self.cached_enrs.iter()
|
||||
}
|
||||
|
||||
/// This adds a new `FindPeers` query to the queue if one doesn't already exist.
|
||||
pub fn discover_peers(&mut self) {
|
||||
// If the discv5 service isn't running or we are in the process of a query, don't bother queuing a new one.
|
||||
@@ -558,7 +563,7 @@ impl<TSpec: EthSpec> Discovery<TSpec> {
|
||||
.peers_on_subnet(subnet_query.subnet_id)
|
||||
.count();
|
||||
|
||||
if peers_on_subnet > TARGET_SUBNET_PEERS {
|
||||
if peers_on_subnet >= TARGET_SUBNET_PEERS {
|
||||
debug!(self.log, "Discovery ignored";
|
||||
"reason" => "Already connected to desired peers",
|
||||
"connected_peers_on_subnet" => peers_on_subnet,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//! Implementation of a Lighthouse's peer management system.
|
||||
|
||||
pub use self::peerdb::*;
|
||||
use crate::discovery::{Discovery, DiscoveryEvent};
|
||||
use crate::discovery::{subnet_predicate, Discovery, DiscoveryEvent, TARGET_SUBNET_PEERS};
|
||||
use crate::rpc::{GoodbyeReason, MetaData, Protocol, RPCError, RPCResponseErrorCode};
|
||||
use crate::{error, metrics};
|
||||
use crate::{EnrExt, NetworkConfig, NetworkGlobals, PeerId, SubnetDiscovery};
|
||||
@@ -19,7 +19,7 @@ use std::{
|
||||
task::{Context, Poll},
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
use types::EthSpec;
|
||||
use types::{EthSpec, SubnetId};
|
||||
|
||||
pub use libp2p::core::{identity::Keypair, Multiaddr};
|
||||
|
||||
@@ -214,18 +214,45 @@ impl<TSpec: EthSpec> PeerManager<TSpec> {
|
||||
|
||||
/// A request to find peers on a given subnet.
|
||||
pub fn discover_subnet_peers(&mut self, subnets_to_discover: Vec<SubnetDiscovery>) {
|
||||
// Extend the time to maintain peers if required.
|
||||
for s in subnets_to_discover.iter() {
|
||||
if let Some(min_ttl) = s.min_ttl {
|
||||
self.network_globals
|
||||
let filtered: Vec<SubnetDiscovery> = subnets_to_discover
|
||||
.into_iter()
|
||||
.filter(|s| {
|
||||
// Extend min_ttl of connected peers on required subnets
|
||||
if let Some(min_ttl) = s.min_ttl {
|
||||
self.network_globals
|
||||
.peers
|
||||
.write()
|
||||
.extend_peers_on_subnet(s.subnet_id, min_ttl);
|
||||
}
|
||||
// Already have target number of peers, no need for subnet discovery
|
||||
let peers_on_subnet = self
|
||||
.network_globals
|
||||
.peers
|
||||
.write()
|
||||
.extend_peers_on_subnet(s.subnet_id, min_ttl);
|
||||
}
|
||||
}
|
||||
.read()
|
||||
.peers_on_subnet(s.subnet_id)
|
||||
.count();
|
||||
if peers_on_subnet >= TARGET_SUBNET_PEERS {
|
||||
debug!(
|
||||
self.log,
|
||||
"Discovery query ignored";
|
||||
"subnet_id" => format!("{:?}",s.subnet_id),
|
||||
"reason" => "Already connected to desired peers",
|
||||
"connected_peers_on_subnet" => peers_on_subnet,
|
||||
"target_subnet_peers" => TARGET_SUBNET_PEERS,
|
||||
);
|
||||
false
|
||||
// Queue an outgoing connection request to the cached peers that are on `s.subnet_id`.
|
||||
// If we connect to the cached peers before the discovery query starts, then we potentially
|
||||
// save a costly discovery query.
|
||||
} else {
|
||||
self.dial_cached_enrs_in_subnet(s.subnet_id);
|
||||
true
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
// request the subnet query from discovery
|
||||
self.discovery.discover_subnet_peers(subnets_to_discover);
|
||||
self.discovery.discover_subnet_peers(filtered);
|
||||
}
|
||||
|
||||
/// A STATUS message has been received from a peer. This resets the status timer.
|
||||
@@ -531,6 +558,30 @@ impl<TSpec: EthSpec> PeerManager<TSpec> {
|
||||
self.events.push(PeerManagerEvent::SocketUpdated(multiaddr));
|
||||
}
|
||||
|
||||
/// Dial cached enrs in discovery service that are in the given `subnet_id` and aren't
|
||||
/// in Connected, Dialing or Banned state.
|
||||
fn dial_cached_enrs_in_subnet(&mut self, subnet_id: SubnetId) {
|
||||
let predicate = subnet_predicate::<TSpec>(vec![subnet_id], &self.log);
|
||||
let peers_to_dial: Vec<PeerId> = self
|
||||
.discovery()
|
||||
.cached_enrs()
|
||||
.filter_map(|(peer_id, enr)| {
|
||||
let peers = self.network_globals.peers.read();
|
||||
if predicate(enr)
|
||||
&& !peers.is_connected_or_dialing(peer_id)
|
||||
&& !peers.is_banned(peer_id)
|
||||
{
|
||||
Some(peer_id.clone())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
for peer in &peers_to_dial {
|
||||
self.dial_peer(peer);
|
||||
}
|
||||
}
|
||||
|
||||
/// Peers that have been returned by discovery requests are dialed here if they are suitable.
|
||||
///
|
||||
/// NOTE: By dialing `PeerId`s and not multiaddrs, libp2p requests the multiaddr associated
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
//! Available RPC methods types and ids.
|
||||
|
||||
use crate::types::EnrBitfield;
|
||||
use regex::bytes::Regex;
|
||||
use serde::Serialize;
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use ssz_types::{
|
||||
@@ -42,10 +43,9 @@ impl Deref for ErrorType {
|
||||
|
||||
impl ToString for ErrorType {
|
||||
fn to_string(&self) -> String {
|
||||
match std::str::from_utf8(self.0.deref()) {
|
||||
Ok(s) => s.to_string(),
|
||||
Err(_) => format!("{:?}", self.0.deref()), // Display raw bytes if not a UTF-8 string
|
||||
}
|
||||
#[allow(clippy::invalid_regex)]
|
||||
let re = Regex::new("\\p{C}").expect("Regex is valid");
|
||||
String::from_utf8_lossy(&re.replace_all(self.0.deref(), &b""[..])).to_string()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -189,7 +189,30 @@ impl RPCRateLimiter {
|
||||
request: &RPCRequest<T>,
|
||||
) -> Result<(), RateLimitedErr> {
|
||||
let time_since_start = self.init_time.elapsed();
|
||||
let tokens = request.expected_responses().max(1);
|
||||
let mut tokens = request.expected_responses().max(1);
|
||||
|
||||
// Increase the rate limit for blocks by range requests with large step counts.
|
||||
// We count to tokens as a quadratic increase with step size.
|
||||
// Using (step_size/5)^2 + 1 as penalty factor allows step sizes of 1-4 to have no penalty
|
||||
// but step sizes higher than this add a quadratic penalty.
|
||||
// Penalty's go:
|
||||
// Step size | Penalty Factor
|
||||
// 1 | 1
|
||||
// 2 | 1
|
||||
// 3 | 1
|
||||
// 4 | 1
|
||||
// 5 | 2
|
||||
// 6 | 2
|
||||
// 7 | 2
|
||||
// 8 | 3
|
||||
// 9 | 4
|
||||
// 10 | 5
|
||||
|
||||
if let RPCRequest::BlocksByRange(bbr_req) = request {
|
||||
let penalty_factor = (bbr_req.step as f64 / 5.0).powi(2) as u64 + 1;
|
||||
tokens *= penalty_factor;
|
||||
}
|
||||
|
||||
let check =
|
||||
|limiter: &mut Limiter<PeerId>| limiter.allows(time_since_start, peer_id, tokens);
|
||||
let limiter = match request.protocol() {
|
||||
|
||||
@@ -7,7 +7,7 @@ use beacon_chain::{
|
||||
attestation_verification::Error as AttnError, observed_operations::ObservationOutcome,
|
||||
BeaconChain, BeaconChainError, BeaconChainTypes, BlockError, ForkChoiceError,
|
||||
};
|
||||
use eth2_libp2p::{MessageAcceptance, MessageId, PeerId};
|
||||
use eth2_libp2p::{MessageAcceptance, MessageId, PeerAction, PeerId};
|
||||
use slog::{crit, debug, error, info, trace, warn, Logger};
|
||||
use ssz::Encode;
|
||||
use std::sync::Arc;
|
||||
@@ -234,7 +234,12 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
| Err(e @ BlockError::GenesisBlock) => {
|
||||
warn!(self.log, "Could not verify block for gossip, rejecting the block";
|
||||
"error" => e.to_string());
|
||||
self.propagate_validation_result(message_id, peer_id, MessageAcceptance::Reject);
|
||||
self.propagate_validation_result(
|
||||
message_id,
|
||||
peer_id.clone(),
|
||||
MessageAcceptance::Reject,
|
||||
);
|
||||
self.penalize_peer(peer_id, PeerAction::LowToleranceError);
|
||||
return;
|
||||
}
|
||||
};
|
||||
@@ -252,9 +257,6 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
"peer_id" => peer_id.to_string()
|
||||
);
|
||||
|
||||
// TODO: It would be better if we can run this _after_ we publish the block to
|
||||
// reduce block propagation latency.
|
||||
//
|
||||
// The `MessageHandler` would be the place to put this, however it doesn't seem
|
||||
// to have a reference to the `BeaconChain`. I will leave this for future
|
||||
// works.
|
||||
@@ -290,6 +292,7 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
"block root" => format!("{}", block.canonical_root()),
|
||||
"block slot" => block.slot()
|
||||
);
|
||||
self.penalize_peer(peer_id, PeerAction::MidToleranceError);
|
||||
trace!(
|
||||
self.log,
|
||||
"Invalid gossip beacon block ssz";
|
||||
@@ -333,7 +336,13 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
);
|
||||
// These errors occur due to a fault in the beacon chain. It is not necessarily
|
||||
// the fault on the peer.
|
||||
self.propagate_validation_result(message_id, peer_id, MessageAcceptance::Ignore);
|
||||
self.propagate_validation_result(
|
||||
message_id,
|
||||
peer_id.clone(),
|
||||
MessageAcceptance::Ignore,
|
||||
);
|
||||
// We still penalize a peer slightly to prevent overuse of invalids.
|
||||
self.penalize_peer(peer_id, PeerAction::HighToleranceError);
|
||||
return;
|
||||
}
|
||||
};
|
||||
@@ -382,7 +391,14 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
"peer" => peer_id.to_string(),
|
||||
"error" => format!("{:?}", e)
|
||||
);
|
||||
self.propagate_validation_result(message_id, peer_id, MessageAcceptance::Ignore);
|
||||
self.propagate_validation_result(
|
||||
message_id,
|
||||
peer_id.clone(),
|
||||
MessageAcceptance::Ignore,
|
||||
);
|
||||
|
||||
// Penalize peer slightly for invalids.
|
||||
self.penalize_peer(peer_id, PeerAction::HighToleranceError);
|
||||
return;
|
||||
}
|
||||
};
|
||||
@@ -425,7 +441,13 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
"peer" => peer_id.to_string(),
|
||||
"error" => format!("{:?}", e)
|
||||
);
|
||||
self.propagate_validation_result(message_id, peer_id, MessageAcceptance::Ignore);
|
||||
self.propagate_validation_result(
|
||||
message_id,
|
||||
peer_id.clone(),
|
||||
MessageAcceptance::Ignore,
|
||||
);
|
||||
// Penalize peer slightly for invalids.
|
||||
self.penalize_peer(peer_id, PeerAction::HighToleranceError);
|
||||
return;
|
||||
}
|
||||
};
|
||||
@@ -497,6 +519,18 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
});
|
||||
}
|
||||
|
||||
/// Penalizes a peer for misbehaviour.
|
||||
fn penalize_peer(&self, peer_id: PeerId, action: PeerAction) {
|
||||
self.network_tx
|
||||
.send(NetworkMessage::ReportPeer { peer_id, action })
|
||||
.unwrap_or_else(|_| {
|
||||
warn!(
|
||||
self.log,
|
||||
"Could not send peer action to the network service"
|
||||
)
|
||||
});
|
||||
}
|
||||
|
||||
/// Send a message to `sync_tx`.
|
||||
///
|
||||
/// Creates a log if there is an interal error.
|
||||
@@ -528,10 +562,17 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
*
|
||||
* The peer has published an invalid consensus message, _only_ if we trust our own clock.
|
||||
*/
|
||||
trace!(
|
||||
self.log,
|
||||
"Attestation is not within the last ATTESTATION_PROPAGATION_SLOT_RANGE slots";
|
||||
"peer_id" => peer_id.to_string(),
|
||||
"block" => format!("{}", beacon_block_root),
|
||||
"type" => format!("{:?}", attestation_type),
|
||||
);
|
||||
self.propagate_validation_result(
|
||||
message_id,
|
||||
peer_id.clone(),
|
||||
MessageAcceptance::Reject,
|
||||
MessageAcceptance::Ignore,
|
||||
);
|
||||
}
|
||||
AttnError::InvalidSelectionProof { .. } | AttnError::InvalidSignature => {
|
||||
@@ -545,6 +586,7 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
peer_id.clone(),
|
||||
MessageAcceptance::Reject,
|
||||
);
|
||||
self.penalize_peer(peer_id.clone(), PeerAction::LowToleranceError);
|
||||
}
|
||||
AttnError::EmptyAggregationBitfield => {
|
||||
/*
|
||||
@@ -559,6 +601,7 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
peer_id.clone(),
|
||||
MessageAcceptance::Reject,
|
||||
);
|
||||
self.penalize_peer(peer_id.clone(), PeerAction::LowToleranceError);
|
||||
}
|
||||
AttnError::AggregatorPubkeyUnknown(_) => {
|
||||
/*
|
||||
@@ -579,6 +622,7 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
peer_id.clone(),
|
||||
MessageAcceptance::Reject,
|
||||
);
|
||||
self.penalize_peer(peer_id.clone(), PeerAction::LowToleranceError);
|
||||
}
|
||||
AttnError::AggregatorNotInCommittee { .. } => {
|
||||
/*
|
||||
@@ -599,6 +643,7 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
peer_id.clone(),
|
||||
MessageAcceptance::Reject,
|
||||
);
|
||||
self.penalize_peer(peer_id.clone(), PeerAction::LowToleranceError);
|
||||
}
|
||||
AttnError::AttestationAlreadyKnown { .. } => {
|
||||
/*
|
||||
@@ -662,6 +707,7 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
peer_id.clone(),
|
||||
MessageAcceptance::Reject,
|
||||
);
|
||||
self.penalize_peer(peer_id.clone(), PeerAction::LowToleranceError);
|
||||
}
|
||||
AttnError::UnknownHeadBlock { beacon_block_root } => {
|
||||
// Note: its a little bit unclear as to whether or not this block is unknown or
|
||||
@@ -714,6 +760,7 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
peer_id.clone(),
|
||||
MessageAcceptance::Reject,
|
||||
);
|
||||
self.penalize_peer(peer_id.clone(), PeerAction::LowToleranceError);
|
||||
}
|
||||
AttnError::BadTargetEpoch => {
|
||||
/*
|
||||
@@ -727,6 +774,7 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
peer_id.clone(),
|
||||
MessageAcceptance::Reject,
|
||||
);
|
||||
self.penalize_peer(peer_id.clone(), PeerAction::LowToleranceError);
|
||||
}
|
||||
AttnError::NoCommitteeForSlotAndIndex { .. } => {
|
||||
/*
|
||||
@@ -739,6 +787,7 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
peer_id.clone(),
|
||||
MessageAcceptance::Reject,
|
||||
);
|
||||
self.penalize_peer(peer_id.clone(), PeerAction::LowToleranceError);
|
||||
}
|
||||
AttnError::NotExactlyOneAggregationBitSet(_) => {
|
||||
/*
|
||||
@@ -751,6 +800,7 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
peer_id.clone(),
|
||||
MessageAcceptance::Reject,
|
||||
);
|
||||
self.penalize_peer(peer_id.clone(), PeerAction::LowToleranceError);
|
||||
}
|
||||
AttnError::AttestsToFutureBlock { .. } => {
|
||||
/*
|
||||
@@ -763,6 +813,7 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
peer_id.clone(),
|
||||
MessageAcceptance::Reject,
|
||||
);
|
||||
self.penalize_peer(peer_id.clone(), PeerAction::LowToleranceError);
|
||||
}
|
||||
|
||||
AttnError::InvalidSubnetId { received, expected } => {
|
||||
@@ -780,6 +831,7 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
peer_id.clone(),
|
||||
MessageAcceptance::Reject,
|
||||
);
|
||||
self.penalize_peer(peer_id.clone(), PeerAction::LowToleranceError);
|
||||
}
|
||||
AttnError::Invalid(_) => {
|
||||
/*
|
||||
@@ -792,6 +844,7 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
peer_id.clone(),
|
||||
MessageAcceptance::Reject,
|
||||
);
|
||||
self.penalize_peer(peer_id.clone(), PeerAction::LowToleranceError);
|
||||
}
|
||||
AttnError::TooManySkippedSlots {
|
||||
head_block_slot,
|
||||
@@ -815,6 +868,7 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
peer_id.clone(),
|
||||
MessageAcceptance::Reject,
|
||||
);
|
||||
self.penalize_peer(peer_id.clone(), PeerAction::MidToleranceError);
|
||||
}
|
||||
AttnError::BeaconChainError(e) => {
|
||||
/*
|
||||
@@ -835,6 +889,8 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
peer_id.clone(),
|
||||
MessageAcceptance::Ignore,
|
||||
);
|
||||
// Penalize the peer slightly
|
||||
self.penalize_peer(peer_id.clone(), PeerAction::HighToleranceError);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -374,22 +374,29 @@ impl<T: BeaconChainTypes> Processor<T> {
|
||||
}
|
||||
};
|
||||
|
||||
// pick out the required blocks, ignoring skip-slots and stepping by the step parameter;
|
||||
// Pick out the required blocks, ignoring skip-slots and stepping by the step parameter.
|
||||
//
|
||||
// NOTE: We don't mind if req.count * req.step overflows as it just ends the iterator early and
|
||||
// the peer will get less blocks.
|
||||
// The step parameter is quadratically weighted in the filter, so large values should be
|
||||
// prevented before reaching this point.
|
||||
let mut last_block_root = None;
|
||||
let maybe_block_roots = process_results(forwards_block_root_iter, |iter| {
|
||||
iter.take_while(|(_, slot)| slot.as_u64() < req.start_slot + req.count * req.step)
|
||||
// map skip slots to None
|
||||
.map(|(root, _)| {
|
||||
let result = if Some(root) == last_block_root {
|
||||
None
|
||||
} else {
|
||||
Some(root)
|
||||
};
|
||||
last_block_root = Some(root);
|
||||
result
|
||||
})
|
||||
.step_by(req.step as usize)
|
||||
.collect::<Vec<Option<Hash256>>>()
|
||||
iter.take_while(|(_, slot)| {
|
||||
slot.as_u64() < req.start_slot.saturating_add(req.count * req.step)
|
||||
})
|
||||
// map skip slots to None
|
||||
.map(|(root, _)| {
|
||||
let result = if Some(root) == last_block_root {
|
||||
None
|
||||
} else {
|
||||
Some(root)
|
||||
};
|
||||
last_block_root = Some(root);
|
||||
result
|
||||
})
|
||||
.step_by(req.step as usize)
|
||||
.collect::<Vec<Option<Hash256>>>()
|
||||
});
|
||||
|
||||
let block_roots = match maybe_block_roots {
|
||||
|
||||
@@ -248,15 +248,17 @@ impl<T: BeaconChainTypes> ChainCollection<T> {
|
||||
// Check if any chains become the new syncing chain
|
||||
if let Some(index) = self.finalized_syncing_index() {
|
||||
// There is a current finalized chain syncing
|
||||
let syncing_chain_peer_count = self.finalized_chains[index].peer_pool.len();
|
||||
let _syncing_chain_peer_count = self.finalized_chains[index].peer_pool.len();
|
||||
|
||||
// search for a chain with more peers
|
||||
if let Some((new_index, chain)) =
|
||||
self.finalized_chains
|
||||
.iter_mut()
|
||||
.enumerate()
|
||||
.find(|(iter_index, chain)| {
|
||||
*iter_index != index && chain.peer_pool.len() > syncing_chain_peer_count
|
||||
.find(|(_iter_index, _chain)| {
|
||||
false
|
||||
// && *iter_index != index
|
||||
// && chain.peer_pool.len() > syncing_chain_peer_count
|
||||
})
|
||||
{
|
||||
// A chain has more peers. Swap the syncing chain
|
||||
|
||||
@@ -2,12 +2,10 @@
|
||||
|
||||
_Documentation for Lighthouse users and developers._
|
||||
|
||||
[![Doc Status]][Doc Link] [![Chat Badge]][Chat Link]
|
||||
[![Chat Badge]][Chat Link]
|
||||
|
||||
[Chat Badge]: https://img.shields.io/badge/chat-discord-%237289da
|
||||
[Chat Link]: https://discord.gg/cyAszAh
|
||||
[Doc Status]:https://img.shields.io/badge/rust--docs-master-orange
|
||||
[Doc Link]: http://lighthouse-docs.sigmaprime.io/
|
||||
|
||||
Lighthouse is an **Ethereum 2.0 client** that connects to other Ethereum 2.0
|
||||
clients to form a resilient and decentralized proof-of-stake blockchain.
|
||||
@@ -24,7 +22,6 @@ You may read this book from start to finish, or jump to some of these topics:
|
||||
- Utilize the whole stack by starting a [local testnet](./local-testnets.md).
|
||||
- Query the [RESTful HTTP API](./http.md) using `curl`.
|
||||
- Listen to events with the [JSON WebSocket API](./websockets.md).
|
||||
- View the [Rust code docs](http://lighthouse-docs.sigmaprime.io/).
|
||||
|
||||
|
||||
Prospective contributors can read the [Contributing](./contributing.md) section
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "boot_node"
|
||||
version = "0.2.9"
|
||||
version = "0.2.10"
|
||||
authors = ["Sigma Prime <contact@sigmaprime.io>"]
|
||||
edition = "2018"
|
||||
|
||||
|
||||
@@ -48,22 +48,29 @@ impl Eth2Config {
|
||||
/// Used by the `eth2_testnet_config` crate to initialize testnet directories during build and
|
||||
/// access them at runtime.
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub struct Eth2NetDirectory<'a> {
|
||||
pub struct Eth2NetArchiveAndDirectory<'a> {
|
||||
pub name: &'a str,
|
||||
pub unique_id: &'a str,
|
||||
pub archive_name: &'a str,
|
||||
pub commit: &'a str,
|
||||
pub url_template: &'a str,
|
||||
pub genesis_is_known: bool,
|
||||
}
|
||||
|
||||
impl<'a> Eth2NetDirectory<'a> {
|
||||
impl<'a> Eth2NetArchiveAndDirectory<'a> {
|
||||
/// The directory that should be used to store files downloaded for this net.
|
||||
pub fn dir(&self) -> PathBuf {
|
||||
fn pwd(&self) -> PathBuf {
|
||||
env::var("CARGO_MANIFEST_DIR")
|
||||
.expect("should know manifest dir")
|
||||
.parse::<PathBuf>()
|
||||
.expect("should parse manifest dir as path")
|
||||
.join(self.unique_id)
|
||||
}
|
||||
|
||||
pub fn dir(&self) -> PathBuf {
|
||||
self.pwd().join(self.unique_id)
|
||||
}
|
||||
|
||||
pub fn archive_fullpath(&self) -> PathBuf {
|
||||
self.pwd().join(self.archive_name)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,19 +79,23 @@ macro_rules! unique_id {
|
||||
($name: tt, $commit: tt, $genesis_is_known: tt) => {
|
||||
concat!("testnet_", $name, "_", $commit, "_", $genesis_is_known);
|
||||
};
|
||||
|
||||
($name: tt, $commit: tt) => {
|
||||
concat!("testnet_", $name, "_", $commit, ".zip");
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! define_net {
|
||||
($title: ident, $macro_title: tt, $name: tt, $commit: tt, $url_template: tt, $genesis_is_known: tt) => {
|
||||
($title: ident, $macro_title: tt, $name: tt, $commit: tt, $genesis_is_known: tt) => {
|
||||
#[macro_use]
|
||||
pub mod $title {
|
||||
use super::*;
|
||||
|
||||
pub const ETH2_NET_DIR: Eth2NetDirectory = Eth2NetDirectory {
|
||||
pub const ETH2_NET_DIR: Eth2NetArchiveAndDirectory = Eth2NetArchiveAndDirectory {
|
||||
name: $name,
|
||||
unique_id: unique_id!($name, $commit, $genesis_is_known),
|
||||
archive_name: unique_id!($name, $commit),
|
||||
commit: $commit,
|
||||
url_template: $url_template,
|
||||
genesis_is_known: $genesis_is_known,
|
||||
};
|
||||
|
||||
@@ -110,7 +121,6 @@ define_net!(
|
||||
include_altona_file,
|
||||
"altona",
|
||||
"a94e00c1a03df851f960fcf44a79f2a6b1d29af1",
|
||||
"https://raw.githubusercontent.com/sigp/witti/{{ commit }}/altona/lighthouse/{{ file }}",
|
||||
true
|
||||
);
|
||||
|
||||
@@ -119,7 +129,6 @@ define_net!(
|
||||
include_medalla_file,
|
||||
"medalla",
|
||||
"09bbf2c9d108944ac934f94ec6a1d0684ca062a5",
|
||||
"https://raw.githubusercontent.com/sigp/witti/{{ commit }}/medalla/{{ file }}",
|
||||
true
|
||||
);
|
||||
|
||||
|
||||
2
common/eth2_testnet_config/.gitignore
vendored
2
common/eth2_testnet_config/.gitignore
vendored
@@ -1,4 +1,4 @@
|
||||
testnet*
|
||||
testnet*/*
|
||||
schlesi-*
|
||||
witti-*
|
||||
altona*
|
||||
|
||||
@@ -7,10 +7,8 @@ edition = "2018"
|
||||
build = "build.rs"
|
||||
|
||||
[build-dependencies]
|
||||
reqwest = { version = "0.10.4", features = ["blocking", "native-tls-vendored"] }
|
||||
zip = "0.5"
|
||||
eth2_config = { path = "../eth2_config"}
|
||||
handlebars = "3.3.0"
|
||||
serde_json = "1.0.56"
|
||||
|
||||
[dev-dependencies]
|
||||
tempdir = "0.3.7"
|
||||
@@ -21,4 +19,4 @@ serde_yaml = "0.8.11"
|
||||
types = { path = "../../consensus/types"}
|
||||
enr = { version = "0.1.0", features = ["libsecp256k1", "ed25519"] }
|
||||
eth2_ssz = "0.1.2"
|
||||
eth2_config = { path = "../eth2_config"}
|
||||
eth2_config = { path = "../eth2_config"}
|
||||
@@ -1,80 +1,68 @@
|
||||
//! Downloads a testnet configuration from Github.
|
||||
|
||||
use eth2_config::{altona, medalla, Eth2NetDirectory};
|
||||
use handlebars::Handlebars;
|
||||
use serde_json::json;
|
||||
use eth2_config::{altona, medalla, Eth2NetArchiveAndDirectory};
|
||||
use std::fs;
|
||||
use std::fs::File;
|
||||
use std::io::Write;
|
||||
use std::io;
|
||||
use zip::ZipArchive;
|
||||
|
||||
const ETH2_NET_DIRS: &[Eth2NetDirectory<'static>] = &[altona::ETH2_NET_DIR, medalla::ETH2_NET_DIR];
|
||||
const ETH2_NET_DIRS: &[Eth2NetArchiveAndDirectory<'static>] =
|
||||
&[altona::ETH2_NET_DIR, medalla::ETH2_NET_DIR];
|
||||
|
||||
fn main() {
|
||||
for testnet in ETH2_NET_DIRS {
|
||||
let testnet_dir = testnet.dir();
|
||||
|
||||
let archive_fullpath = testnet.archive_fullpath();
|
||||
//no need to do anything if archives have already been uncompressed before
|
||||
if !testnet_dir.exists() {
|
||||
std::fs::create_dir_all(&testnet_dir)
|
||||
.unwrap_or_else(|_| panic!("Unable to create {:?}", testnet_dir));
|
||||
if archive_fullpath.exists() {
|
||||
//uncompress archive and continue
|
||||
let archive_file = match File::open(&archive_fullpath) {
|
||||
Ok(f) => f,
|
||||
Err(e) => panic!("Problem opening archive file: {}", e),
|
||||
};
|
||||
|
||||
match get_all_files(testnet) {
|
||||
Ok(()) => (),
|
||||
Err(e) => {
|
||||
std::fs::remove_dir_all(&testnet_dir).unwrap_or_else(|_| panic!(
|
||||
"{}. Failed to remove {:?}, please remove the directory manually because it may contains incomplete testnet data.",
|
||||
e,
|
||||
testnet_dir,
|
||||
));
|
||||
panic!(e);
|
||||
}
|
||||
match uncompress(archive_file) {
|
||||
Ok(_) => (),
|
||||
Err(e) => panic!(e),
|
||||
};
|
||||
} else {
|
||||
panic!(
|
||||
"Couldn't find testnet archive at this location: {:?}",
|
||||
archive_fullpath
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn get_all_files(testnet: &Eth2NetDirectory<'static>) -> Result<(), String> {
|
||||
get_file(testnet, "boot_enr.yaml")?;
|
||||
get_file(testnet, "config.yaml")?;
|
||||
get_file(testnet, "deploy_block.txt")?;
|
||||
get_file(testnet, "deposit_contract.txt")?;
|
||||
fn uncompress(archive_file: File) -> Result<(), String> {
|
||||
let mut archive =
|
||||
ZipArchive::new(archive_file).map_err(|e| format!("Error with zip file: {}", e))?;
|
||||
for i in 0..archive.len() {
|
||||
let mut file = archive
|
||||
.by_index(i)
|
||||
.map_err(|e| format!("Error retrieving file {} inside zip: {}", i, e))?;
|
||||
|
||||
if testnet.genesis_is_known {
|
||||
get_file(testnet, "genesis.ssz")?;
|
||||
} else {
|
||||
File::create(testnet.dir().join("genesis.ssz")).unwrap();
|
||||
let outpath = file.sanitized_name();
|
||||
|
||||
if file.name().ends_with('/') {
|
||||
fs::create_dir_all(&outpath)
|
||||
.map_err(|e| format!("Error creating testnet directories: {}", e))?;
|
||||
} else {
|
||||
if let Some(p) = outpath.parent() {
|
||||
if !p.exists() {
|
||||
fs::create_dir_all(&p)
|
||||
.map_err(|e| format!("Error creating testnet directories: {}", e))?;
|
||||
}
|
||||
}
|
||||
|
||||
let mut outfile = File::create(&outpath)
|
||||
.map_err(|e| format!("Error while creating file {:?}: {}", outpath, e))?;
|
||||
io::copy(&mut file, &mut outfile)
|
||||
.map_err(|e| format!("Error writing file {:?}: {}", outpath, e))?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_file(testnet: &Eth2NetDirectory, filename: &str) -> Result<(), String> {
|
||||
let url = Handlebars::new()
|
||||
.render_template(
|
||||
testnet.url_template,
|
||||
&json!({"commit": testnet.commit, "file": filename}),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let path = testnet.dir().join(filename);
|
||||
|
||||
let mut file =
|
||||
File::create(path).map_err(|e| format!("Failed to create {}: {:?}", filename, e))?;
|
||||
|
||||
let request = reqwest::blocking::Client::builder()
|
||||
.build()
|
||||
.map_err(|_| "Could not build request client".to_string())?
|
||||
.get(&url)
|
||||
.timeout(std::time::Duration::from_secs(120));
|
||||
|
||||
let contents = request
|
||||
.send()
|
||||
.map_err(|e| format!("Failed to download {}: {}", filename, e))?
|
||||
.error_for_status()
|
||||
.map_err(|e| format!("Error downloading {}: {}", filename, e))?
|
||||
.bytes()
|
||||
.map_err(|e| format!("Failed to read {} response bytes: {}", filename, e))?;
|
||||
|
||||
file.write(&contents)
|
||||
.map_err(|e| format!("Failed to write to {}: {:?}", filename, e))?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -10,7 +10,7 @@ use target_info::Target;
|
||||
/// `Lighthouse/v0.2.0-1419501f2+`
|
||||
pub const VERSION: &str = git_version!(
|
||||
args = ["--always", "--dirty=+"],
|
||||
prefix = "Lighthouse/v0.2.9-",
|
||||
prefix = "Lighthouse/v0.2.10-",
|
||||
fallback = "unknown"
|
||||
);
|
||||
|
||||
|
||||
@@ -745,12 +745,11 @@ where
|
||||
|
||||
/// Returns a `ProtoBlock` if the block is known **and** a descendant of the finalized root.
|
||||
pub fn get_block(&self, block_root: &Hash256) -> Option<ProtoBlock> {
|
||||
self.proto_array.get_block(block_root).filter(|block| {
|
||||
// If available, use the parent_root to perform the lookup since it will involve one
|
||||
// less lookup. This involves making the assumption that the finalized block will
|
||||
// always have `block.parent_root` of `None`.
|
||||
self.is_descendant_of_finalized(block.parent_root.unwrap_or(block.root))
|
||||
})
|
||||
if self.is_descendant_of_finalized(*block_root) {
|
||||
self.proto_array.get_block(block_root)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Return `true` if `block_root` is equal to the finalized root, or a known descendant of it.
|
||||
|
||||
@@ -377,6 +377,26 @@ impl ForkChoiceTest {
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
/// Check to ensure that we can read the finalized block. This is a regression test.
|
||||
pub fn check_finalized_block_is_accessible(self) -> Self {
|
||||
self.harness
|
||||
.chain
|
||||
.fork_choice
|
||||
.write()
|
||||
.get_block(
|
||||
&self
|
||||
.harness
|
||||
.chain
|
||||
.head_info()
|
||||
.unwrap()
|
||||
.finalized_checkpoint
|
||||
.root,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
fn is_safe_to_update(slot: Slot) -> bool {
|
||||
@@ -879,3 +899,11 @@ fn valid_attestation_skip_across_epoch() {
|
||||
|result| result.unwrap(),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn can_read_finalized_block() {
|
||||
ForkChoiceTest::new()
|
||||
.apply_blocks_while(|_, state| state.finalized_checkpoint.epoch == 0)
|
||||
.apply_blocks(1)
|
||||
.check_finalized_block_is_accessible();
|
||||
}
|
||||
|
||||
@@ -450,10 +450,6 @@ pub fn process_deposit<T: EthSpec>(
|
||||
// depositing validator already exists in the registry.
|
||||
state.update_pubkey_cache()?;
|
||||
|
||||
let pubkey: PublicKey = match deposit.data.pubkey.decompress() {
|
||||
Err(_) => return Ok(()), //bad public key => return early
|
||||
Ok(k) => k,
|
||||
};
|
||||
// Get an `Option<u64>` where `u64` is the validator index if this deposit public key
|
||||
// already exists in the beacon_state.
|
||||
let validator_index = get_existing_validator_index(state, &deposit.data.pubkey)
|
||||
@@ -473,7 +469,7 @@ pub fn process_deposit<T: EthSpec>(
|
||||
|
||||
// Create a new validator.
|
||||
let validator = Validator {
|
||||
pubkey: pubkey.into(),
|
||||
pubkey: deposit.data.pubkey.clone(),
|
||||
withdrawal_credentials: deposit.data.withdrawal_credentials,
|
||||
activation_eligibility_epoch: spec.far_future_epoch,
|
||||
activation_epoch: spec.far_future_epoch,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "lcli"
|
||||
description = "Lighthouse CLI (modeled after zcli)"
|
||||
version = "0.2.9"
|
||||
version = "0.2.10"
|
||||
authors = ["Paul Hauner <paul@paulhauner.com>"]
|
||||
edition = "2018"
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "lighthouse"
|
||||
version = "0.2.9"
|
||||
version = "0.2.10"
|
||||
authors = ["Sigma Prime <contact@sigmaprime.io>"]
|
||||
edition = "2018"
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "validator_client"
|
||||
version = "0.2.9"
|
||||
version = "0.2.10"
|
||||
authors = ["Paul Hauner <paul@paulhauner.com>", "Age Manning <Age@AgeManning.com>", "Luke Anderson <luke@lukeanderson.com.au>"]
|
||||
edition = "2018"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user