lighthouse/beacon_node/beacon_chain/src
Paul Hauner a764c3b247 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.
2021-02-24 03:08:52 +00:00
..
attestation_verification.rs Detailed validator monitoring (#2151) 2021-01-20 19:19:38 +00:00
beacon_chain.rs Advance state to next slot after importing block (#2174) 2021-02-15 07:17:52 +00:00
beacon_fork_choice_store.rs Advance state to next slot after importing block (#2174) 2021-02-15 07:17:52 +00:00
beacon_proposer_cache.rs Advance state to next slot after importing block (#2174) 2021-02-15 07:17:52 +00:00
beacon_snapshot.rs Advance state to next slot after importing block (#2174) 2021-02-15 07:17:52 +00:00
block_verification.rs Handle early blocks (#2155) 2021-02-24 03:08:52 +00:00
builder.rs Advance state to next slot after importing block (#2174) 2021-02-15 07:17:52 +00:00
chain_config.rs Implement database temp states to reduce memory usage (#1798) 2020-10-23 01:27:51 +00:00
errors.rs Advance state to next slot after importing block (#2174) 2021-02-15 07:17:52 +00:00
eth1_chain.rs Fix clippy errors on tests (#2160) 2021-01-28 23:31:06 +00:00
events.rs Server sent events (#1920) 2020-12-04 00:18:58 +00:00
head_tracker.rs Clippy 1.49.0 updates and dht persistence test fix (#2156) 2021-01-19 00:34:28 +00:00
lib.rs Handle early blocks (#2155) 2021-02-24 03:08:52 +00:00
metrics.rs Advance state to next slot after importing block (#2174) 2021-02-15 07:17:52 +00:00
migrate.rs Address queue congestion in migrator (#1923) 2020-11-17 23:11:26 +00:00
naive_aggregation_pool.rs Handle early blocks (#2155) 2021-02-24 03:08:52 +00:00
observed_attestations.rs Fix new clippy lints (#2036) 2020-12-03 01:10:26 +00:00
observed_attesters.rs Fix race condition in seen caches (#1937) 2020-11-22 23:02:51 +00:00
observed_block_producers.rs Fix race condition in seen caches (#1937) 2020-11-22 23:02:51 +00:00
observed_operations.rs Clippy 1.49.0 updates and dht persistence test fix (#2156) 2021-01-19 00:34:28 +00:00
persisted_beacon_chain.rs Fix head tracker concurrency bugs (#1771) 2020-10-19 05:58:39 +00:00
persisted_fork_choice.rs v0.12 fork choice update (#1229) 2020-06-17 11:10:22 +10:00
shuffling_cache.rs Advance state to next slot after importing block (#2174) 2021-02-15 07:17:52 +00:00
snapshot_cache.rs Handle early blocks (#2155) 2021-02-24 03:08:52 +00:00
state_advance_timer.rs Fix false positive "State advance too slow" logs (#2218) 2021-02-21 23:47:53 +00:00
test_utils.rs Upgrade rand_core (#2201) 2021-02-15 20:34:49 +00:00
timeout_rw_lock.rs Add timeouts to canonical head rwlock (#759) 2020-01-06 17:30:37 +11:00
validator_monitor.rs Advance state to next slot after importing block (#2174) 2021-02-15 07:17:52 +00:00
validator_pubkey_cache.rs Fix clippy errors on tests (#2160) 2021-01-28 23:31:06 +00:00