Add basic Gossip sync handlers

This commit is contained in:
Paul Hauner 2019-03-25 14:27:20 +11:00
parent 267477ffc2
commit 708d9b5674
No known key found for this signature in database
GPG Key ID: D362883A9218FCC6
7 changed files with 119 additions and 8 deletions

View File

@ -8,6 +8,7 @@ pub mod test_utils;
pub use self::beacon_chain::{BeaconChain, BlockProcessingOutcome, InvalidBlock, ValidBlock}; pub use self::beacon_chain::{BeaconChain, BlockProcessingOutcome, InvalidBlock, ValidBlock};
pub use self::checkpoint::CheckPoint; pub use self::checkpoint::CheckPoint;
pub use self::errors::BeaconChainError; pub use self::errors::BeaconChainError;
pub use attestation_aggregator::Outcome as AggregationOutcome;
pub use db; pub use db;
pub use fork_choice; pub use fork_choice;
pub use parking_lot; pub use parking_lot;

View File

@ -1,7 +1,7 @@
use ssz::{Decodable, DecodeError, Encodable, SszStream}; use ssz::{Decodable, DecodeError, Encodable, SszStream};
/// Available RPC methods types and ids. /// Available RPC methods types and ids.
use ssz_derive::{Decode, Encode}; use ssz_derive::{Decode, Encode};
use types::{BeaconBlockBody, BeaconBlockHeader, Epoch, Hash256, Slot}; use types::{Attestation, BeaconBlockBody, BeaconBlockHeader, Epoch, Hash256, Slot};
#[derive(Debug)] #[derive(Debug)]
/// Available Serenity Libp2p RPC methods /// Available Serenity Libp2p RPC methods
@ -97,6 +97,12 @@ impl RPCResponse {
} }
} }
#[derive(Debug, Clone)]
pub enum IncomingGossip {
Block(BlockGossip),
Attestation(AttestationGossip),
}
/* Request/Response data structures for RPC methods */ /* Request/Response data structures for RPC methods */
/// The HELLO request/response handshake message. /// The HELLO request/response handshake message.
@ -236,3 +242,15 @@ pub struct BeaconChainStateResponse {
/// The values corresponding the to the requested tree hashes. /// The values corresponding the to the requested tree hashes.
pub values: bool, //TBD - stubbed with encodeable bool pub values: bool, //TBD - stubbed with encodeable bool
} }
/// Gossipsub message providing notification of a new block.
#[derive(Encode, Decode, Clone, Debug, PartialEq)]
pub struct BlockGossip {
pub root: BlockRootSlot,
}
/// Gossipsub message providing notification of a new attestation.
#[derive(Encode, Decode, Clone, Debug, PartialEq)]
pub struct AttestationGossip {
pub attestation: Attestation,
}

View File

@ -11,7 +11,7 @@ use libp2p::core::swarm::{
ConnectedPoint, NetworkBehaviour, NetworkBehaviourAction, PollParameters, ConnectedPoint, NetworkBehaviour, NetworkBehaviourAction, PollParameters,
}; };
use libp2p::{Multiaddr, PeerId}; use libp2p::{Multiaddr, PeerId};
pub use methods::{HelloMessage, RPCMethod, RPCRequest, RPCResponse}; pub use methods::{HelloMessage, IncomingGossip, RPCMethod, RPCRequest, RPCResponse};
pub use protocol::{RPCEvent, RPCProtocol}; pub use protocol::{RPCEvent, RPCProtocol};
use slog::o; use slog::o;
use std::marker::PhantomData; use std::marker::PhantomData;

View File

