Compare commits

..

13 Commits

Author SHA1 Message Date
Paul Hauner
371e1c1d5d Bump version to v0.2.10 (#1630)
## Issue Addressed

NA

## Proposed Changes

Bump crate version so we can cut a new release with the fix from #1629.

## Additional Info

NA
2020-09-18 06:41:29 +00:00
Paul Hauner
a17f74896a Fix bad assumption when checking finalized descendant (#1629)
## Issue Addressed

- Resolves #1616

## Proposed Changes

Fixes a bug where we are unable to read the finalized block from fork choice.

## Detail

I had made an assumption that the finalized block always has a parent root of `None`:

e5fc6bab48/consensus/fork_choice/src/fork_choice.rs (L749-L752)

This was a faulty assumption, we don't set parent *roots* to `None`. Instead we *sometimes* set parent *indices* to `None`, depending if this pruning condition is satisfied: 

e5fc6bab48/consensus/proto_array/src/proto_array.rs (L229-L232) 

The bug manifested itself like this:

1. We attempt to get the finalized block from fork choice
1. We try to check that the block is descendant of the finalized block (note: they're the same block).
1. We expect the parent root to be `None`, but it's actually the parent root of the finalized root.
1. We therefore end up checking if the parent of the finalized root is a descendant of itself. (note: it's an *ancestor* not a *descendant*).
1. We therefore declare that the finalized block is not a descendant of (or eq to) the finalized block. Bad.

## Additional Info

In reflection, I made a poor assumption in the quest to obtain a probably negligible performance gain. The performance gain wasn't worth the risk and we got burnt.
2020-09-18 05:14:31 +00:00
Age Manning
49ab414594 Shift gossipsub validation (#1612)
## Issue Addressed

N/A

## Proposed Changes

This will consider all gossipsub messages that have either the `from`, `seqno` or `signature` field as invalid. 

## Additional Info

We should not merge this until all other clients have been sending empty fields for a while.

See https://github.com/ethereum/eth2.0-specs/issues/1981 for reference
2020-09-18 02:05:36 +00:00
Age Manning
2074beccdc Gossipsub message id to shortened bytes (#1607)
## Issue Addressed

https://github.com/ethereum/eth2.0-specs/pull/2044

## Proposed Changes

Shifts the gossipsub message id to use the first 8 bytes of the SHA256 hash of the gossipsub message data field.

## Additional Info

We should merge this in once the spec has been decided on. It will cause issues with gossipsub scoring and gossipsub propagation rates (as we won't receive IWANT) messages from clients that also haven't made this update.
2020-09-18 02:05:34 +00:00
Michael Sproul
e5fc6bab48 Remove redundant decompression in process_deposit (#1610)
## Issue Addressed

Closes #1076

## Proposed Changes

Remove an extra unnecessary decompression of the deposit public key from `process_deposit`. The key is decompressed and used to verify the signature in `verify_deposit_signature`, making this initial decompression redundant.

## Additional Info

This is _not_ a consensus-breaking change because keys which previously failed the early decompression check will not be found in the pubkey cache (they are invalid), and will be checked and rejected as part of `verify_deposit_signature`.
2020-09-14 10:58:15 +00:00
Age Manning
c9596fcf0e Temporary Sync Work-Around (#1615)
## Issue Addressed

#1590 

## Proposed Changes

This is a temporary workaround that prevents finalized chain sync from swapping chains. I'm merging this in now until the full solution is ready.
2020-09-13 23:58:49 +00:00
Age Manning
c6abc56113 Prevent large step-size parameters (#1583)
## Issue Addressed

Malicious users could request very large block ranges, more than we expect. Although technically legal, we are now quadraticaly weighting large step sizes in the filter. Therefore users may request large skips, but not a large number of blocks, to prevent requests forcing us to do long chain lookups. 

## Proposed Changes

Weight the step parameter in the RPC filter and prevent any overflows that effect us in the step parameter.

## Additional Info
2020-09-11 02:33:36 +00:00
blacktemplar
7f1b936905 ignore too early / too late attestations instead of penalizing them (#1608)
## Issue Addressed

NA

## Proposed Changes

This ignores attestations that are too early or too late as it is specified in the spec (see https://github.com/ethereum/eth2.0-specs/blob/v0.12.1/specs/phase0/p2p-interface.md#global-topics first subpoint of `beacon_aggregate_and_proof`)
2020-09-11 01:43:15 +00:00
Daniel Schonfeld
810de2f8b7 Static testnet configs (#1603)
## Issue Addressed

#1431 

## Proposed Changes

Added an archived zip file with required files manually

## Additional Info

1) Used zip, instead of tar.gz to add a single dependency instead of two.
2) I left the download from github code for now, waiting to hear if you'd like it cleaned up or left to be used for some tooling needs.
2020-09-11 01:43:13 +00:00
Pawan Dhananjay
0525876882 Dial cached enr's before making subnet discovery query (#1376)
## Issue Addressed

Closes #1365 

## Proposed Changes

Dial peers in the `cached_enrs` who aren't connected, aren't banned and satisfy the subnet predicate before making a subnet discovery query.
2020-09-11 00:52:27 +00:00
Age Manning
d79366c503 Prevent printing binary in RPC errors (#1604)
## Issue Addressed

#1566 

## Proposed Changes

Prevents printing binary characters in the RPC error response from peers.
2020-09-10 04:43:22 +00:00
Age Manning
b19cf02d2d Penalise bad peer behaviour (#1602)
## Issue Addressed

#1386 

## Proposed Changes

Penalises peers in our scoring system that produce invalid attestations or blocks.
2020-09-10 03:51:06 +00:00
Paul Hauner
dfe507715d Remove references to rust-docs (#1601)
## Issue Addressed

- Resolves #897
- Resolves #821

## Proposed Changes

Removes references to the rust docs that we're no long maintaining.

## Additional Info

NA
2020-09-10 00:24:41 +00:00
29 changed files with 397 additions and 272 deletions

191
Cargo.lock generated
View File

@@ -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",
]

View File

@@ -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).

View File

@@ -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"

View File

@@ -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"

View File

@@ -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.

View File

@@ -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"

View File

@@ -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)

View File

@@ -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,

View File

@@ -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

View File

@@ -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()
}
}

View File

@@ -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() {

View File

@@ -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);
}
}

View File

@@ -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 {

View File

@@ -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

View File

@@ -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

View File

@@ -1,6 +1,6 @@
[package]
name = "boot_node"
version = "0.2.9"
version = "0.2.10"
authors = ["Sigma Prime <contact@sigmaprime.io>"]
edition = "2018"

View File

@@ -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
);

View File

@@ -1,4 +1,4 @@
testnet*
testnet*/*
schlesi-*
witti-*
altona*

View File

@@ -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"}

View File

@@ -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(())
}

View File

@@ -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"
);

View File

@@ -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.

View File

@@ -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();
}

View File

@@ -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,

View File

@@ -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"

View File

@@ -1,6 +1,6 @@
[package]
name = "lighthouse"
version = "0.2.9"
version = "0.2.10"
authors = ["Sigma Prime <contact@sigmaprime.io>"]
edition = "2018"

View File

@@ -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"