mirror of
https://github.com/sigp/lighthouse.git
synced 2026-05-07 16:55:46 +00:00
Handle early blocks (#2155)
## Issue Addressed
NA
## Problem this PR addresses
There's an issue where Lighthouse is banning a lot of peers due to the following sequence of events:
1. Gossip block 0xabc arrives ~200ms early
- It is propagated across the network, with respect to [`MAXIMUM_GOSSIP_CLOCK_DISPARITY`](https://github.com/ethereum/eth2.0-specs/blob/v1.0.0/specs/phase0/p2p-interface.md#why-is-there-maximum_gossip_clock_disparity-when-validating-slot-ranges-of-messages-in-gossip-subnets).
- However, it is not imported to our database since the block is early.
2. Attestations for 0xabc arrive, but the block was not imported.
- The peer that sent the attestation is down-voted.
- Each unknown-block attestation causes a score loss of 1, the peer is banned at -100.
- When the peer is on an attestation subnet there can be hundreds of attestations, so the peer is banned quickly (before the missed block can be obtained via rpc).
## Potential solutions
I can think of three solutions to this:
1. Wait for attestation-queuing (#635) to arrive and solve this.
- Easy
- Not immediate fix.
- Whilst this would work, I don't think it's a perfect solution for this particular issue, rather (3) is better.
1. Allow importing blocks with a tolerance of `MAXIMUM_GOSSIP_CLOCK_DISPARITY`.
- Easy
- ~~I have implemented this, for now.~~
1. If a block is verified for gossip propagation (i.e., signature verified) and it's within `MAXIMUM_GOSSIP_CLOCK_DISPARITY`, then queue it to be processed at the start of the appropriate slot.
- More difficult
- Feels like the best solution, I will try to implement this.
**This PR takes approach (3).**
## Changes included
- Implement the `block_delay_queue`, based upon a [`DelayQueue`](https://docs.rs/tokio-util/0.6.3/tokio_util/time/delay_queue/struct.DelayQueue.html) which can store blocks until it's time to import them.
- Add a new `DelayedImportBlock` variant to the `beacon_processor::WorkEvent` enum to handle this new event.
- In the `BeaconProcessor`, refactor a `tokio::select!` to a struct with an explicit `Stream` implementation. I experienced some issues with `tokio::select!` in the block delay queue and I also found it hard to debug. I think this explicit implementation is nicer and functionally equivalent (apart from the fact that `tokio::select!` randomly chooses futures to poll, whereas now we're deterministic).
- Add a testing framework to the `beacon_processor` module that tests this new block delay logic. I also tested a handful of other operations in the beacon processor (attns, slashings, exits) since it was super easy to copy-pasta the code from the `http_api` tester.
- To implement these tests I added the concept of an optional `work_journal_tx` to the `BeaconProcessor` which will spit out a log of events. I used this in the tests to ensure that things were happening as I expect.
- The tests are a little racey, but it's hard to avoid that when testing timing-based code. If we see CI failures I can revise. I haven't observed *any* failures due to races on my machine or on CI yet.
- To assist with testing I allowed for directly setting the time on the `ManualSlotClock`.
- I gave the `beacon_processor::Worker` a `Toolbox` for two reasons; (a) it avoids changing tons of function sigs when you want to pass a new object to the worker and (b) it seemed cute.
This commit is contained in:
53
Cargo.lock
generated
53
Cargo.lock
generated
@@ -1607,6 +1607,38 @@ version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0"
|
||||
|
||||
[[package]]
|
||||
name = "discv5"
|
||||
version = "0.1.0-beta.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f6f52d2228d51e8f868a37d5b5b25b82c13552b635d5b47c3a5d53855a6fc4f0"
|
||||
dependencies = [
|
||||
"aes-ctr",
|
||||
"aes-gcm 0.8.0",
|
||||
"arrayvec",
|
||||
"digest 0.9.0",
|
||||
"enr",
|
||||
"fnv",
|
||||
"futures 0.3.12",
|
||||
"hex",
|
||||
"hkdf",
|
||||
"k256",
|
||||
"lazy_static",
|
||||
"lru_time_cache",
|
||||
"parking_lot",
|
||||
"rand 0.7.3",
|
||||
"rlp 0.5.0",
|
||||
"sha2 0.9.2",
|
||||
"smallvec",
|
||||
"tokio 1.1.0",
|
||||
"tokio-stream",
|
||||
"tokio-util 0.6.3",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
"uint",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "discv5"
|
||||
version = "0.1.0-beta.3"
|
||||
@@ -1775,9 +1807,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "env_logger"
|
||||
version = "0.8.2"
|
||||
version = "0.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f26ecb66b4bdca6c1409b40fb255eefc2bd4f6d135dab3c3124f80ffa2a9661e"
|
||||
checksum = "17392a012ea30ef05a610aa97dfb49496e71c9f676b27879922ea5bdf60d9d3f"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"humantime",
|
||||
@@ -1966,7 +1998,7 @@ dependencies = [
|
||||
"base64 0.13.0",
|
||||
"directory",
|
||||
"dirs 3.0.1",
|
||||
"discv5",
|
||||
"discv5 0.1.0-beta.3 (git+https://github.com/sigp/discv5?rev=02d2c896c66f8dc2b848c3996fedcd98e1dfec69)",
|
||||
"error-chain",
|
||||
"eth2_ssz",
|
||||
"eth2_ssz_derive",
|
||||
@@ -2797,7 +2829,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"beacon_chain",
|
||||
"bs58 0.4.0",
|
||||
"discv5",
|
||||
"discv5 0.1.0-beta.3 (git+https://github.com/sigp/discv5?rev=02d2c896c66f8dc2b848c3996fedcd98e1dfec69)",
|
||||
"environment",
|
||||
"eth1",
|
||||
"eth2",
|
||||
@@ -3657,7 +3689,7 @@ dependencies = [
|
||||
"clap",
|
||||
"clap_utils",
|
||||
"directory",
|
||||
"env_logger 0.8.2",
|
||||
"env_logger 0.8.3",
|
||||
"environment",
|
||||
"eth2_network_config",
|
||||
"futures 0.3.12",
|
||||
@@ -4069,6 +4101,8 @@ name = "network"
|
||||
version = "0.2.0"
|
||||
dependencies = [
|
||||
"beacon_chain",
|
||||
"discv5 0.1.0-beta.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"environment",
|
||||
"error-chain",
|
||||
"eth2_libp2p",
|
||||
"eth2_ssz",
|
||||
@@ -4104,6 +4138,7 @@ dependencies = [
|
||||
"tempfile",
|
||||
"tokio 1.1.0",
|
||||
"tokio-stream",
|
||||
"tokio-util 0.6.3",
|
||||
"tree_hash",
|
||||
"types",
|
||||
]
|
||||
@@ -5651,7 +5686,7 @@ name = "simulator"
|
||||
version = "0.2.0"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"env_logger 0.8.2",
|
||||
"env_logger 0.8.3",
|
||||
"eth1",
|
||||
"eth1_test_rig",
|
||||
"futures 0.3.12",
|
||||
@@ -5942,7 +5977,7 @@ dependencies = [
|
||||
"arbitrary",
|
||||
"bls",
|
||||
"criterion",
|
||||
"env_logger 0.8.2",
|
||||
"env_logger 0.8.3",
|
||||
"eth2_hashing",
|
||||
"eth2_ssz",
|
||||
"eth2_ssz_types",
|
||||
@@ -6509,9 +6544,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tokio-stream"
|
||||
version = "0.1.2"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "76066865172052eb8796c686f0b441a93df8b08d40a950b062ffb9a426f00edd"
|
||||
checksum = "1981ad97df782ab506a1f43bf82c967326960d278acf3bf8279809648c3ff3ea"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"pin-project-lite 0.2.4",
|
||||
|
||||
Reference in New Issue
Block a user