@ -5,10 +5,10 @@ use beacon_chain::{
parking_lot::RwLockReadGuard, parking_lot::RwLockReadGuard,
slot_clock::SlotClock, slot_clock::SlotClock,
types::{BeaconState, ChainSpec}, types::{BeaconState, ChainSpec},
CheckPoint, AggregationOutcome, CheckPoint,
}; };
use eth2_libp2p::HelloMessage; use eth2_libp2p::HelloMessage;
use types::{BeaconBlock, BeaconBlockBody, BeaconBlockHeader, Epoch, Hash256, Slot}; use types::{Attestation, BeaconBlock, BeaconBlockBody, BeaconBlockHeader, Epoch, Hash256, Slot};
pub use beacon_chain::{BeaconChainError, BlockProcessingOutcome}; pub use beacon_chain::{BeaconChainError, BlockProcessingOutcome};
@ -37,6 +37,11 @@ pub trait BeaconChain: Send + Sync {
fn process_block(&self, block: BeaconBlock) fn process_block(&self, block: BeaconBlock)
-> Result<BlockProcessingOutcome, BeaconChainError>; -> Result<BlockProcessingOutcome, BeaconChainError>;
fn process_attestation(
&self,
attestation: Attestation,
) -> Result<AggregationOutcome, BeaconChainError>;
fn get_block_roots( fn get_block_roots(
&self, &self,
start_slot: Slot, start_slot: Slot,
@ -119,6 +124,18 @@ where
self.process_block(block) self.process_block(block)
} }
fn process_attestation(
&self,
_attestation: Attestation,
) -> Result<AggregationOutcome, BeaconChainError> {
// Awaiting a proper operations pool before we can import attestations.
//
// Returning a useless error for now.
//
// https://github.com/sigp/lighthouse/issues/281
return Err(BeaconChainError::DBInconsistent("CANNOT PROCESS".into()));
}
fn get_block_roots( fn get_block_roots(
&self, &self,
start_slot: Slot, start_slot: Slot,

View File

@ -4,7 +4,7 @@ use crate::service::{NetworkMessage, OutgoingMessage};
use crate::sync::SimpleSync; use crate::sync::SimpleSync;
use crossbeam_channel::{unbounded as channel, Sender}; use crossbeam_channel::{unbounded as channel, Sender};
use eth2_libp2p::{ use eth2_libp2p::{
rpc::{RPCRequest, RPCResponse}, rpc::{IncomingGossip, RPCRequest, RPCResponse},
PeerId, RPCEvent, PeerId, RPCEvent,
}; };
use futures::future; use futures::future;
@ -39,8 +39,8 @@ pub enum HandlerMessage {
PeerDisconnected(PeerId), PeerDisconnected(PeerId),
/// An RPC response/request has been received. /// An RPC response/request has been received.
RPC(PeerId, RPCEvent), RPC(PeerId, RPCEvent),
/// A block has been imported. /// A gossip message has been received.
BlockImported(), //TODO: This comes from pub-sub - decide its contents IncomingGossip(PeerId, IncomingGossip),
} }
impl MessageHandler { impl MessageHandler {
@ -90,6 +90,10 @@ impl MessageHandler {
HandlerMessage::RPC(peer_id, rpc_event) => { HandlerMessage::RPC(peer_id, rpc_event) => {
self.handle_rpc_message(peer_id, rpc_event); self.handle_rpc_message(peer_id, rpc_event);
} }
// we have received an RPC message request/response
HandlerMessage::IncomingGossip(peer_id, gossip) => {
self.handle_gossip(peer_id, gossip);
}
//TODO: Handle all messages //TODO: Handle all messages
_ => {} _ => {}
} }
@ -186,6 +190,19 @@ impl MessageHandler {
} }
}; };
} }
/// Handle RPC messages
fn handle_gossip(&mut self, peer_id: PeerId, gossip_message: IncomingGossip) {
match gossip_message {
IncomingGossip::Block(message) => {
self.sync
.on_block_gossip(peer_id, message, &mut self.network_context)
}
IncomingGossip::Attestation(message) => {
//
}
}
}
} }
pub struct NetworkContext { pub struct NetworkContext {

View File

@ -104,7 +104,7 @@ impl ImportQueue {
} }
/// Returns `true` if `self.chain` has not yet processed this block. /// Returns `true` if `self.chain` has not yet processed this block.
fn is_new_block(&self, block_root: &Hash256) -> bool { pub fn is_new_block(&self, block_root: &Hash256) -> bool {
self.chain self.chain
.is_new_block_root(&block_root) .is_new_block_root(&block_root)
.unwrap_or_else(|_| { .unwrap_or_else(|_| {

View File

@ -204,6 +204,8 @@ impl SimpleSync {
self.known_peers.insert(peer_id.clone(), remote); self.known_peers.insert(peer_id.clone(), remote);
} }
// TODO: boot peer if finalization is wrong.
match remote_status { match remote_status {
PeerStatus::OnDifferentChain => { PeerStatus::OnDifferentChain => {
info!( info!(
@ -462,6 +464,62 @@ impl SimpleSync {
self.process_import_queue(network); self.process_import_queue(network);
} }
/// Process a gossip message declaring a new block.
pub fn on_block_gossip(
&mut self,
peer_id: PeerId,
msg: BlockGossip,
network: &mut NetworkContext,
) {
debug!(
self.log,
"BlockGossip";
"peer" => format!("{:?}", peer_id),
);
// TODO: filter out messages that a prior to the finalized slot.
//
// TODO: if the block is a few more slots ahead, try to get all block roots from then until
// now.
//
// Note: only requests the new block -- will fail if we don't have its parents.
if self.import_queue.is_new_block(&msg.root.block_root) {
self.request_block_headers(
peer_id,
BeaconBlockHeadersRequest {
start_root: msg.root.block_root,
start_slot: msg.root.slot,
max_headers: 1,
skip_slots: 0,
},
network,
)
}
}
/// Process a gossip message declaring a new attestation.
///
/// Not currently implemented.
pub fn on_attestation_gossip(
&mut self,
peer_id: PeerId,
msg: AttestationGossip,
_network: &mut NetworkContext,
) {
debug!(
self.log,
"AttestationGossip";
"peer" => format!("{:?}", peer_id),
);
// Awaiting a proper operations pool before we can import attestations.
//
// https://github.com/sigp/lighthouse/issues/281
match self.chain.process_attestation(msg.attestation) {
Ok(_) => panic!("Impossible, method not implemented."),
Err(_) => error!(self.log, "Attestation processing not implemented!"),
}
}
/// Iterate through the `import_queue` and process any complete blocks. /// Iterate through the `import_queue` and process any complete blocks.
/// ///
/// If a block is successfully processed it is removed from the queue, otherwise it remains in /// If a block is successfully processed it is removed from the queue, otherwise it remains in