Optional Discovery (#1280)
* Remove beacon-chain config file * Makes discovery optional * Remove unused dep
This commit is contained in:
parent
ea76faeeee
commit
da6ab85e99
@ -56,6 +56,9 @@ pub struct Config {
|
|||||||
/// Client version
|
/// Client version
|
||||||
pub client_version: String,
|
pub client_version: String,
|
||||||
|
|
||||||
|
/// Disables the discovery protocol from starting.
|
||||||
|
pub disable_discovery: bool,
|
||||||
|
|
||||||
/// List of extra topics to initially subscribe to as strings.
|
/// List of extra topics to initially subscribe to as strings.
|
||||||
pub topics: Vec<GossipKind>,
|
pub topics: Vec<GossipKind>,
|
||||||
}
|
}
|
||||||
@ -104,7 +107,7 @@ impl Default for Config {
|
|||||||
.request_retries(2)
|
.request_retries(2)
|
||||||
.enr_peer_update_min(2) // prevents NAT's should be raised for mainnet
|
.enr_peer_update_min(2) // prevents NAT's should be raised for mainnet
|
||||||
.query_parallelism(5)
|
.query_parallelism(5)
|
||||||
.query_timeout(Duration::from_secs(60))
|
.query_timeout(Duration::from_secs(30))
|
||||||
.query_peer_timeout(Duration::from_secs(2))
|
.query_peer_timeout(Duration::from_secs(2))
|
||||||
.ip_limit() // limits /24 IP's in buckets.
|
.ip_limit() // limits /24 IP's in buckets.
|
||||||
.ping_interval(Duration::from_secs(300))
|
.ping_interval(Duration::from_secs(300))
|
||||||
@ -125,6 +128,7 @@ impl Default for Config {
|
|||||||
boot_nodes: vec![],
|
boot_nodes: vec![],
|
||||||
libp2p_nodes: vec![],
|
libp2p_nodes: vec![],
|
||||||
client_version: version::version(),
|
client_version: version::version(),
|
||||||
|
disable_discovery: false,
|
||||||
topics,
|
topics,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -112,10 +112,12 @@ enum EventStream {
|
|||||||
),
|
),
|
||||||
/// The future has completed.
|
/// The future has completed.
|
||||||
Present(mpsc::Receiver<Discv5Event>),
|
Present(mpsc::Receiver<Discv5Event>),
|
||||||
// The future has failed, there are no events from discv5.
|
// The future has failed or discv5 has been disabled. There are no events from discv5.
|
||||||
Failed,
|
InActive,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The main discovery service. This can be disabled via CLI arguements. When disabled the
|
||||||
|
/// underlying processes are not started, but this struct still maintains our current ENR.
|
||||||
pub struct Discovery<TSpec: EthSpec> {
|
pub struct Discovery<TSpec: EthSpec> {
|
||||||
/// A collection of seen live ENRs for quick lookup and to map peer-id's to ENRs.
|
/// A collection of seen live ENRs for quick lookup and to map peer-id's to ENRs.
|
||||||
cached_enrs: LruCache<PeerId, Enr>,
|
cached_enrs: LruCache<PeerId, Enr>,
|
||||||
@ -145,6 +147,10 @@ pub struct Discovery<TSpec: EthSpec> {
|
|||||||
/// The discv5 event stream.
|
/// The discv5 event stream.
|
||||||
event_stream: EventStream,
|
event_stream: EventStream,
|
||||||
|
|
||||||
|
/// Indicates if the discovery service has been started. When the service is disabled, this is
|
||||||
|
/// always false.
|
||||||
|
started: bool,
|
||||||
|
|
||||||
/// Logger for the discovery behaviour.
|
/// Logger for the discovery behaviour.
|
||||||
log: slog::Logger,
|
log: slog::Logger,
|
||||||
}
|
}
|
||||||
@ -196,12 +202,16 @@ impl<TSpec: EthSpec> Discovery<TSpec> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start the discv5 service.
|
// Start the discv5 service and obtain an event stream
|
||||||
discv5.start(listen_socket);
|
let event_stream = if !config.disable_discovery {
|
||||||
debug!(log, "Discovery service started");
|
discv5.start(listen_socket);
|
||||||
|
debug!(log, "Discovery service started");
|
||||||
|
EventStream::Awaiting(Box::pin(discv5.event_stream()))
|
||||||
|
} else {
|
||||||
|
EventStream::InActive
|
||||||
|
};
|
||||||
|
|
||||||
// Obtain the event stream
|
// Obtain the event stream
|
||||||
let event_stream = EventStream::Awaiting(Box::pin(discv5.event_stream()));
|
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
cached_enrs: LruCache::new(50),
|
cached_enrs: LruCache::new(50),
|
||||||
@ -211,6 +221,7 @@ impl<TSpec: EthSpec> Discovery<TSpec> {
|
|||||||
active_queries: FuturesUnordered::new(),
|
active_queries: FuturesUnordered::new(),
|
||||||
discv5,
|
discv5,
|
||||||
event_stream,
|
event_stream,
|
||||||
|
started: !config.disable_discovery,
|
||||||
log,
|
log,
|
||||||
enr_dir,
|
enr_dir,
|
||||||
})
|
})
|
||||||
@ -223,10 +234,11 @@ impl<TSpec: EthSpec> Discovery<TSpec> {
|
|||||||
|
|
||||||
/// This adds a new `FindPeers` query to the queue if one doesn't already exist.
|
/// This adds a new `FindPeers` query to the queue if one doesn't already exist.
|
||||||
pub fn discover_peers(&mut self) {
|
pub fn discover_peers(&mut self) {
|
||||||
// If we are in the process of a query, don't bother queuing a new one.
|
// If the discv5 service isn't running or we are in the process of a query, don't bother queuing a new one.
|
||||||
if self.find_peer_active {
|
if !self.started || self.find_peer_active {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there is not already a find peer's query queued, add one
|
// If there is not already a find peer's query queued, add one
|
||||||
let query = QueryType::FindPeers;
|
let query = QueryType::FindPeers;
|
||||||
if !self.queued_queries.contains(&query) {
|
if !self.queued_queries.contains(&query) {
|
||||||
@ -239,54 +251,11 @@ impl<TSpec: EthSpec> Discovery<TSpec> {
|
|||||||
|
|
||||||
/// Processes a request to search for more peers on a subnet.
|
/// Processes a request to search for more peers on a subnet.
|
||||||
pub fn discover_subnet_peers(&mut self, subnet_id: SubnetId, min_ttl: Option<Instant>) {
|
pub fn discover_subnet_peers(&mut self, subnet_id: SubnetId, min_ttl: Option<Instant>) {
|
||||||
self.add_subnet_query(subnet_id, min_ttl, 0);
|
// If the discv5 service isn't running, ignore queries
|
||||||
}
|
if !self.started {
|
||||||
|
|
||||||
/// Adds a subnet query if one doesn't exist. If a subnet query already exists, this
|
|
||||||
/// updates the min_ttl field.
|
|
||||||
fn add_subnet_query(&mut self, subnet_id: SubnetId, min_ttl: Option<Instant>, retries: usize) {
|
|
||||||
// remove the entry and complete the query if greater than the maximum search count
|
|
||||||
if retries >= MAX_DISCOVERY_RETRY {
|
|
||||||
debug!(
|
|
||||||
self.log,
|
|
||||||
"Subnet peer discovery did not find sufficient peers. Reached max retry limit"
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
self.add_subnet_query(subnet_id, min_ttl, 0);
|
||||||
// Search through any queued requests and update the timeout if a query for this subnet
|
|
||||||
// already exists
|
|
||||||
let mut found = false;
|
|
||||||
for query in self.queued_queries.iter_mut() {
|
|
||||||
if let QueryType::Subnet {
|
|
||||||
subnet_id: ref mut q_subnet_id,
|
|
||||||
min_ttl: ref mut q_min_ttl,
|
|
||||||
retries: ref mut q_retries,
|
|
||||||
} = query
|
|
||||||
{
|
|
||||||
if *q_subnet_id == subnet_id {
|
|
||||||
if *q_min_ttl < min_ttl {
|
|
||||||
*q_min_ttl = min_ttl;
|
|
||||||
}
|
|
||||||
// update the number of retries
|
|
||||||
*q_retries = retries;
|
|
||||||
// mimic an `Iter::Find()` and short-circuit the loop
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !found {
|
|
||||||
// Set up the query and add it to the queue
|
|
||||||
let query = QueryType::Subnet {
|
|
||||||
subnet_id,
|
|
||||||
min_ttl,
|
|
||||||
retries,
|
|
||||||
};
|
|
||||||
// update the metrics and insert into the queue.
|
|
||||||
metrics::set_gauge(&metrics::DISCOVERY_QUEUE, self.queued_queries.len() as i64);
|
|
||||||
self.queued_queries.push_back(query);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add an ENR to the routing table of the discovery mechanism.
|
/// Add an ENR to the routing table of the discovery mechanism.
|
||||||
@ -295,7 +264,7 @@ impl<TSpec: EthSpec> Discovery<TSpec> {
|
|||||||
self.cached_enrs.put(enr.peer_id(), enr.clone());
|
self.cached_enrs.put(enr.peer_id(), enr.clone());
|
||||||
|
|
||||||
if let Err(e) = self.discv5.add_enr(enr) {
|
if let Err(e) = self.discv5.add_enr(enr) {
|
||||||
warn!(
|
debug!(
|
||||||
self.log,
|
self.log,
|
||||||
"Could not add peer to the local routing table";
|
"Could not add peer to the local routing table";
|
||||||
"error" => format!("{}", e)
|
"error" => format!("{}", e)
|
||||||
@ -396,6 +365,53 @@ impl<TSpec: EthSpec> Discovery<TSpec> {
|
|||||||
|
|
||||||
/* Internal Functions */
|
/* Internal Functions */
|
||||||
|
|
||||||
|
/// Adds a subnet query if one doesn't exist. If a subnet query already exists, this
|
||||||
|
/// updates the min_ttl field.
|
||||||
|
fn add_subnet_query(&mut self, subnet_id: SubnetId, min_ttl: Option<Instant>, retries: usize) {
|
||||||
|
// remove the entry and complete the query if greater than the maximum search count
|
||||||
|
if retries >= MAX_DISCOVERY_RETRY {
|
||||||
|
debug!(
|
||||||
|
self.log,
|
||||||
|
"Subnet peer discovery did not find sufficient peers. Reached max retry limit"
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search through any queued requests and update the timeout if a query for this subnet
|
||||||
|
// already exists
|
||||||
|
let mut found = false;
|
||||||
|
for query in self.queued_queries.iter_mut() {
|
||||||
|
if let QueryType::Subnet {
|
||||||
|
subnet_id: ref mut q_subnet_id,
|
||||||
|
min_ttl: ref mut q_min_ttl,
|
||||||
|
retries: ref mut q_retries,
|
||||||
|
} = query
|
||||||
|
{
|
||||||
|
if *q_subnet_id == subnet_id {
|
||||||
|
if *q_min_ttl < min_ttl {
|
||||||
|
*q_min_ttl = min_ttl;
|
||||||
|
}
|
||||||
|
// update the number of retries
|
||||||
|
*q_retries = retries;
|
||||||
|
// mimic an `Iter::Find()` and short-circuit the loop
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !found {
|
||||||
|
// Set up the query and add it to the queue
|
||||||
|
let query = QueryType::Subnet {
|
||||||
|
subnet_id,
|
||||||
|
min_ttl,
|
||||||
|
retries,
|
||||||
|
};
|
||||||
|
// update the metrics and insert into the queue.
|
||||||
|
metrics::set_gauge(&metrics::DISCOVERY_QUEUE, self.queued_queries.len() as i64);
|
||||||
|
self.queued_queries.push_back(query);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Consume the discovery queue and initiate queries when applicable.
|
/// Consume the discovery queue and initiate queries when applicable.
|
||||||
///
|
///
|
||||||
/// This also sanitizes the queue removing out-dated queries.
|
/// This also sanitizes the queue removing out-dated queries.
|
||||||
@ -572,6 +588,10 @@ impl<TSpec: EthSpec> Discovery<TSpec> {
|
|||||||
|
|
||||||
// Main execution loop to be driven by the peer manager.
|
// Main execution loop to be driven by the peer manager.
|
||||||
pub fn poll(&mut self, cx: &mut Context) -> Poll<DiscoveryEvent> {
|
pub fn poll(&mut self, cx: &mut Context) -> Poll<DiscoveryEvent> {
|
||||||
|
if !self.started {
|
||||||
|
return Poll::Pending;
|
||||||
|
}
|
||||||
|
|
||||||
// Process the query queue
|
// Process the query queue
|
||||||
self.process_queue();
|
self.process_queue();
|
||||||
|
|
||||||
@ -594,12 +614,12 @@ impl<TSpec: EthSpec> Discovery<TSpec> {
|
|||||||
Ok(stream) => self.event_stream = EventStream::Present(stream),
|
Ok(stream) => self.event_stream = EventStream::Present(stream),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
slog::crit!(self.log, "Discv5 event stream failed"; "error" => e.to_string());
|
slog::crit!(self.log, "Discv5 event stream failed"; "error" => e.to_string());
|
||||||
self.event_stream = EventStream::Failed;
|
self.event_stream = EventStream::InActive;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EventStream::Failed => {} // ignore checking the stream
|
EventStream::InActive => {} // ignore checking the stream
|
||||||
EventStream::Present(ref mut stream) => {
|
EventStream::Present(ref mut stream) => {
|
||||||
while let Ok(event) = stream.try_recv() {
|
while let Ok(event) = stream.try_recv() {
|
||||||
match event {
|
match event {
|
||||||
|
@ -110,7 +110,12 @@ impl<TSpec: EthSpec> Service<TSpec> {
|
|||||||
));
|
));
|
||||||
|
|
||||||
info!(log, "Libp2p Service"; "peer_id" => format!("{:?}", enr.peer_id()));
|
info!(log, "Libp2p Service"; "peer_id" => format!("{:?}", enr.peer_id()));
|
||||||
debug!(log, "Attempting to open listening ports"; "address" => format!("{}", config.listen_address), "tcp_port" => config.libp2p_port, "udp_port" => config.discovery_port);
|
let discovery_string = if config.disable_discovery {
|
||||||
|
"None".into()
|
||||||
|
} else {
|
||||||
|
config.discovery_port.to_string()
|
||||||
|
};
|
||||||
|
debug!(log, "Attempting to open listening ports"; "address" => format!("{}", config.listen_address), "tcp_port" => config.libp2p_port, "udp_port" => discovery_string);
|
||||||
|
|
||||||
let mut swarm = {
|
let mut swarm = {
|
||||||
// Set up the transport - tcp/ws with noise/secio and mplex/yamux
|
// Set up the transport - tcp/ws with noise/secio and mplex/yamux
|
||||||
|
@ -61,7 +61,7 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> {
|
|||||||
.takes_value(true),
|
.takes_value(true),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("max_peers")
|
Arg::with_name("max-peers")
|
||||||
.long("max-peers")
|
.long("max-peers")
|
||||||
.help("The maximum number of peers.")
|
.help("The maximum number of peers.")
|
||||||
.default_value("50")
|
.default_value("50")
|
||||||
@ -125,6 +125,13 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> {
|
|||||||
without an ENR.")
|
without an ENR.")
|
||||||
.takes_value(true),
|
.takes_value(true),
|
||||||
)
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("disable-discovery")
|
||||||
|
.long("disable-discovery")
|
||||||
|
.help("Disables the discv5 discovery protocol. The node will not search for new peers or participate in the discovery protocol.")
|
||||||
|
.takes_value(false),
|
||||||
|
)
|
||||||
|
|
||||||
/* REST API related arguments */
|
/* REST API related arguments */
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("http")
|
Arg::with_name("http")
|
||||||
|
@ -195,6 +195,11 @@ pub fn get_config<E: EthSpec>(
|
|||||||
client_config.network.discv5_config.enr_update = false;
|
client_config.network.discv5_config.enr_update = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if cli_args.is_present("disable-discovery") {
|
||||||
|
client_config.network.disable_discovery = true;
|
||||||
|
slog::warn!(log, "Discovery is disabled. New peers will not be found");
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Http server
|
* Http server
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user