df40700ddd
## Description The `eth2_libp2p` crate was originally named and designed to incorporate a simple libp2p integration into lighthouse. Since its origins the crates purpose has expanded dramatically. It now houses a lot more sophistication that is specific to lighthouse and no longer just a libp2p integration. As of this writing it currently houses the following high-level lighthouse-specific logic: - Lighthouse's implementation of the eth2 RPC protocol and specific encodings/decodings - Integration and handling of ENRs with respect to libp2p and eth2 - Lighthouse's discovery logic, its integration with discv5 and logic about searching and handling peers. - Lighthouse's peer manager - This is a large module handling various aspects of Lighthouse's network, such as peer scoring, handling pings and metadata, connection maintenance and recording, etc. - Lighthouse's peer database - This is a collection of information stored for each individual peer which is specific to lighthouse. We store connection state, sync state, last seen ips and scores etc. The data stored for each peer is designed for various elements of the lighthouse code base such as syncing and the http api. - Gossipsub scoring - This stores a collection of gossipsub 1.1 scoring mechanisms that are continuously analyssed and updated based on the ethereum 2 networks and how Lighthouse performs on these networks. - Lighthouse specific types for managing gossipsub topics, sync status and ENR fields - Lighthouse's network HTTP API metrics - A collection of metrics for lighthouse network monitoring - Lighthouse's custom configuration of all networking protocols, RPC, gossipsub, discovery, identify and libp2p. Therefore it makes sense to rename the crate to be more akin to its current purposes, simply that it manages the majority of Lighthouse's network stack. This PR renames this crate to `lighthouse_network` Co-authored-by: Paul Hauner <paul@paulhauner.com>
172 lines
6.5 KiB
Rust
172 lines
6.5 KiB
Rust
/* These are temporarily disabled due to their non-deterministic behaviour and impending update to
|
|
* gossipsub 1.1. We leave these here as a template for future test upgrades
|
|
|
|
|
|
#![cfg(test)]
|
|
use crate::types::GossipEncoding;
|
|
use ::types::{BeaconBlock, EthSpec, MinimalEthSpec, Signature, SignedBeaconBlock};
|
|
use lighthouse_network::*;
|
|
use slog::{debug, Level};
|
|
|
|
type E = MinimalEthSpec;
|
|
|
|
mod common;
|
|
|
|
/* Gossipsub tests */
|
|
// Note: The aim of these tests is not to test the robustness of the gossip network
|
|
// but to check if the gossipsub implementation is behaving according to the specifications.
|
|
|
|
// Test if gossipsub message are forwarded by nodes with a simple linear topology.
|
|
//
|
|
// Topology used in test
|
|
//
|
|
// node1 <-> node2 <-> node3 ..... <-> node(n-1) <-> node(n)
|
|
|
|
#[tokio::test]
|
|
async fn test_gossipsub_forward() {
|
|
// set up the logging. The level and enabled or not
|
|
let log = common::build_log(Level::Info, false);
|
|
|
|
let num_nodes = 20;
|
|
let mut nodes = common::build_linear(log.clone(), num_nodes);
|
|
let mut received_count = 0;
|
|
let spec = E::default_spec();
|
|
let empty_block = BeaconBlock::empty(&spec);
|
|
let signed_block = SignedBeaconBlock {
|
|
message: empty_block,
|
|
signature: Signature::empty_signature(),
|
|
};
|
|
let pubsub_message = PubsubMessage::BeaconBlock(Box::new(signed_block));
|
|
let publishing_topic: String = pubsub_message
|
|
.topics(GossipEncoding::default(), [0, 0, 0, 0])
|
|
.first()
|
|
.unwrap()
|
|
.clone()
|
|
.into();
|
|
let mut subscribed_count = 0;
|
|
let fut = async move {
|
|
for node in nodes.iter_mut() {
|
|
loop {
|
|
match node.next_event().await {
|
|
Libp2pEvent::Behaviour(b) => match b {
|
|
BehaviourEvent::PubsubMessage {
|
|
topics,
|
|
message,
|
|
source,
|
|
id,
|
|
} => {
|
|
assert_eq!(topics.len(), 1);
|
|
// Assert topic is the published topic
|
|
assert_eq!(
|
|
topics.first().unwrap(),
|
|
&TopicHash::from_raw(publishing_topic.clone())
|
|
);
|
|
// Assert message received is the correct one
|
|
assert_eq!(message, pubsub_message.clone());
|
|
received_count += 1;
|
|
// Since `propagate_message` is false, need to propagate manually
|
|
node.swarm.propagate_message(&source, id);
|
|
// Test should succeed if all nodes except the publisher receive the message
|
|
if received_count == num_nodes - 1 {
|
|
debug!(log.clone(), "Received message at {} nodes", num_nodes - 1);
|
|
return;
|
|
}
|
|
}
|
|
BehaviourEvent::PeerSubscribed(_, topic) => {
|
|
// Publish on beacon block topic
|
|
if topic == TopicHash::from_raw(publishing_topic.clone()) {
|
|
subscribed_count += 1;
|
|
// Every node except the corner nodes are connected to 2 nodes.
|
|
if subscribed_count == (num_nodes * 2) - 2 {
|
|
node.swarm.publish(vec![pubsub_message.clone()]);
|
|
}
|
|
}
|
|
}
|
|
_ => break,
|
|
},
|
|
_ => break,
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
tokio::select! {
|
|
_ = fut => {}
|
|
_ = tokio::time::delay_for(tokio::time::Duration::from_millis(800)) => {
|
|
panic!("Future timed out");
|
|
}
|
|
}
|
|
}
|
|
|
|
// Test publishing of a message with a full mesh for the topic
|
|
// Not very useful but this is the bare minimum functionality.
|
|
#[tokio::test]
|
|
async fn test_gossipsub_full_mesh_publish() {
|
|
// set up the logging. The level and enabled or not
|
|
let log = common::build_log(Level::Debug, false);
|
|
|
|
// Note: This test does not propagate gossipsub messages.
|
|
// Having `num_nodes` > `mesh_n_high` may give inconsistent results
|
|
// as nodes may get pruned out of the mesh before the gossipsub message
|
|
// is published to them.
|
|
let num_nodes = 12;
|
|
let mut nodes = common::build_full_mesh(log, num_nodes);
|
|
let mut publishing_node = nodes.pop().unwrap();
|
|
let spec = E::default_spec();
|
|
let empty_block = BeaconBlock::empty(&spec);
|
|
let signed_block = SignedBeaconBlock {
|
|
message: empty_block,
|
|
signature: Signature::empty_signature(),
|
|
};
|
|
let pubsub_message = PubsubMessage::BeaconBlock(Box::new(signed_block));
|
|
let publishing_topic: String = pubsub_message
|
|
.topics(GossipEncoding::default(), [0, 0, 0, 0])
|
|
.first()
|
|
.unwrap()
|
|
.clone()
|
|
.into();
|
|
let mut subscribed_count = 0;
|
|
let mut received_count = 0;
|
|
let fut = async move {
|
|
for node in nodes.iter_mut() {
|
|
while let Libp2pEvent::Behaviour(BehaviourEvent::PubsubMessage {
|
|
topics,
|
|
message,
|
|
..
|
|
}) = node.next_event().await
|
|
{
|
|
assert_eq!(topics.len(), 1);
|
|
// Assert topic is the published topic
|
|
assert_eq!(
|
|
topics.first().unwrap(),
|
|
&TopicHash::from_raw(publishing_topic.clone())
|
|
);
|
|
// Assert message received is the correct one
|
|
assert_eq!(message, pubsub_message.clone());
|
|
received_count += 1;
|
|
if received_count == num_nodes - 1 {
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
while let Libp2pEvent::Behaviour(BehaviourEvent::PeerSubscribed(_, topic)) =
|
|
publishing_node.next_event().await
|
|
{
|
|
// Publish on beacon block topic
|
|
if topic == TopicHash::from_raw(publishing_topic.clone()) {
|
|
subscribed_count += 1;
|
|
if subscribed_count == num_nodes - 1 {
|
|
publishing_node.swarm.publish(vec![pubsub_message.clone()]);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
tokio::select! {
|
|
_ = fut => {}
|
|
_ = tokio::time::delay_for(tokio::time::Duration::from_millis(800)) => {
|
|
panic!("Future timed out");
|
|
}
|
|
}
|
|
}
|
|
*/
|