mirror of
https://github.com/pezkuwichain/pezkuwi-telemetry.git
synced 2026-05-29 23:31:12 +00:00
Update node locations when they come in, and get the real IP addr of nodes
This commit is contained in:
@@ -3,7 +3,7 @@ use std::sync::atomic::AtomicU64;
|
||||
use futures::channel::mpsc;
|
||||
use futures::{ future, Sink, SinkExt };
|
||||
use super::inner_loop;
|
||||
use super::find_location::{ self, find_location };
|
||||
use crate::find_location::find_location;
|
||||
use crate::state::NodeId;
|
||||
use std::net::Ipv4Addr;
|
||||
|
||||
|
||||
@@ -8,13 +8,13 @@ use common::{
|
||||
util::now
|
||||
};
|
||||
use bimap::BiMap;
|
||||
use std::{iter::FromIterator, net::Ipv4Addr, str::FromStr};
|
||||
use std::{net::{IpAddr, Ipv4Addr}, str::FromStr};
|
||||
use futures::channel::{ mpsc };
|
||||
use futures::{ SinkExt, StreamExt };
|
||||
use std::collections::{ HashMap, HashSet };
|
||||
use crate::state::{ self, State, NodeId };
|
||||
use crate::feed_message::{ self, FeedMessageSerializer };
|
||||
use super::find_location;
|
||||
use crate::find_location;
|
||||
|
||||
/// A unique Id is assigned per websocket connection (or more accurately,
|
||||
/// per feed socket and per shard socket). This can be combined with the
|
||||
@@ -143,7 +143,7 @@ pub struct InnerLoop {
|
||||
/// These feeds want finality info, too.
|
||||
feed_conn_id_finality: HashSet<ConnId>,
|
||||
|
||||
/// Send messages here to make location requests, which are sent back into the loop.
|
||||
/// Send messages here to make geographical location requests.
|
||||
tx_to_locator: mpsc::UnboundedSender<(NodeId, Ipv4Addr)>
|
||||
}
|
||||
|
||||
@@ -184,8 +184,32 @@ impl InnerLoop {
|
||||
}
|
||||
}
|
||||
|
||||
/// Handle messages that come from the node geographical locator.
|
||||
async fn handle_from_find_location(&mut self, node_id: NodeId, location: find_location::Location) {
|
||||
// TODO: Update node location here
|
||||
self.node_state.update_node_location(node_id, location.clone());
|
||||
|
||||
if let Some(loc) = location {
|
||||
let mut feed_message_serializer = FeedMessageSerializer::new();
|
||||
feed_message_serializer.push(feed_message::LocatedNode(
|
||||
node_id,
|
||||
loc.latitude,
|
||||
loc.longitude,
|
||||
&loc.city
|
||||
));
|
||||
|
||||
if let Some(bytes) = feed_message_serializer.into_finalized() {
|
||||
let chain_label = self.node_state
|
||||
.get_node_chain(node_id)
|
||||
.map(|chain| chain.label());
|
||||
|
||||
if let Some(chain_label) = chain_label {
|
||||
// Don't hold onto lifetime from self because we call a mut fn next:
|
||||
let label = chain_label.to_owned();
|
||||
// Update location for any feeds subscribed to the node's chain.
|
||||
self.broadcast_to_chain_feeds(&label, ToFeedWebsocket::Bytes(bytes)).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Handle messages coming from shards.
|
||||
@@ -228,7 +252,10 @@ impl InnerLoop {
|
||||
).await
|
||||
}
|
||||
|
||||
// TODO: The node has been added. use it's IP to find a location.
|
||||
// Currently we only geographically locate IPV4 addresses so ignore IPV6;
|
||||
if let Some(IpAddr::V4(ip_v4)) = ip {
|
||||
let _ = self.tx_to_locator.send((node_id, ip_v4)).await;
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
@@ -409,6 +436,7 @@ impl InnerLoop {
|
||||
if let Some(feeds) = self.chain_to_feed_conn_ids.get(chain) {
|
||||
for &feed_id in feeds {
|
||||
// How much faster would it be if we processed these in parallel?
|
||||
// Is it practical to do so given lifetimes and such?
|
||||
if let Some(chan) = self.feed_channels.get_mut(&feed_id) {
|
||||
chan.send(message.clone()).await;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
mod aggregator;
|
||||
mod inner_loop;
|
||||
mod find_location;
|
||||
|
||||
// Expose the various message types that can be worked with externally:
|
||||
pub use inner_loop::{ FromFeedWebsocket, FromShardWebsocket, ToFeedWebsocket, ToShardWebsocket };
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
mod aggregator;
|
||||
mod state;
|
||||
mod feed_message;
|
||||
mod find_location;
|
||||
|
||||
use std::net::SocketAddr;
|
||||
use std::str::FromStr;
|
||||
|
||||
@@ -90,6 +90,9 @@ impl Chain {
|
||||
pub fn get_node(&self, node_id: NodeId) -> Option<&Node> {
|
||||
self.nodes.get(&node_id)
|
||||
}
|
||||
pub fn get_node_mut(&mut self, node_id: NodeId) -> Option<&mut Node> {
|
||||
self.nodes.get_mut(&node_id)
|
||||
}
|
||||
pub fn label(&self) -> &str {
|
||||
&self.labels.best()
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ use common::types::{
|
||||
};
|
||||
use common::util::now;
|
||||
use common::node::SystemInterval;
|
||||
use crate::find_location;
|
||||
|
||||
/// Minimum time between block below broadcasting updates to the browser gets throttled, in ms.
|
||||
const THROTTLE_THRESHOLD: u64 = 100;
|
||||
@@ -28,7 +29,7 @@ pub struct Node {
|
||||
/// Hardware stats over time
|
||||
hardware: NodeHardware,
|
||||
/// Physical location details
|
||||
location: Option<Arc<NodeLocation>>,
|
||||
location: find_location::Location,
|
||||
/// Flag marking if the node is stale (not syncing or producing blocks)
|
||||
stale: bool,
|
||||
/// Unix timestamp for when node started up (falls back to connection time)
|
||||
@@ -88,8 +89,8 @@ impl Node {
|
||||
self.location.as_deref()
|
||||
}
|
||||
|
||||
pub fn update_location(&mut self, location: Arc<NodeLocation>) {
|
||||
self.location = Some(location);
|
||||
pub fn update_location(&mut self, location: find_location::Location) {
|
||||
self.location = location;
|
||||
}
|
||||
|
||||
pub fn block_details(&self) -> &BlockDetails {
|
||||
|
||||
@@ -6,6 +6,7 @@ use common::types::{Block, NodeDetails, NodeLocation, Timestamp};
|
||||
use common::util::{now, DenseMap, NumStats};
|
||||
use common::node::Payload;
|
||||
use std::iter::IntoIterator;
|
||||
use crate::find_location;
|
||||
|
||||
use super::chain::{ self, Chain };
|
||||
|
||||
@@ -16,7 +17,7 @@ pub type Label = Arc<str>;
|
||||
pub struct State {
|
||||
next_id: NodeId,
|
||||
chains: HashMap<BlockHash, Chain>,
|
||||
chains_by_label: HashMap<Label, BlockHash>,
|
||||
chains_by_label: HashMap<String, BlockHash>,
|
||||
chains_by_node: HashMap<NodeId, BlockHash>,
|
||||
/// Denylist for networks we do not want to allow connecting.
|
||||
denylist: HashSet<String>,
|
||||
@@ -94,6 +95,14 @@ impl State {
|
||||
AddNodeResult::ChainOverQuota
|
||||
},
|
||||
chain::AddNodeResult::Added { chain_renamed } => {
|
||||
// Update the label we use to reference the chain if
|
||||
// it changes (it'll always change first time a node's added):
|
||||
if chain_renamed {
|
||||
let label = chain.label().to_owned();
|
||||
self.chains_by_label.remove(&label);
|
||||
self.chains_by_label.insert(label, genesis_hash);
|
||||
}
|
||||
|
||||
let node = chain.get_node(node_id).unwrap();
|
||||
AddNodeResult::NodeAddedToChain(NodeAddedToChain {
|
||||
id: node_id,
|
||||
@@ -106,6 +115,30 @@ impl State {
|
||||
}
|
||||
}
|
||||
|
||||
/// Update the location for a node. Return `false` if the node was not found.
|
||||
pub fn update_node_location(&mut self, node_id: NodeId, location: find_location::Location) -> bool {
|
||||
if let Some(node) = self.get_node_mut(node_id) {
|
||||
node.update_location(location);
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the chain that a node belongs to.
|
||||
pub fn get_node_chain(&self, node_id: NodeId) -> Option<&Chain> {
|
||||
self.chains_by_node
|
||||
.get(&node_id)
|
||||
.and_then(|chain_id| self.chains.get(chain_id))
|
||||
}
|
||||
|
||||
/// Obtain mutable access to a node, if it's found.
|
||||
fn get_node_mut(&mut self, node_id: NodeId) -> Option<&mut Node> {
|
||||
let chain_id = *self.chains_by_node.get(&node_id)?;
|
||||
let chain = self.chains.get_mut(&chain_id)?;
|
||||
chain.get_node_mut(node_id)
|
||||
}
|
||||
|
||||
// /// Add a new node to our state.
|
||||
// pub fn add_node(&mut self, id: GlobalId, genesis_hash: BlockHash, node: &NodeDetails) -> AddNodeResult {
|
||||
// if self.denylist.contains(&*node.chain) {
|
||||
|
||||
Reference in New Issue
Block a user