mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-03 00:31:50 +00:00
Updates to latest interop branch.
- Shifts decoding of objects into message handler. - Updates to latest interop gossipsub. - Adds interop spec constant.
This commit is contained in:
@@ -7,8 +7,8 @@ edition = "2018"
|
||||
[dependencies]
|
||||
clap = "2.32.0"
|
||||
#SigP repository
|
||||
libp2p = { git = "https://github.com/SigP/rust-libp2p", rev = "35104cca27231b9178e1fea5b3788ea41ba8af76" }
|
||||
enr = { git = "https://github.com/SigP/rust-libp2p/", rev = "35104cca27231b9178e1fea5b3788ea41ba8af76", features = ["serde"] }
|
||||
libp2p = { git = "https://github.com/SigP/rust-libp2p", rev = "b0d3cf7b4b0fa6c555b64dbdd110673a05457abd" }
|
||||
enr = { git = "https://github.com/SigP/rust-libp2p/", rev = "b0d3cf7b4b0fa6c555b64dbdd110673a05457abd", features = ["serde"] }
|
||||
types = { path = "../../eth2/types" }
|
||||
serde = "1.0"
|
||||
serde_derive = "1.0"
|
||||
|
||||
@@ -2,6 +2,7 @@ use crate::discovery::Discovery;
|
||||
use crate::rpc::{RPCEvent, RPCMessage, RPC};
|
||||
use crate::{error, NetworkConfig};
|
||||
use crate::{Topic, TopicHash};
|
||||
use crate::{BEACON_ATTESTATION_TOPIC, BEACON_BLOCK_TOPIC};
|
||||
use futures::prelude::*;
|
||||
use libp2p::{
|
||||
core::identity::Keypair,
|
||||
@@ -13,11 +14,10 @@ use libp2p::{
|
||||
tokio_io::{AsyncRead, AsyncWrite},
|
||||
NetworkBehaviour, PeerId,
|
||||
};
|
||||
use slog::{debug, o, trace, warn};
|
||||
use ssz::{ssz_encode, Decode, DecodeError, Encode};
|
||||
use slog::{debug, o, trace};
|
||||
use ssz::{ssz_encode, Encode};
|
||||
use std::num::NonZeroU32;
|
||||
use std::time::Duration;
|
||||
use types::{Attestation, BeaconBlock};
|
||||
|
||||
/// Builds the network behaviour that manages the core protocols of eth2.
|
||||
/// This core behaviour is managed by `Behaviour` which adds peer management to all core
|
||||
@@ -87,23 +87,12 @@ impl<TSubstream: AsyncRead + AsyncWrite> NetworkBehaviourEventProcess<GossipsubE
|
||||
GossipsubEvent::Message(gs_msg) => {
|
||||
trace!(self.log, "Received GossipEvent"; "msg" => format!("{:?}", gs_msg));
|
||||
|
||||
let pubsub_message = match PubsubMessage::from_ssz_bytes(&gs_msg.data) {
|
||||
//TODO: Punish peer on error
|
||||
Err(e) => {
|
||||
warn!(
|
||||
self.log,
|
||||
"Received undecodable message from Peer {:?} error", gs_msg.source;
|
||||
"error" => format!("{:?}", e)
|
||||
);
|
||||
return;
|
||||
}
|
||||
Ok(msg) => msg,
|
||||
};
|
||||
let msg = PubsubMessage::from_topics(&gs_msg.topics, gs_msg.data);
|
||||
|
||||
self.events.push(BehaviourEvent::GossipMessage {
|
||||
source: gs_msg.source,
|
||||
topics: gs_msg.topics,
|
||||
message: Box::new(pubsub_message),
|
||||
message: msg,
|
||||
});
|
||||
}
|
||||
GossipsubEvent::Subscribed { .. } => {}
|
||||
@@ -225,7 +214,7 @@ pub enum BehaviourEvent {
|
||||
GossipMessage {
|
||||
source: PeerId,
|
||||
topics: Vec<TopicHash>,
|
||||
message: Box<PubsubMessage>,
|
||||
message: PubsubMessage,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -233,41 +222,50 @@ pub enum BehaviourEvent {
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum PubsubMessage {
|
||||
/// Gossipsub message providing notification of a new block.
|
||||
Block(BeaconBlock),
|
||||
Block(Vec<u8>),
|
||||
/// Gossipsub message providing notification of a new attestation.
|
||||
Attestation(Attestation),
|
||||
Attestation(Vec<u8>),
|
||||
/// Gossipsub message from an unknown topic.
|
||||
Unknown(Vec<u8>),
|
||||
}
|
||||
|
||||
impl PubsubMessage {
|
||||
/* Note: This is assuming we are not hashing topics. If we choose to hash topics, these will
|
||||
* need to be modified.
|
||||
*
|
||||
* Also note that a message can be associated with many topics. As soon as one of the topics is
|
||||
* known we match. If none of the topics are known we return an unknown state.
|
||||
*/
|
||||
fn from_topics(topics: &Vec<TopicHash>, data: Vec<u8>) -> Self {
|
||||
for topic in topics {
|
||||
match topic.as_str() {
|
||||
BEACON_BLOCK_TOPIC => return PubsubMessage::Block(data),
|
||||
BEACON_ATTESTATION_TOPIC => return PubsubMessage::Attestation(data),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
PubsubMessage::Unknown(data)
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: Correctly encode/decode enums. Prefixing with integer for now.
|
||||
impl Encode for PubsubMessage {
|
||||
fn is_ssz_fixed_len() -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn ssz_append(&self, buf: &mut Vec<u8>) {
|
||||
let offset = <u32 as Encode>::ssz_fixed_len() + <Vec<u8> as Encode>::ssz_fixed_len();
|
||||
|
||||
let mut encoder = ssz::SszEncoder::container(buf, offset);
|
||||
|
||||
match self {
|
||||
PubsubMessage::Block(block_gossip) => {
|
||||
encoder.append(&0_u32);
|
||||
|
||||
PubsubMessage::Block(inner)
|
||||
| PubsubMessage::Attestation(inner)
|
||||
| PubsubMessage::Unknown(inner) => {
|
||||
// Encode the gossip as a Vec<u8>;
|
||||
encoder.append(&block_gossip.as_ssz_bytes());
|
||||
}
|
||||
PubsubMessage::Attestation(attestation_gossip) => {
|
||||
encoder.append(&1_u32);
|
||||
|
||||
// Encode the gossip as a Vec<u8>;
|
||||
encoder.append(&attestation_gossip.as_ssz_bytes());
|
||||
buf.append(&mut inner.as_ssz_bytes());
|
||||
}
|
||||
}
|
||||
|
||||
encoder.finalize();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
impl Decode for PubsubMessage {
|
||||
fn is_ssz_fixed_len() -> bool {
|
||||
false
|
||||
@@ -295,7 +293,9 @@ impl Decode for PubsubMessage {
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
@@ -313,4 +313,6 @@ mod test {
|
||||
|
||||
assert_eq!(original, decoded);
|
||||
}
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
@@ -7,7 +7,7 @@ use std::path::PathBuf;
|
||||
use std::time::Duration;
|
||||
|
||||
/// The beacon node topic string to subscribe to.
|
||||
pub const BEACON_PUBSUB_TOPIC: &str = "beacon_block";
|
||||
pub const BEACON_BLOCK_TOPIC: &str = "beacon_block";
|
||||
pub const BEACON_ATTESTATION_TOPIC: &str = "beacon_attestation";
|
||||
pub const SHARD_TOPIC_PREFIX: &str = "shard";
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ mod service;
|
||||
|
||||
pub use behaviour::PubsubMessage;
|
||||
pub use config::{
|
||||
Config as NetworkConfig, BEACON_ATTESTATION_TOPIC, BEACON_PUBSUB_TOPIC, SHARD_TOPIC_PREFIX,
|
||||
Config as NetworkConfig, BEACON_ATTESTATION_TOPIC, BEACON_BLOCK_TOPIC, SHARD_TOPIC_PREFIX,
|
||||
};
|
||||
pub use libp2p::gossipsub::{Topic, TopicHash};
|
||||
pub use libp2p::multiaddr;
|
||||
|
||||
@@ -12,16 +12,14 @@ use libp2p::swarm::protocols_handler::{
|
||||
use smallvec::SmallVec;
|
||||
use std::time::{Duration, Instant};
|
||||
use tokio_io::{AsyncRead, AsyncWrite};
|
||||
use types::EthSpec;
|
||||
|
||||
/// The time (in seconds) before a substream that is awaiting a response times out.
|
||||
pub const RESPONSE_TIMEOUT: u64 = 9;
|
||||
|
||||
/// Implementation of `ProtocolsHandler` for the RPC protocol.
|
||||
pub struct RPCHandler<TSubstream, E>
|
||||
pub struct RPCHandler<TSubstream>
|
||||
where
|
||||
TSubstream: AsyncRead + AsyncWrite,
|
||||
E: EthSpec,
|
||||
{
|
||||
/// The upgrade for inbound substreams.
|
||||
listen_protocol: SubstreamProtocol<RPCProtocol>,
|
||||
@@ -56,8 +54,8 @@ where
|
||||
/// After the given duration has elapsed, an inactive connection will shutdown.
|
||||
inactive_timeout: Duration,
|
||||
|
||||
/// Phantom EthSpec.
|
||||
_phantom: PhantomData<E>,
|
||||
/// Marker to pin the generic stream.
|
||||
_phantom: PhantomData<TSubstream>,
|
||||
}
|
||||
|
||||
/// An outbound substream is waiting a response from the user.
|
||||
@@ -90,10 +88,9 @@ where
|
||||
},
|
||||
}
|
||||
|
||||
impl<TSubstream, E> RPCHandler<TSubstream, E>
|
||||
impl<TSubstream> RPCHandler<TSubstream>
|
||||
where
|
||||
TSubstream: AsyncRead + AsyncWrite,
|
||||
E: EthSpec,
|
||||
{
|
||||
pub fn new(
|
||||
listen_protocol: SubstreamProtocol<RPCProtocol>,
|
||||
@@ -145,20 +142,18 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<TSubstream, E> Default for RPCHandler<TSubstream, E>
|
||||
impl<TSubstream> Default for RPCHandler<TSubstream>
|
||||
where
|
||||
TSubstream: AsyncRead + AsyncWrite,
|
||||
E: EthSpec,
|
||||
{
|
||||
fn default() -> Self {
|
||||
RPCHandler::new(SubstreamProtocol::new(RPCProtocol), Duration::from_secs(30))
|
||||
}
|
||||
}
|
||||
|
||||
impl<TSubstream, E> ProtocolsHandler for RPCHandler<TSubstream, E>
|
||||
impl<TSubstream> ProtocolsHandler for RPCHandler<TSubstream>
|
||||
where
|
||||
TSubstream: AsyncRead + AsyncWrite,
|
||||
E: EthSpec,
|
||||
{
|
||||
type InEvent = RPCEvent;
|
||||
type OutEvent = RPCEvent;
|
||||
|
||||
@@ -16,7 +16,6 @@ pub use protocol::{RPCError, RPCProtocol, RPCRequest};
|
||||
use slog::o;
|
||||
use std::marker::PhantomData;
|
||||
use tokio::io::{AsyncRead, AsyncWrite};
|
||||
use types::EthSpec;
|
||||
|
||||
pub(crate) mod codec;
|
||||
mod handler;
|
||||
@@ -50,16 +49,16 @@ impl RPCEvent {
|
||||
|
||||
/// Implements the libp2p `NetworkBehaviour` trait and therefore manages network-level
|
||||
/// logic.
|
||||
pub struct RPC<TSubstream, E: EthSpec> {
|
||||
pub struct RPC<TSubstream> {
|
||||
/// Queue of events to processed.
|
||||
events: Vec<NetworkBehaviourAction<RPCEvent, RPCMessage>>,
|
||||
/// Pins the generic substream.
|
||||
marker: PhantomData<(TSubstream, E)>,
|
||||
marker: PhantomData<(TSubstream)>,
|
||||
/// Slog logger for RPC behaviour.
|
||||
_log: slog::Logger,
|
||||
}
|
||||
|
||||
impl<TSubstream, E: EthSpec> RPC<TSubstream, E> {
|
||||
impl<TSubstream> RPC<TSubstream> {
|
||||
pub fn new(log: &slog::Logger) -> Self {
|
||||
let log = log.new(o!("Service" => "Libp2p-RPC"));
|
||||
RPC {
|
||||
@@ -80,12 +79,11 @@ impl<TSubstream, E: EthSpec> RPC<TSubstream, E> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<TSubstream, E> NetworkBehaviour for RPC<TSubstream, E>
|
||||
impl<TSubstream> NetworkBehaviour for RPC<TSubstream>
|
||||
where
|
||||
TSubstream: AsyncRead + AsyncWrite,
|
||||
E: EthSpec,
|
||||
{
|
||||
type ProtocolsHandler = RPCHandler<TSubstream, E>;
|
||||
type ProtocolsHandler = RPCHandler<TSubstream>;
|
||||
type OutEvent = RPCMessage;
|
||||
|
||||
fn new_handler(&mut self) -> Self::ProtocolsHandler {
|
||||
|
||||
@@ -4,7 +4,7 @@ use crate::multiaddr::Protocol;
|
||||
use crate::rpc::RPCEvent;
|
||||
use crate::NetworkConfig;
|
||||
use crate::{Topic, TopicHash};
|
||||
use crate::{BEACON_ATTESTATION_TOPIC, BEACON_PUBSUB_TOPIC};
|
||||
use crate::{BEACON_ATTESTATION_TOPIC, BEACON_BLOCK_TOPIC};
|
||||
use futures::prelude::*;
|
||||
use futures::Stream;
|
||||
use libp2p::core::{
|
||||
@@ -21,25 +21,24 @@ use std::fs::File;
|
||||
use std::io::prelude::*;
|
||||
use std::io::{Error, ErrorKind};
|
||||
use std::time::Duration;
|
||||
use types::EthSpec;
|
||||
|
||||
type Libp2pStream = Boxed<(PeerId, StreamMuxerBox), Error>;
|
||||
type Libp2pBehaviour<E> = Behaviour<Substream<StreamMuxerBox>, E>;
|
||||
type Libp2pBehaviour = Behaviour<Substream<StreamMuxerBox>>;
|
||||
|
||||
const NETWORK_KEY_FILENAME: &str = "key";
|
||||
|
||||
/// The configuration and state of the libp2p components for the beacon node.
|
||||
pub struct Service<E: EthSpec> {
|
||||
pub struct Service {
|
||||
/// The libp2p Swarm handler.
|
||||
//TODO: Make this private
|
||||
pub swarm: Swarm<Libp2pStream, Libp2pBehaviour<E>>,
|
||||
pub swarm: Swarm<Libp2pStream, Libp2pBehaviour>,
|
||||
/// This node's PeerId.
|
||||
_local_peer_id: PeerId,
|
||||
/// The libp2p logger handle.
|
||||
pub log: slog::Logger,
|
||||
}
|
||||
|
||||
impl<E: EthSpec> Service<E> {
|
||||
impl Service {
|
||||
pub fn new(config: NetworkConfig, log: slog::Logger) -> error::Result<Self> {
|
||||
debug!(log, "Network-libp2p Service starting");
|
||||
|
||||
@@ -92,7 +91,7 @@ impl<E: EthSpec> Service<E> {
|
||||
//TODO: Handle multiple shard attestations. For now we simply use a separate topic for
|
||||
// attestations
|
||||
topics.push(Topic::new(BEACON_ATTESTATION_TOPIC.into()));
|
||||
topics.push(Topic::new(BEACON_PUBSUB_TOPIC.into()));
|
||||
topics.push(Topic::new(BEACON_BLOCK_TOPIC.into()));
|
||||
topics.append(
|
||||
&mut config
|
||||
.topics
|
||||
@@ -121,8 +120,8 @@ impl<E: EthSpec> Service<E> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: EthSpec> Stream for Service<E> {
|
||||
type Item = Libp2pEvent<E>;
|
||||
impl Stream for Service {
|
||||
type Item = Libp2pEvent;
|
||||
type Error = crate::error::Error;
|
||||
|
||||
fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
|
||||
@@ -136,7 +135,7 @@ impl<E: EthSpec> Stream for Service<E> {
|
||||
topics,
|
||||
message,
|
||||
} => {
|
||||
trace!(self.log, "Pubsub message received: {:?}", message);
|
||||
trace!(self.log, "Gossipsub message received"; "Message" => format!("{:?}", message));
|
||||
return Ok(Async::Ready(Some(Libp2pEvent::PubsubMessage {
|
||||
source,
|
||||
topics,
|
||||
@@ -196,7 +195,7 @@ fn build_transport(local_private_key: Keypair) -> Boxed<(PeerId, StreamMuxerBox)
|
||||
}
|
||||
|
||||
/// Events that can be obtained from polling the Libp2p Service.
|
||||
pub enum Libp2pEvent<E: EthSpec> {
|
||||
pub enum Libp2pEvent {
|
||||
/// An RPC response request has been received on the swarm.
|
||||
RPC(PeerId, RPCEvent),
|
||||
/// Initiated the connection to a new peer.
|
||||
@@ -207,7 +206,7 @@ pub enum Libp2pEvent<E: EthSpec> {
|
||||
PubsubMessage {
|
||||
source: PeerId,
|
||||
topics: Vec<TopicHash>,
|
||||
message: Box<PubsubMessage<E>>,
|
||||
message: PubsubMessage,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user