lighthouse/common
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
..
account_utils Prevent adding duplicate validators to validator_definitions.yml (#2166) 2021-02-15 06:09:51 +00:00
clap_utils fix default network handling (#2029) 2020-12-08 05:41:10 +00:00
compare_fields Check for unused deps in CI (#1262) 2020-06-14 10:59:50 +10:00
compare_fields_derive Update external deps (#1711) 2020-10-05 08:22:19 +00:00
deposit_contract Update to tokio 1.1 (#2172) 2021-02-10 23:29:49 +00:00
directory fix default network handling (#2029) 2020-12-08 05:41:10 +00:00
eth2 Update to tokio 1.1 (#2172) 2021-02-10 23:29:49 +00:00
eth2_config Represent slots in secs instead of millisecs (#2163) 2021-01-19 09:39:51 +00:00
eth2_interop_keypairs Fix new clippy lints (#2036) 2020-12-03 01:10:26 +00:00
eth2_network_config Update bootnode ENRs (#2191) 2021-02-15 06:09:52 +00:00
eth2_wallet_manager Use OS file locks in validator client (#1958) 2020-11-26 11:25:46 +00:00
fallback Fallback nodes for eth1 access (#1918) 2020-11-27 08:37:44 +00:00
hashset_delay Update to tokio 1.1 (#2172) 2021-02-10 23:29:49 +00:00
lighthouse_metrics Add metrics for beacon block propagation (#2173) 2021-02-04 05:33:56 +00:00
lighthouse_version Fix lighthouse_version (#2221) 2021-02-23 23:31:37 +00:00
lockfile Fix clippy errors on tests (#2160) 2021-01-28 23:31:06 +00:00
logging Update external deps (#1711) 2020-10-05 08:22:19 +00:00
lru_cache Keep track of failed head chains and prevent re-lookups (#1534) 2020-08-18 03:54:09 +00:00
remote_signer_consumer Update to tokio 1.1 (#2172) 2021-02-10 23:29:49 +00:00
rest_types Update to tokio 1.1 (#2172) 2021-02-10 23:29:49 +00:00
slot_clock Handle early blocks (#2155) 2021-02-24 03:08:52 +00:00
task_executor Update to tokio 1.1 (#2172) 2021-02-10 23:29:49 +00:00
test_random_derive Update external deps (#1711) 2020-10-05 08:22:19 +00:00
validator_dir Fix new clippy lints (#2036) 2020-12-03 01:10:26 +00:00
warp_utils Switch back to warp with cors wildcard support (#2211) 2021-02-18 22:33:12 +00:00
README.md Directory Restructure (#1163) 2020-05-18 21:24:23 +10:00

eth2

Common crates containing eth2-specific logic.