Altair consensus changes and refactors (#2279)

## Proposed Changes

Implement the consensus changes necessary for the upcoming Altair hard fork.

## Additional Info

This is quite a heavy refactor, with pivotal types like the `BeaconState` and `BeaconBlock` changing from structs to enums. This ripples through the whole codebase with field accesses changing to methods, e.g. `state.slot` => `state.slot()`.


Co-authored-by: realbigsean <seananderson33@gmail.com>
This commit is contained in:
Michael Sproul
2021-07-09 06:15:32 +00:00
parent 89361573d4
commit b4689e20c6
271 changed files with 9652 additions and 8444 deletions

View File

@@ -43,7 +43,7 @@ lazy_static = "1.4.0"
lighthouse_metrics = { path = "../../common/lighthouse_metrics" }
task_executor = { path = "../../common/task_executor" }
igd = "0.11.1"
itertools = "0.9.0"
itertools = "0.10.0"
num_cpus = "1.13.0"
lru_cache = { path = "../../common/lru_cache" }
if-addrs = "0.6.4"

View File

@@ -3,10 +3,10 @@
use crate::beacon_processor::*;
use crate::{service::NetworkMessage, sync::SyncMessage};
use beacon_chain::{
test_utils::{AttestationStrategy, BeaconChainHarness, BlockStrategy, EphemeralHarnessType},
BeaconChain, MAXIMUM_GOSSIP_CLOCK_DISPARITY,
use beacon_chain::test_utils::{
AttestationStrategy, BeaconChainHarness, BlockStrategy, EphemeralHarnessType,
};
use beacon_chain::{BeaconChain, MAXIMUM_GOSSIP_CLOCK_DISPARITY};
use discv5::enr::{CombinedKey, EnrBuilder};
use environment::{null_logger, Environment, EnvironmentBuilder};
use eth2_libp2p::{rpc::methods::MetaData, types::EnrBitfield, MessageId, NetworkGlobals, PeerId};
@@ -66,6 +66,7 @@ impl TestRig {
pub fn new(chain_length: u64) -> Self {
let mut harness = BeaconChainHarness::new(
MainnetEthSpec,
None,
generate_deterministic_keypairs(VALIDATOR_COUNT),
);

View File

@@ -244,7 +244,7 @@ impl<T: BeaconChainTypes> Worker<T> {
// Log metrics to track delay from other nodes on the network.
metrics::observe_duration(
&metrics::BEACON_BLOCK_GOSSIP_SLOT_START_DELAY_TIME,
get_block_delay_ms(seen_duration, &block.message, &self.chain.slot_clock),
get_block_delay_ms(seen_duration, block.message(), &self.chain.slot_clock),
);
let verified_block = match self.chain.verify_block_for_gossip(block) {
@@ -305,6 +305,7 @@ impl<T: BeaconChainTypes> Worker<T> {
| Err(e @ BlockError::InvalidSignature)
| Err(e @ BlockError::TooManySkippedSlots { .. })
| Err(e @ BlockError::WeakSubjectivityConflict)
| Err(e @ BlockError::InconsistentFork(_))
| Err(e @ BlockError::GenesisBlock) => {
warn!(self.log, "Could not verify block for gossip, rejecting the block";
"error" => %e);
@@ -322,7 +323,7 @@ impl<T: BeaconChainTypes> Worker<T> {
// verified.
self.chain.validator_monitor.read().register_gossip_block(
seen_duration,
&verified_block.block.message,
verified_block.block.message(),
verified_block.block_root,
&self.chain.slot_clock,
);

View File

@@ -57,8 +57,8 @@ impl<T: BeaconChainTypes> Worker<T> {
match process_id {
// this a request from the range sync
ProcessId::RangeBatchId(chain_id, epoch) => {
let start_slot = downloaded_blocks.first().map(|b| b.message.slot.as_u64());
let end_slot = downloaded_blocks.last().map(|b| b.message.slot.as_u64());
let start_slot = downloaded_blocks.first().map(|b| b.slot().as_u64());
let end_slot = downloaded_blocks.last().map(|b| b.slot().as_u64());
let sent_blocks = downloaded_blocks.len();
let result = match self.process_blocks(downloaded_blocks.iter()) {

View File

@@ -277,7 +277,7 @@ fn spawn_service<T: BeaconChainTypes>(
.map(|current_epoch| {
head
.beacon_state
.validators
.validators()
.iter()
.filter(|validator|
validator.is_active_at(current_epoch)

View File

@@ -38,6 +38,7 @@ mod tests {
let beacon_chain = Arc::new(
BeaconChainHarness::new_with_store_config(
MinimalEthSpec,
None,
generate_deterministic_keypairs(8),
StoreConfig::default(),
)

View File

@@ -331,8 +331,13 @@ impl<T: BeaconChainTypes> SyncManager<T> {
// check if the parent of this block isn't in our failed cache. If it is, this
// chain should be dropped and the peer downscored.
if self.failed_chains.contains(&block.message.parent_root) {
debug!(self.log, "Parent chain ignored due to past failure"; "block" => ?block.message.parent_root, "slot" => block.message.slot);
if self.failed_chains.contains(&block.message().parent_root()) {
debug!(
self.log,
"Parent chain ignored due to past failure";
"block" => ?block.message().parent_root(),
"slot" => block.slot()
);
if !parent_request.downloaded_blocks.is_empty() {
// Add the root block to failed chains
self.failed_chains
@@ -490,7 +495,7 @@ impl<T: BeaconChainTypes> SyncManager<T> {
.head_info()
.map(|info| info.slot)
.unwrap_or_else(|_| Slot::from(0u64));
let unknown_block_slot = block.message.slot;
let unknown_block_slot = block.slot();
// if the block is far in the future, ignore it. If its within the slot tolerance of
// our current head, regardless of the syncing state, fetch it.
@@ -505,10 +510,10 @@ impl<T: BeaconChainTypes> SyncManager<T> {
let block_root = block.canonical_root();
// If this block or it's parent is part of a known failed chain, ignore it.
if self.failed_chains.contains(&block.message.parent_root)
if self.failed_chains.contains(&block.message().parent_root())
|| self.failed_chains.contains(&block_root)
{
debug!(self.log, "Block is from a past failed chain. Dropping"; "block_root" => ?block_root, "block_slot" => block.message.slot);
debug!(self.log, "Block is from a past failed chain. Dropping"; "block_root" => ?block_root, "block_slot" => block.slot());
return;
}
@@ -525,7 +530,7 @@ impl<T: BeaconChainTypes> SyncManager<T> {
}
}
debug!(self.log, "Unknown block received. Starting a parent lookup"; "block_slot" => block.message.slot, "block_hash" => %block.canonical_root());
debug!(self.log, "Unknown block received. Starting a parent lookup"; "block_slot" => block.slot(), "block_hash" => %block.canonical_root());
let parent_request = ParentRequests {
downloaded_blocks: vec![block],