Connects the attestation service to network components (#961)

* Sends attestations to the attestation service for processing

* Adds 'attnets' field to local ENR

* Adds ENR bitfield modification logic

* Link attestation service to discovery

- Updates discv5
- Links discover events to discovery
- Support for ENRBitfield

* Adds discovery config params, correct warnings

* Rust fmt fixes

* Correct tests
This commit is contained in:
Age Manning
2020-03-25 22:18:06 +11:00
committed by GitHub
parent fbcf0f8e2e
commit 6ca4f4709b
16 changed files with 381 additions and 149 deletions

View File

@@ -3,19 +3,17 @@
//! determines whether attestations should be aggregated and/or passed to the beacon node.
use beacon_chain::{BeaconChain, BeaconChainTypes};
use eth2_libp2p::{types::GossipKind, NetworkGlobals};
use eth2_libp2p::{types::GossipKind, MessageId, NetworkGlobals, PeerId};
use futures::prelude::*;
use hashmap_delay::HashSetDelay;
use rand::seq::SliceRandom;
use rest_types::ValidatorSubscription;
use slog::{crit, debug, error, o, warn};
use slot_clock::SlotClock;
use std::boxed::Box;
use std::collections::VecDeque;
use std::sync::Arc;
use std::time::{Duration, Instant};
use types::{Attestation, SubnetId};
use types::{EthSpec, Slot};
use types::{Attestation, EthSpec, SignedAggregateAndProof, Slot, SubnetId};
/// The minimum number of slots ahead that we attempt to discover peers for a subscription. If the
/// slot is less than this number, skip the peer discovery process.
@@ -44,6 +42,8 @@ pub enum AttServiceMessage {
EnrRemove(SubnetId),
/// Discover peers for a particular subnet.
DiscoverPeers(SubnetId),
/// Propagate an attestation if it's deemed valid.
Propagate(PeerId, MessageId),
}
pub struct AttestationService<T: BeaconChainTypes> {
@@ -152,11 +152,29 @@ impl<T: BeaconChainTypes> AttestationService<T> {
Ok(())
}
pub fn handle_attestation(
/// Handles un-aggregated attestations from the network.
pub fn handle_unaggregated_attestation(
&mut self,
message_id: MessageId,
peer_id: PeerId,
subnet: SubnetId,
attestation: Box<Attestation<T::EthSpec>>,
attestation: Attestation<T::EthSpec>,
) {
// TODO: Handle attestation processing
self.events
.push_back(AttServiceMessage::Propagate(peer_id, message_id));
}
/// Handles aggregate attestations from the network.
pub fn handle_aggregate_attestation(
&mut self,
message_id: MessageId,
peer_id: PeerId,
attestation: SignedAggregateAndProof<T::EthSpec>,
) {
// TODO: Handle attestation processing
self.events
.push_back(AttServiceMessage::Propagate(peer_id, message_id));
}
/* Internal private functions */
@@ -231,6 +249,12 @@ impl<T: BeaconChainTypes> AttestationService<T> {
self.discover_peers
.insert_at((subnet_id, subscription_slot), duration_to_discover);
}
} else {
// TODO: Send the time frame needed to have a peer connected, so that we can
// maintain peers for a least this duration.
// We may want to check the global PeerInfo to see estimated timeouts for each
// peer before they can be removed.
return Err("Not enough time for a discovery search");
}
Ok(())
}

View File

@@ -0,0 +1,55 @@
/// Process a gossip message declaring a new attestation.
///
/// Not currently implemented.
pub fn on_attestation_gossip(&mut self, _peer_id: PeerId, _msg: Attestation<T::EthSpec>) {
// TODO: Handle subnet gossip
/*
match self.chain.process_attestation(msg.clone()) {
Ok(outcome) => match outcome {
AttestationProcessingOutcome::Processed => {
debug!(
self.log,
"Processed attestation";
"source" => "gossip",
"peer" => format!("{:?}",peer_id),
"block_root" => format!("{}", msg.data.beacon_block_root),
"slot" => format!("{}", msg.data.slot),
);
}
AttestationProcessingOutcome::UnknownHeadBlock { beacon_block_root } => {
// TODO: Maintain this attestation and re-process once sync completes
trace!(
self.log,
"Attestation for unknown block";
"peer_id" => format!("{:?}", peer_id),
"block" => format!("{}", beacon_block_root)
);
// we don't know the block, get the sync manager to handle the block lookup
self.send_to_sync(SyncMessage::UnknownBlockHash(peer_id, beacon_block_root));
}
AttestationProcessingOutcome::FutureEpoch { .. }
| AttestationProcessingOutcome::PastEpoch { .. }
| AttestationProcessingOutcome::UnknownTargetRoot { .. }
| AttestationProcessingOutcome::FinalizedSlot { .. } => {} // ignore the attestation
AttestationProcessingOutcome::Invalid { .. }
| AttestationProcessingOutcome::EmptyAggregationBitfield { .. }
| AttestationProcessingOutcome::AttestsToFutureBlock { .. }
| AttestationProcessingOutcome::InvalidSignature
| AttestationProcessingOutcome::NoCommitteeForSlotAndIndex { .. }
| AttestationProcessingOutcome::BadTargetEpoch { .. } => {
// the peer has sent a bad attestation. Remove them.
self.network.disconnect(peer_id, GoodbyeReason::Fault);
}
},
Err(_) => {
// error is logged during the processing therefore no error is logged here
trace!(
self.log,
"Erroneous gossip attestation ssz";
"ssz" => format!("0x{}", hex::encode(msg.as_ssz_bytes())),
);
}
};
*/
}