Skip to content

Commit

Permalink
feat: define concrete type for RoutingTableInfo (#875)
Browse files Browse the repository at this point in the history
* Define RoutingTableInfo type (#862)

* Make suggested changes
  • Loading branch information
0xcrust authored Nov 23, 2023
1 parent 9226c4e commit 092427a
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 41 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

33 changes: 28 additions & 5 deletions ethportal-api/src/types/discv5.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
use super::enr::Enr;
use crate::utils::bytes::hex_encode;
use serde::{Deserialize, Serialize};
use serde_json::Value;

use discv5::enr::NodeId;

/// Discv5 bucket
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(transparent)]
pub struct Bucket {
#[serde(flatten)]
pub node_ids: Vec<NodeId>,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub node_ids: Vec<String>,
}

/// Represents a discv5 kbuckets table
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(transparent)]
pub struct KBucketsTable {
#[serde(flatten)]
pub buckets: Vec<Bucket>,
}

Expand All @@ -27,4 +28,26 @@ pub struct NodeInfo {
pub ip: Option<String>,
}

pub type RoutingTableInfo = Value;
/// Information about a discv5/overlay network's routing table.
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct RoutingTableInfo {
pub local_node_id: String,
pub buckets: KBucketsTable,
}

impl<TVal: Eq> From<discv5::kbucket::KBucketsTable<NodeId, TVal>> for KBucketsTable {
fn from(table: discv5::kbucket::KBucketsTable<NodeId, TVal>) -> Self {
let buckets = table
.buckets_iter()
.map(|bucket| Bucket {
node_ids: bucket
.iter()
.map(|node| hex_encode(*node.key.preimage()))
.collect(),
})
.collect();

KBucketsTable { buckets }
}
}
10 changes: 2 additions & 8 deletions ethportal-peertest/src/scenarios/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,7 @@ pub async fn test_discv5_node_info(peertest: &Peertest) {
pub async fn test_discv5_routing_table_info(target: &Client) {
info!("Testing discv5_routingTableInfo");
let result = Discv5ApiClient::routing_table_info(target).await.unwrap();
let local_key = result.get("localNodeId").unwrap();
assert!(local_key.is_string());
assert!(local_key.as_str().unwrap().starts_with("0x"));
assert!(result.get("buckets").unwrap().is_array());
assert!(result.local_node_id.starts_with("0x"));
}

pub async fn test_history_radius(target: &Client) {
Expand Down Expand Up @@ -117,10 +114,7 @@ pub async fn test_history_routing_table_info(target: &Client) {
let result = HistoryNetworkApiClient::routing_table_info(target)
.await
.unwrap();
assert!(result.get("buckets").unwrap().is_object());
assert!(result.get("numBuckets").unwrap().is_u64());
assert!(result.get("numNodes").unwrap().is_u64());
assert!(result.get("numConnected").unwrap().is_u64());
assert!(result.local_node_id.starts_with("0x"));
}

pub async fn test_history_local_content_absent(target: &Client) {
Expand Down
29 changes: 7 additions & 22 deletions portalnet/src/discovery.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@ use discv5::{
use lru::LruCache;
use parking_lot::RwLock;
use rlp::RlpStream;
use serde_json::{json, Value};
use tokio::sync::mpsc;
use tracing::{debug, info, warn};
use utp_rs::{cid::ConnectionPeer, udp::AsyncUdpSocket};

use super::config::PortalnetConfig;
use super::types::messages::ProtocolId;
use crate::socket;
use ethportal_api::types::discv5::RoutingTableInfo;
use ethportal_api::types::enr::Enr;
use ethportal_api::utils::bytes::hex_encode;
use ethportal_api::NodeInfo;
Expand Down Expand Up @@ -249,27 +249,12 @@ impl Discovery {
})
}

/// Returns vector of all ENR node IDs of nodes currently contained in the routing table mapped to JSON Value.
pub fn routing_table_info(&self) -> Value {
let buckets: Vec<(String, String, String)> = self
.discv5
.table_entries()
.iter()
.map(|(node_id, enr, node_status)| {
(
hex_encode(node_id.raw()),
enr.to_base64(),
format!("{:?}", node_status.state),
)
})
.collect();

json!(
{
"localNodeId": hex_encode(self.discv5.local_enr().node_id().raw()),
"buckets": buckets
}
)
/// Returns the local node-id and a nested array of node-ids contained in each of this node's k-buckets.
pub fn routing_table_info(&self) -> RoutingTableInfo {
RoutingTableInfo {
local_node_id: hex_encode(self.discv5.local_enr().node_id().raw()),
buckets: self.discv5.kbuckets().into(),
}
}

/// Returns the node IDs of connected peers in the Discv5 routing table.
Expand Down
9 changes: 9 additions & 0 deletions portalnet/src/overlay.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ use crate::{
},
};
use ethportal_api::types::bootnodes::Bootnode;
use ethportal_api::types::discv5::RoutingTableInfo;
use ethportal_api::types::distance::{Distance, Metric};
use ethportal_api::types::enr::Enr;
use ethportal_api::utils::bytes::hex_encode;
Expand Down Expand Up @@ -267,6 +268,14 @@ where
.collect()
}

/// Returns the node-id and a nested array of node-ids to represent this node's k-buckets table.
pub fn routing_table_info(&self) -> RoutingTableInfo {
RoutingTableInfo {
local_node_id: hex_encode(self.local_enr().node_id().raw()),
buckets: self.kbuckets.read().clone().into(),
}
}

/// Returns a map (BTree for its ordering guarantees) with:
/// key: usize representing bucket index
/// value: Vec of tuples, each tuple represents a node
Expand Down
5 changes: 4 additions & 1 deletion trin-beacon/src/jsonrpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,10 @@ async fn complete_request(network: Arc<RwLock<BeaconNetwork>>, request: BeaconJs
offer(network, enr, content_key, content_value).await
}
BeaconEndpoint::Ping(enr) => ping(network, enr).await,
BeaconEndpoint::RoutingTableInfo => Ok(json!("Not implemented")), // TODO: implement this when refactor trin_history utils
BeaconEndpoint::RoutingTableInfo => {
serde_json::to_value(network.read().await.overlay.routing_table_info())
.map_err(|err| err.to_string())
}
BeaconEndpoint::RecursiveFindNodes(node_id) => recursive_find_nodes(network, node_id).await,
};
let _ = request.resp.send(response);
Expand Down
8 changes: 4 additions & 4 deletions trin-history/src/jsonrpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ use tokio::sync::{mpsc, Mutex, RwLock};
use tracing::error;

use crate::network::HistoryNetwork;
use crate::utils::bucket_entries_to_json;

/// Handles History network JSON-RPC requests
pub struct HistoryRequestHandler {
Expand Down Expand Up @@ -75,9 +74,10 @@ async fn complete_request(network: Arc<RwLock<HistoryNetwork>>, request: History
offer(network, enr, content_key, content_value).await
}
HistoryEndpoint::Ping(enr) => ping(network, enr).await,
HistoryEndpoint::RoutingTableInfo => Ok(bucket_entries_to_json(
network.read().await.overlay.bucket_entries(),
)),
HistoryEndpoint::RoutingTableInfo => {
serde_json::to_value(network.read().await.overlay.routing_table_info())
.map_err(|err| err.to_string())
}
HistoryEndpoint::RecursiveFindNodes(node_id) => {
recursive_find_nodes(network, node_id).await
}
Expand Down

0 comments on commit 092427a

Please sign in to comment.