From 31522463cf27f2a429f4e60b529462c7f589e1b4 Mon Sep 17 00:00:00 2001 From: Nick Gheorghita Date: Tue, 24 Sep 2024 11:05:59 -0400 Subject: [PATCH] refactor: swap ProtocolId with Subnetwork type (#1478) * refactor: swap ProtocolId with Subnetwork type --- ethportal-api/src/types/cli.rs | 8 +- .../src/types/content_value/error.rs | 6 +- .../src/types/content_value/history.rs | 2 +- ethportal-api/src/types/network.rs | 53 +++++- ethportal-api/src/types/portal_wire.rs | 156 +++++------------- ethportal-peertest/src/lib.rs | 2 +- ethportal-peertest/src/scenarios/basic.rs | 128 +++++++------- ethportal-peertest/src/scenarios/find.rs | 32 ++-- portal-bridge/src/cli.rs | 4 +- portal-bridge/src/handle.rs | 3 +- portalnet/src/discovery.rs | 19 ++- portalnet/src/events.rs | 45 +++-- portalnet/src/overlay/protocol.rs | 9 +- portalnet/src/overlay/service.rs | 13 +- portalnet/tests/overlay.rs | 27 +-- rpc/src/lib.rs | 1 + src/bin/purge_invalid_history_content.rs | 7 +- tests/self_peertest.rs | 33 ++-- trin-beacon/src/network.rs | 4 +- trin-beacon/src/storage.rs | 4 +- trin-history/src/network.rs | 4 +- trin-history/src/storage.rs | 4 +- trin-metrics/src/labels.rs | 43 +---- trin-metrics/src/storage.rs | 6 +- trin-state/src/network.rs | 4 +- trin-state/src/storage.rs | 4 +- trin-storage/src/config.rs | 1 + .../src/versioned/id_indexed_v1/config.rs | 8 +- .../src/versioned/id_indexed_v1/migration.rs | 6 +- .../id_indexed_v1/pruning_strategy.rs | 4 +- .../src/versioned/id_indexed_v1/store.rs | 8 +- utp-testing/src/lib.rs | 11 +- 32 files changed, 296 insertions(+), 363 deletions(-) diff --git a/ethportal-api/src/types/cli.rs b/ethportal-api/src/types/cli.rs index cf4b1c569..41e39e526 100644 --- a/ethportal-api/src/types/cli.rs +++ b/ethportal-api/src/types/cli.rs @@ -339,13 +339,19 @@ pub fn network_parser(network_string: &str) -> Result, String> pub fn subnetwork_parser(subnetwork_string: &str) -> Result>, String> { let subnetworks = subnetwork_string .split(',') - .map(Subnetwork::from_str) + .map(Subnetwork::from_cli_arg) .collect::, String>>()?; if subnetworks.is_empty() { return Err("At least one subnetwork must be enabled".to_owned()); } + for subnetwork in &subnetworks { + if !subnetwork.is_active() { + return Err("{subnetwork} subnetwork has not yet been activated".to_owned()); + } + } + Ok(Arc::new(subnetworks)) } diff --git a/ethportal-api/src/types/content_value/error.rs b/ethportal-api/src/types/content_value/error.rs index 4b86b8f6a..12419f2c7 100644 --- a/ethportal-api/src/types/content_value/error.rs +++ b/ethportal-api/src/types/content_value/error.rs @@ -9,7 +9,7 @@ pub enum ContentValueError { decode_error: ssz::DecodeError, input: String, }, - #[error("could not determine content type of {bytes} from {subnetwork} subnetwork")] + #[error("could not determine content type of {bytes} from {subnetwork:?} subnetwork")] UnknownContent { bytes: String, subnetwork: Subnetwork, @@ -25,12 +25,12 @@ pub enum ContentValueError { /// This error implies that handling of the "content absent" response was skipped. #[error("attempted to decode the '0x' absent content message")] DecodeAbsentContent, - #[error("could not determine fork digest of {bytes} from {subnetwork} subnetwork")] + #[error("could not determine fork digest of {bytes} from {subnetwork:?} subnetwork")] UnknownForkDigest { bytes: String, subnetwork: Subnetwork, }, - #[error("could not determine fork name of {bytes} from {subnetwork} subnetwork")] + #[error("could not determine fork name of {bytes} from {subnetwork:?} subnetwork")] UnknownForkName { bytes: String, subnetwork: Subnetwork, diff --git a/ethportal-api/src/types/content_value/history.rs b/ethportal-api/src/types/content_value/history.rs index ba46aa6f7..c810aeffd 100644 --- a/ethportal-api/src/types/content_value/history.rs +++ b/ethportal-api/src/types/content_value/history.rs @@ -101,7 +101,7 @@ mod test { // Test the error Display representation. assert_eq!( error.to_string(), - "could not determine content type of 0x010203040506070809 from history subnetwork" + "could not determine content type of 0x010203040506070809 from History subnetwork" ); } } diff --git a/ethportal-api/src/types/network.rs b/ethportal-api/src/types/network.rs index 9cba9347d..6d6a38485 100644 --- a/ethportal-api/src/types/network.rs +++ b/ethportal-api/src/types/network.rs @@ -29,32 +29,69 @@ impl std::str::FromStr for Network { } /// Enum for various different portal subnetworks in a "core" network. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum Subnetwork { Beacon, History, State, + CanonicalIndices, + VerkleState, + TransactionGossip, + Utp, } +// Pretty printed version of the subnetwork enum, used in metrics labels. impl fmt::Display for Subnetwork { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - Subnetwork::Beacon => write!(f, "beacon"), - Subnetwork::History => write!(f, "history"), - Subnetwork::State => write!(f, "state"), + Subnetwork::Beacon => write!(f, "Beacon"), + Subnetwork::History => write!(f, "History"), + Subnetwork::State => write!(f, "State"), + Subnetwork::CanonicalIndices => write!(f, "Canonical Indices"), + Subnetwork::VerkleState => write!(f, "Verkle State"), + Subnetwork::TransactionGossip => write!(f, "Transaction Gossip"), + Subnetwork::Utp => write!(f, "uTP"), } } } -impl std::str::FromStr for Subnetwork { - type Err = String; - - fn from_str(s: &str) -> Result { +// Convert camel_case cli args to/from the Subnetwork enum. +impl Subnetwork { + pub fn from_cli_arg(s: &str) -> Result { match s { "beacon" => Ok(Subnetwork::Beacon), "history" => Ok(Subnetwork::History), "state" => Ok(Subnetwork::State), + "canonical_indices" => Ok(Subnetwork::CanonicalIndices), + "verkle_state" => Ok(Subnetwork::VerkleState), + "transaction_gossip" => Ok(Subnetwork::TransactionGossip), + "utp" => Ok(Subnetwork::Utp), _ => Err(format!("Unknown subnetwork: {s}")), } } + + pub fn to_cli_arg(&self) -> String { + match self { + Subnetwork::Beacon => "beacon".to_string(), + Subnetwork::History => "history".to_string(), + Subnetwork::State => "state".to_string(), + Subnetwork::CanonicalIndices => "canonical_indices".to_string(), + Subnetwork::VerkleState => "verkle_state".to_string(), + Subnetwork::TransactionGossip => "transaction_gossip".to_string(), + Subnetwork::Utp => "utp".to_string(), + } + } + + /// Returns true if the subnetwork has been "fully" activated. + pub fn is_active(&self) -> bool { + match self { + Subnetwork::Beacon => true, + Subnetwork::History => true, + Subnetwork::State => true, + Subnetwork::CanonicalIndices => false, + Subnetwork::VerkleState => false, + Subnetwork::TransactionGossip => false, + Subnetwork::Utp => false, + } + } } diff --git a/ethportal-api/src/types/portal_wire.rs b/ethportal-api/src/types/portal_wire.rs index 751e598af..10caf93d0 100644 --- a/ethportal-api/src/types/portal_wire.rs +++ b/ethportal-api/src/types/portal_wire.rs @@ -6,6 +6,7 @@ use std::{ }; use alloy_primitives::U256; +use anyhow::anyhow; use bimap::BiHashMap; use once_cell::sync::Lazy; use rlp::Encodable; @@ -22,9 +23,9 @@ use crate::{ bytes::ByteList2048, distance::Distance, enr::{Enr, SszEnr}, - network::Network, + network::{Network, Subnetwork}, }, - utils::bytes::{hex_decode, hex_encode, ByteUtilsError}, + utils::bytes::{hex_decode, hex_encode}, RawContentKey, }; @@ -157,31 +158,11 @@ pub enum DiscoveryRequestError { InvalidMessage, } -#[derive(Error, Debug)] -pub enum ProtocolIdError { - #[error("Unable to decode protocol id to bytes")] - Decode(ByteUtilsError), - - #[error("invalid protocol id")] - Invalid, -} - -/// Protocol identifiers -#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] -pub enum ProtocolId { - State, - VerkleState, - History, - TransactionGossip, - CanonicalIndices, - Beacon, - Utp, -} - #[derive(Clone, Debug, Eq, PartialEq)] pub struct NetworkSpec { network: Network, - portal_networks: BiHashMap, + // mapping of subnetworks to protocol id hex strings + portal_subnetworks: BiHashMap, } impl NetworkSpec { @@ -189,85 +170,58 @@ impl NetworkSpec { self.network } - pub fn get_protocol_id_from_hex(&self, hex: &str) -> Result { - self.portal_networks + pub fn get_subnetwork_from_protocol_identifier(&self, hex: &str) -> anyhow::Result { + self.portal_subnetworks .get_by_right(hex) .copied() - .ok_or(ProtocolIdError::Invalid) + .ok_or(anyhow!("Invalid subnetwork identifier: {hex}")) } - pub fn get_protocol_hex_from_id( + pub fn get_protocol_identifier_from_subnetwork( &self, - protocol_id: &ProtocolId, - ) -> Result { - self.portal_networks - .get_by_left(protocol_id) + subnetwork: &Subnetwork, + ) -> anyhow::Result { + self.portal_subnetworks + .get_by_left(subnetwork) .cloned() - .ok_or(ProtocolIdError::Invalid) + .ok_or(anyhow!( + "Cannot find protocol identifier for subnetwork: {subnetwork}" + )) } } pub static MAINNET: Lazy> = Lazy::new(|| { - let mut portal_networks = BiHashMap::new(); - portal_networks.insert(ProtocolId::State, "0x500A".to_string()); - portal_networks.insert(ProtocolId::History, "0x500B".to_string()); - portal_networks.insert(ProtocolId::Beacon, "0x500C".to_string()); - portal_networks.insert(ProtocolId::CanonicalIndices, "0x500D".to_string()); - portal_networks.insert(ProtocolId::VerkleState, "0x500E".to_string()); - portal_networks.insert(ProtocolId::TransactionGossip, "0x500F".to_string()); - portal_networks.insert(ProtocolId::Utp, "0x757470".to_string()); + let mut portal_subnetworks = BiHashMap::new(); + portal_subnetworks.insert(Subnetwork::State, "0x500A".to_string()); + portal_subnetworks.insert(Subnetwork::History, "0x500B".to_string()); + portal_subnetworks.insert(Subnetwork::Beacon, "0x500C".to_string()); + portal_subnetworks.insert(Subnetwork::CanonicalIndices, "0x500D".to_string()); + portal_subnetworks.insert(Subnetwork::VerkleState, "0x500E".to_string()); + portal_subnetworks.insert(Subnetwork::TransactionGossip, "0x500F".to_string()); + portal_subnetworks.insert(Subnetwork::Utp, "0x757470".to_string()); NetworkSpec { - portal_networks, + portal_subnetworks, network: Network::Mainnet, } .into() }); pub static ANGELFOOD: Lazy> = Lazy::new(|| { - let mut portal_networks = BiHashMap::new(); - portal_networks.insert(ProtocolId::State, "0x504A".to_string()); - portal_networks.insert(ProtocolId::History, "0x504B".to_string()); - portal_networks.insert(ProtocolId::Beacon, "0x504C".to_string()); - portal_networks.insert(ProtocolId::CanonicalIndices, "0x504D".to_string()); - portal_networks.insert(ProtocolId::VerkleState, "0x504E".to_string()); - portal_networks.insert(ProtocolId::TransactionGossip, "0x504F".to_string()); - portal_networks.insert(ProtocolId::Utp, "0x757470".to_string()); + let mut portal_subnetworks = BiHashMap::new(); + portal_subnetworks.insert(Subnetwork::State, "0x504A".to_string()); + portal_subnetworks.insert(Subnetwork::History, "0x504B".to_string()); + portal_subnetworks.insert(Subnetwork::Beacon, "0x504C".to_string()); + portal_subnetworks.insert(Subnetwork::CanonicalIndices, "0x504D".to_string()); + portal_subnetworks.insert(Subnetwork::VerkleState, "0x504E".to_string()); + portal_subnetworks.insert(Subnetwork::TransactionGossip, "0x504F".to_string()); + portal_subnetworks.insert(Subnetwork::Utp, "0x757470".to_string()); NetworkSpec { - portal_networks, + portal_subnetworks, network: Network::Angelfood, } .into() }); -impl fmt::Display for ProtocolId { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let protocol = match self { - ProtocolId::State => "State", - ProtocolId::VerkleState => "Verkle State", - ProtocolId::History => "History", - ProtocolId::TransactionGossip => "Transaction Gossip", - ProtocolId::CanonicalIndices => "Canonical Indices", - ProtocolId::Beacon => "Beacon", - ProtocolId::Utp => "uTP", - }; - write!(f, "{protocol}") - } -} - -impl From for u8 { - fn from(protocol_id: ProtocolId) -> Self { - match protocol_id { - ProtocolId::State => 2, - ProtocolId::VerkleState => 5, - ProtocolId::History => 0, - ProtocolId::TransactionGossip => 3, - ProtocolId::CanonicalIndices => 4, - ProtocolId::Beacon => 1, - ProtocolId::Utp => 99, - } - } -} - /// A Portal protocol message. #[derive(Debug, PartialEq, Clone, Encode, Decode)] #[ssz(enum_behaviour = "union")] @@ -628,49 +582,25 @@ mod test { use test_log::test; #[test] - fn protocol_id_invalid() { + fn subnetwork_invalid() { let hex = "0x504F"; - assert!(!MAINNET.portal_networks.contains_right(hex)); + assert!(!MAINNET.portal_subnetworks.contains_right(hex)); } #[test] - fn protocol_id_encoding() { + fn subnetwork_encoding() { let hex = "0x500A"; - let protocol_id = MAINNET.get_protocol_id_from_hex(hex).unwrap(); - let expected_hex = MAINNET.get_protocol_hex_from_id(&protocol_id).unwrap(); + let protocol_id = MAINNET + .get_subnetwork_from_protocol_identifier(hex) + .unwrap(); + let expected_hex = MAINNET + .get_protocol_identifier_from_subnetwork(&protocol_id) + .unwrap(); assert_eq!(hex, expected_hex); } - #[test] - fn prtocol_id_to_u8() { - let protocol_id = ProtocolId::History; - let expected_u8 = 0; - assert_eq!(expected_u8, u8::from(protocol_id)); - - let protocol_id = ProtocolId::Beacon; - let expected_u8 = 1; - assert_eq!(expected_u8, u8::from(protocol_id)); - - let protocol_id = ProtocolId::State; - let expected_u8 = 2; - assert_eq!(expected_u8, u8::from(protocol_id)); - - let protocol_id = ProtocolId::TransactionGossip; - let expected_u8 = 3; - assert_eq!(expected_u8, u8::from(protocol_id)); - - let protocol_id = ProtocolId::CanonicalIndices; - let expected_u8 = 4; - assert_eq!(expected_u8, u8::from(protocol_id)); - - let protocol_id = ProtocolId::Utp; - let expected_u8 = 99; - assert_eq!(expected_u8, u8::from(protocol_id)); - } - // Wire message test vectors available in Ethereum Portal Network specs repo: // github.com/ethereum/portal-network-specs - #[test] fn message_encoding_ping() { let data_radius: U256 = U256::MAX - U256::from(1u8); diff --git a/ethportal-peertest/src/lib.rs b/ethportal-peertest/src/lib.rs index c1377295a..35cb2d643 100644 --- a/ethportal-peertest/src/lib.rs +++ b/ethportal-peertest/src/lib.rs @@ -84,7 +84,7 @@ fn generate_trin_config( let private_key = hex_encode(private_key); let subnetworks = subnetworks .iter() - .map(|sn| sn.to_string()) + .map(|sn| sn.to_cli_arg()) .collect::>() .join(","); let network = network.to_string(); diff --git a/ethportal-peertest/src/scenarios/basic.rs b/ethportal-peertest/src/scenarios/basic.rs index b5eebd154..96fc14d90 100644 --- a/ethportal-peertest/src/scenarios/basic.rs +++ b/ethportal-peertest/src/scenarios/basic.rs @@ -1,7 +1,7 @@ use crate::{utils::fixture_header_by_hash, Peertest, PeertestNode}; use alloy_primitives::{B256, U256}; use ethportal_api::{ - types::{distance::Distance, portal_wire::ProtocolId}, + types::{distance::Distance, network::Subnetwork}, BeaconNetworkApiClient, ContentValue, Discv5ApiClient, HistoryContentKey, HistoryNetworkApiClient, StateNetworkApiClient, Web3ApiClient, }; @@ -29,26 +29,26 @@ pub async fn test_discv5_routing_table_info(target: &Client) { assert!(result.local_node_id.starts_with("0x")); } -pub async fn test_routing_table_info(protocol: ProtocolId, target: &Client) { - info!("Testing routing_table_info for {protocol}"); - let result = match protocol { - ProtocolId::Beacon => BeaconNetworkApiClient::routing_table_info(target), - ProtocolId::History => HistoryNetworkApiClient::routing_table_info(target), - ProtocolId::State => StateNetworkApiClient::routing_table_info(target), - _ => panic!("Unexpected protocol: {protocol}"), +pub async fn test_routing_table_info(subnetwork: Subnetwork, target: &Client) { + info!("Testing routing_table_info for {subnetwork}"); + let result = match subnetwork { + Subnetwork::Beacon => BeaconNetworkApiClient::routing_table_info(target), + Subnetwork::History => HistoryNetworkApiClient::routing_table_info(target), + Subnetwork::State => StateNetworkApiClient::routing_table_info(target), + _ => panic!("Unexpected subnetwork: {subnetwork}"), } .await .unwrap(); assert!(result.local_node_id.starts_with("0x")); } -pub async fn test_radius(protocol: ProtocolId, target: &Client) { - info!("Testing radius for {protocol}"); - let result = match protocol { - ProtocolId::Beacon => BeaconNetworkApiClient::radius(target), - ProtocolId::History => HistoryNetworkApiClient::radius(target), - ProtocolId::State => StateNetworkApiClient::radius(target), - _ => panic!("Unexpected protocol: {protocol}"), +pub async fn test_radius(subnetwork: Subnetwork, target: &Client) { + info!("Testing radius for {subnetwork}"); + let result = match subnetwork { + Subnetwork::Beacon => BeaconNetworkApiClient::radius(target), + Subnetwork::History => HistoryNetworkApiClient::radius(target), + Subnetwork::State => StateNetworkApiClient::radius(target), + _ => panic!("Unexpected subnetwork: {subnetwork}"), } .await .unwrap(); @@ -58,71 +58,71 @@ pub async fn test_radius(protocol: ProtocolId, target: &Client) { ); } -pub async fn test_add_enr(protocol: ProtocolId, target: &Client, peertest: &Peertest) { - info!("Testing add_enr for {protocol}"); +pub async fn test_add_enr(subnetwork: Subnetwork, target: &Client, peertest: &Peertest) { + info!("Testing add_enr for {subnetwork}"); let bootnode_enr = peertest.bootnode.enr.clone(); - let result = match protocol { - ProtocolId::Beacon => BeaconNetworkApiClient::add_enr(target, bootnode_enr), - ProtocolId::History => HistoryNetworkApiClient::add_enr(target, bootnode_enr), - ProtocolId::State => StateNetworkApiClient::add_enr(target, bootnode_enr), - _ => panic!("Unexpected protocol: {protocol}"), + let result = match subnetwork { + Subnetwork::Beacon => BeaconNetworkApiClient::add_enr(target, bootnode_enr), + Subnetwork::History => HistoryNetworkApiClient::add_enr(target, bootnode_enr), + Subnetwork::State => StateNetworkApiClient::add_enr(target, bootnode_enr), + _ => panic!("Unexpected subnetwork: {subnetwork}"), } .await .unwrap(); assert!(result); } -pub async fn test_get_enr(protocol: ProtocolId, target: &Client, peertest: &Peertest) { - info!("Testing get_enr for {protocol}"); +pub async fn test_get_enr(subnetwork: Subnetwork, target: &Client, peertest: &Peertest) { + info!("Testing get_enr for {subnetwork}"); let node_id = peertest.bootnode.enr.node_id(); - let result = match protocol { - ProtocolId::Beacon => BeaconNetworkApiClient::get_enr(target, node_id), - ProtocolId::History => HistoryNetworkApiClient::get_enr(target, node_id), - ProtocolId::State => StateNetworkApiClient::get_enr(target, node_id), - _ => panic!("Unexpected protocol: {protocol}"), + let result = match subnetwork { + Subnetwork::Beacon => BeaconNetworkApiClient::get_enr(target, node_id), + Subnetwork::History => HistoryNetworkApiClient::get_enr(target, node_id), + Subnetwork::State => StateNetworkApiClient::get_enr(target, node_id), + _ => panic!("Unexpected subnetwork: {subnetwork}"), } .await .unwrap(); assert_eq!(result, peertest.bootnode.enr); } -pub async fn test_delete_enr(protocol: ProtocolId, target: &Client, peertest: &Peertest) { - info!("Testing delete_enr for {protocol}"); +pub async fn test_delete_enr(subnetwork: Subnetwork, target: &Client, peertest: &Peertest) { + info!("Testing delete_enr for {subnetwork}"); let node_id = peertest.bootnode.enr.node_id(); - let result = match protocol { - ProtocolId::Beacon => BeaconNetworkApiClient::delete_enr(target, node_id), - ProtocolId::History => HistoryNetworkApiClient::delete_enr(target, node_id), - ProtocolId::State => StateNetworkApiClient::delete_enr(target, node_id), - _ => panic!("Unexpected protocol: {protocol}"), + let result = match subnetwork { + Subnetwork::Beacon => BeaconNetworkApiClient::delete_enr(target, node_id), + Subnetwork::History => HistoryNetworkApiClient::delete_enr(target, node_id), + Subnetwork::State => StateNetworkApiClient::delete_enr(target, node_id), + _ => panic!("Unexpected subnetwork: {subnetwork}"), } .await .unwrap(); assert!(result); } -pub async fn test_lookup_enr(protocol: ProtocolId, peertest: &Peertest) { - info!("Testing lookup_enr for {protocol}"); +pub async fn test_lookup_enr(subnetwork: Subnetwork, peertest: &Peertest) { + info!("Testing lookup_enr for {subnetwork}"); let target = &peertest.bootnode.ipc_client; let node_id = peertest.nodes[0].enr.node_id(); - let result = match protocol { - ProtocolId::Beacon => BeaconNetworkApiClient::lookup_enr(target, node_id), - ProtocolId::History => HistoryNetworkApiClient::lookup_enr(target, node_id), - ProtocolId::State => StateNetworkApiClient::lookup_enr(target, node_id), - _ => panic!("Unexpected protocol: {protocol}"), + let result = match subnetwork { + Subnetwork::Beacon => BeaconNetworkApiClient::lookup_enr(target, node_id), + Subnetwork::History => HistoryNetworkApiClient::lookup_enr(target, node_id), + Subnetwork::State => StateNetworkApiClient::lookup_enr(target, node_id), + _ => panic!("Unexpected subnetwork: {subnetwork}"), } .await .unwrap(); assert_eq!(result, peertest.nodes[0].enr); } -pub async fn test_ping(protocol: ProtocolId, target: &Client, peertest: &Peertest) { - info!("Testing ping for {protocol}"); +pub async fn test_ping(subnetwork: Subnetwork, target: &Client, peertest: &Peertest) { + info!("Testing ping for {subnetwork}"); let bootnode_enr = peertest.bootnode.enr.clone(); - let result = match protocol { - ProtocolId::Beacon => BeaconNetworkApiClient::ping(target, bootnode_enr), - ProtocolId::History => HistoryNetworkApiClient::ping(target, bootnode_enr), - ProtocolId::State => StateNetworkApiClient::ping(target, bootnode_enr), - _ => panic!("Unexpected protocol: {protocol}"), + let result = match subnetwork { + Subnetwork::Beacon => BeaconNetworkApiClient::ping(target, bootnode_enr), + Subnetwork::History => HistoryNetworkApiClient::ping(target, bootnode_enr), + Subnetwork::State => StateNetworkApiClient::ping(target, bootnode_enr), + _ => panic!("Unexpected subnetwork: {subnetwork}"), } .await .unwrap(); @@ -141,14 +141,14 @@ pub async fn test_ping_cross_network(mainnet_target: &Client, angelfood_node: &P }; } -pub async fn test_find_nodes(protocol: ProtocolId, target: &Client, peertest: &Peertest) { - info!("Testing find_nodes for {protocol}"); +pub async fn test_find_nodes(subnetwork: Subnetwork, target: &Client, peertest: &Peertest) { + info!("Testing find_nodes for {subnetwork}"); let bootnode_enr = peertest.bootnode.enr.clone(); - let result = match protocol { - ProtocolId::Beacon => BeaconNetworkApiClient::find_nodes(target, bootnode_enr, vec![256]), - ProtocolId::History => HistoryNetworkApiClient::find_nodes(target, bootnode_enr, vec![256]), - ProtocolId::State => StateNetworkApiClient::find_nodes(target, bootnode_enr, vec![256]), - _ => panic!("Unexpected protocol: {protocol}"), + let result = match subnetwork { + Subnetwork::Beacon => BeaconNetworkApiClient::find_nodes(target, bootnode_enr, vec![256]), + Subnetwork::History => HistoryNetworkApiClient::find_nodes(target, bootnode_enr, vec![256]), + Subnetwork::State => StateNetworkApiClient::find_nodes(target, bootnode_enr, vec![256]), + _ => panic!("Unexpected subnetwork: {subnetwork}"), } .await .unwrap(); @@ -156,17 +156,17 @@ pub async fn test_find_nodes(protocol: ProtocolId, target: &Client, peertest: &P } pub async fn test_find_nodes_zero_distance( - protocol: ProtocolId, + subnetwork: Subnetwork, target: &Client, peertest: &Peertest, ) { - info!("Testing find_nodes with zero distance for {protocol}"); + info!("Testing find_nodes with zero distance for {subnetwork}"); let bootnode_enr = peertest.bootnode.enr.clone(); - let result = match protocol { - ProtocolId::Beacon => BeaconNetworkApiClient::find_nodes(target, bootnode_enr, vec![0]), - ProtocolId::History => HistoryNetworkApiClient::find_nodes(target, bootnode_enr, vec![0]), - ProtocolId::State => StateNetworkApiClient::find_nodes(target, bootnode_enr, vec![0]), - _ => panic!("Unexpected protocol: {protocol}"), + let result = match subnetwork { + Subnetwork::Beacon => BeaconNetworkApiClient::find_nodes(target, bootnode_enr, vec![0]), + Subnetwork::History => HistoryNetworkApiClient::find_nodes(target, bootnode_enr, vec![0]), + Subnetwork::State => StateNetworkApiClient::find_nodes(target, bootnode_enr, vec![0]), + _ => panic!("Unexpected subnetwork: {subnetwork}"), } .await .unwrap(); diff --git a/ethportal-peertest/src/scenarios/find.rs b/ethportal-peertest/src/scenarios/find.rs index 0b9bf1d0d..ba8e71c1b 100644 --- a/ethportal-peertest/src/scenarios/find.rs +++ b/ethportal-peertest/src/scenarios/find.rs @@ -6,39 +6,39 @@ use tracing::info; use crate::{utils::fixture_header_by_hash, Peertest}; use ethportal_api::{ - types::{portal::ContentInfo, portal_wire::ProtocolId}, + types::{network::Subnetwork, portal::ContentInfo}, utils::bytes::hex_decode, BeaconNetworkApiClient, ContentValue, Enr, HistoryNetworkApiClient, OverlayContentKey, StateNetworkApiClient, }; -pub async fn test_recursive_find_nodes_self(protocol: ProtocolId, peertest: &Peertest) { - info!("Testing recursive find nodes self for {protocol}"); +pub async fn test_recursive_find_nodes_self(subnetwork: Subnetwork, peertest: &Peertest) { + info!("Testing recursive find nodes self for {subnetwork}"); let target_enr = peertest.bootnode.enr.clone(); let target_node_id = NodeId::from(target_enr.node_id().raw()); let result = - call_recursive_find_nodes(protocol, &peertest.bootnode.ipc_client, target_node_id).await; + call_recursive_find_nodes(subnetwork, &peertest.bootnode.ipc_client, target_node_id).await; assert_eq!(result, vec![target_enr]); } -pub async fn test_recursive_find_nodes_peer(protocol: ProtocolId, peertest: &Peertest) { - info!("Testing recursive find nodes peer for {protocol}"); +pub async fn test_recursive_find_nodes_peer(subnetwork: Subnetwork, peertest: &Peertest) { + info!("Testing recursive find nodes peer for {subnetwork}"); let target_enr = peertest.nodes[0].enr.clone(); let target_node_id = NodeId::from(target_enr.node_id().raw()); let result = - call_recursive_find_nodes(protocol, &peertest.bootnode.ipc_client, target_node_id).await; + call_recursive_find_nodes(subnetwork, &peertest.bootnode.ipc_client, target_node_id).await; assert_eq!(result, vec![target_enr]); } -pub async fn test_recursive_find_nodes_random(protocol: ProtocolId, peertest: &Peertest) { - info!("Testing recursive find nodes random for {protocol}"); +pub async fn test_recursive_find_nodes_random(subnetwork: Subnetwork, peertest: &Peertest) { + info!("Testing recursive find nodes random for {subnetwork}"); let mut bytes = [0u8; 32]; let random_node_id = hex_decode("0xcac75e7e776d84fba55a3104bdccfd716537bca3ad8465113f67f04d62694183").unwrap(); bytes.copy_from_slice(&random_node_id); let target_node_id = NodeId::from(bytes); let result = - call_recursive_find_nodes(protocol, &peertest.bootnode.ipc_client, target_node_id).await; + call_recursive_find_nodes(subnetwork, &peertest.bootnode.ipc_client, target_node_id).await; assert_eq!(result.len(), 2); } @@ -180,15 +180,15 @@ pub async fn test_trace_recursive_find_content_local_db(peertest: &Peertest) { } async fn call_recursive_find_nodes( - protocol: ProtocolId, + subnetwork: Subnetwork, client: &Client, node_id: NodeId, ) -> Vec { - match protocol { - ProtocolId::Beacon => BeaconNetworkApiClient::recursive_find_nodes(client, node_id), - ProtocolId::History => HistoryNetworkApiClient::recursive_find_nodes(client, node_id), - ProtocolId::State => StateNetworkApiClient::recursive_find_nodes(client, node_id), - _ => panic!("Unexpected protocol: {protocol}"), + match subnetwork { + Subnetwork::Beacon => BeaconNetworkApiClient::recursive_find_nodes(client, node_id), + Subnetwork::History => HistoryNetworkApiClient::recursive_find_nodes(client, node_id), + Subnetwork::State => StateNetworkApiClient::recursive_find_nodes(client, node_id), + _ => panic!("Unexpected subnetwork: {subnetwork}"), } .await .unwrap() diff --git a/portal-bridge/src/cli.rs b/portal-bridge/src/cli.rs index 4fdda3c78..939eceb08 100644 --- a/portal-bridge/src/cli.rs +++ b/portal-bridge/src/cli.rs @@ -1,4 +1,4 @@ -use std::{env, net::SocketAddr, path::PathBuf, str::FromStr, sync::Arc}; +use std::{env, net::SocketAddr, path::PathBuf, sync::Arc}; use alloy_primitives::B256; use clap::Parser; @@ -240,7 +240,7 @@ impl ClientWithBaseUrl { fn subnetwork_parser(subnetwork_string: &str) -> Result>, String> { let active_subnetworks: Vec = subnetwork_string .split(',') - .map(Subnetwork::from_str) + .map(Subnetwork::from_cli_arg) .collect::, String>>()?; if active_subnetworks.contains(&Subnetwork::State) && active_subnetworks.len() > 1 { return Err("The State network doesn't support being ran with other subnetwork bridges at the same time".to_string()); diff --git a/portal-bridge/src/handle.rs b/portal-bridge/src/handle.rs index 9addbfb31..fe842ca74 100644 --- a/portal-bridge/src/handle.rs +++ b/portal-bridge/src/handle.rs @@ -65,8 +65,9 @@ pub fn subnetworks_flag(bridge_config: &BridgeConfig) -> String { Subnetwork::History => vec![Subnetwork::History], // State requires both history and state Subnetwork::State => vec![Subnetwork::History, Subnetwork::State], + _ => panic!("Unsupported subnetwork: {subnetwork:?}"), }) - .map(|network_kind| network_kind.to_string()) + .map(|network_kind| network_kind.to_cli_arg()) .collect::>(); Vec::from_iter(subnetworks).join(",") } diff --git a/portalnet/src/discovery.rs b/portalnet/src/discovery.rs index 4a97797a4..a01e40f7f 100644 --- a/portalnet/src/discovery.rs +++ b/portalnet/src/discovery.rs @@ -25,11 +25,7 @@ use utp_rs::{cid::ConnectionPeer, udp::AsyncUdpSocket}; use super::config::PortalnetConfig; use crate::socket; use ethportal_api::{ - types::{ - discv5::RoutingTableInfo, - enr::Enr, - portal_wire::{NetworkSpec, ProtocolId}, - }, + types::{discv5::RoutingTableInfo, enr::Enr, network::Subnetwork, portal_wire::NetworkSpec}, utils::bytes::{hex_decode, hex_encode}, NodeInfo, }; @@ -339,14 +335,19 @@ impl Discovery { pub async fn send_talk_req( &self, enr: Enr, - protocol: ProtocolId, + subnetwork: Subnetwork, request: ProtocolRequest, ) -> Result, RequestError> { // Send empty protocol id if unable to convert it to bytes - let protocol = match self.network_spec.get_protocol_hex_from_id(&protocol) { + let protocol = match self + .network_spec + .get_protocol_identifier_from_subnetwork(&subnetwork) + { Ok(protocol_id) => hex_decode(&protocol_id).unwrap_or_default(), Err(err) => { - unreachable!("send_talk_req() should never receive an invalid ProtocolId protocol: err={err}"); + unreachable!( + "send_talk_req() should never receive an invalid Subnetwork: err={err}" + ); } }; @@ -484,7 +485,7 @@ impl AsyncUdpSocket for Discv5UdpSocket { let target = target.0.clone(); let data = buf.to_vec(); tokio::spawn(async move { - match discv5.send_talk_req(target, ProtocolId::Utp, data).await { + match discv5.send_talk_req(target, Subnetwork::Utp, data).await { // We drop the talk response because it is ignored in the uTP protocol. Ok(..) => {} Err(err) => match err { diff --git a/portalnet/src/events.rs b/portalnet/src/events.rs index c14ee698f..035b921fc 100644 --- a/portalnet/src/events.rs +++ b/portalnet/src/events.rs @@ -10,10 +10,7 @@ use tokio_stream::wrappers::BroadcastStream; use tracing::{debug, error, trace, warn}; use ethportal_api::{ - types::{ - network::Subnetwork, - portal_wire::{NetworkSpec, ProtocolId}, - }, + types::{network::Subnetwork, portal_wire::NetworkSpec}, utils::bytes::{hex_encode, hex_encode_upper}, }; @@ -125,35 +122,35 @@ impl PortalnetEvents { /// Dispatch Discv5 TalkRequest event to overlay networks or uTP socket fn dispatch_discv5_talk_req(&self, request: TalkRequest) { - let protocol_id = self + let subnetwork = self .network_spec - .get_protocol_id_from_hex(&hex_encode_upper(request.protocol())); + .get_subnetwork_from_protocol_identifier(&hex_encode_upper(request.protocol())); - match protocol_id { - Ok(protocol) => match protocol { - ProtocolId::History => self.send_overlay_request( + match subnetwork { + Ok(subnetwork) => match subnetwork { + Subnetwork::History => self.send_overlay_request( self.history_handle.tx.as_ref(), request.into(), Subnetwork::History, ), - ProtocolId::Beacon => self.send_overlay_request( + Subnetwork::Beacon => self.send_overlay_request( self.beacon_handle.tx.as_ref(), request.into(), Subnetwork::Beacon, ), - ProtocolId::State => self.send_overlay_request( + Subnetwork::State => self.send_overlay_request( self.state_handle.tx.as_ref(), request.into(), Subnetwork::State, ), - ProtocolId::Utp => { + Subnetwork::Utp => { if let Err(err) = self.utp_talk_reqs.send(request) { error!(%err, "Error forwarding talk request to uTP socket"); } } _ => { warn!( - "Received TalkRequest on non-supported protocol from={} protocol={} body={}", + "Received TalkRequest on unsupported subnetwork from={} protocol={} body={}", request.node_id(), hex_encode_upper(request.protocol()), hex_encode(request.body()), @@ -172,11 +169,11 @@ impl PortalnetEvents { fn dispatch_overlay_event(&self, event: EventEnvelope) { use OverlayRequest::Event; - let all_protocols = vec![ProtocolId::History, ProtocolId::Beacon, ProtocolId::State]; + let all_subnetworks = vec![Subnetwork::History, Subnetwork::Beacon, Subnetwork::State]; let mut recipients = event .destination .as_ref() - .unwrap_or(&all_protocols) + .unwrap_or(&all_subnetworks) .to_owned(); recipients.retain(|id| id != &event.from); @@ -185,21 +182,21 @@ impl PortalnetEvents { error!("No valid recipients for this event"); } - if recipients.contains(&ProtocolId::Beacon) { + if recipients.contains(&Subnetwork::Beacon) { self.send_overlay_request( self.beacon_handle.tx.as_ref(), Event(event.clone()), Subnetwork::Beacon, ); } - if recipients.contains(&ProtocolId::State) { + if recipients.contains(&Subnetwork::State) { self.send_overlay_request( self.state_handle.tx.as_ref(), Event(event.clone()), Subnetwork::State, ); } - if recipients.contains(&ProtocolId::History) { + if recipients.contains(&Subnetwork::History) { self.send_overlay_request( self.history_handle.tx.as_ref(), Event(event.clone()), @@ -273,21 +270,21 @@ impl From for Timestamp { pub struct EventEnvelope { /// The timestamp of this event's generation. pub timestamp: Timestamp, - /// The protocol that generated this event. - pub from: ProtocolId, + /// The subnetwork that generated this event. + pub from: Subnetwork, /// The event payload. pub payload: OverlayEvent, - /// Specifies the protocols to which this event should be sent. + /// Specifies the subnetworks to which this event should be sent. /// /// A value of `None` is taken to indicate `all protocols`. - pub destination: Option>, + pub destination: Option>, } impl EventEnvelope { pub fn new( payload: OverlayEvent, - from: ProtocolId, - destination: Option>, + from: Subnetwork, + destination: Option>, ) -> Self { let timestamp = Timestamp::now(); Self { diff --git a/portalnet/src/overlay/protocol.rs b/portalnet/src/overlay/protocol.rs index 074abb3c3..b376d06fe 100644 --- a/portalnet/src/overlay/protocol.rs +++ b/portalnet/src/overlay/protocol.rs @@ -41,9 +41,10 @@ use ethportal_api::{ discv5::RoutingTableInfo, distance::{Distance, Metric}, enr::Enr, + network::Subnetwork, portal_wire::{ Accept, Content, CustomPayload, FindContent, FindNodes, Message, Nodes, Ping, Pong, - PopulatedOffer, PopulatedOfferWithResult, ProtocolId, Request, Response, + PopulatedOffer, PopulatedOfferWithResult, Request, Response, }, }, utils::bytes::hex_encode, @@ -70,7 +71,7 @@ pub struct OverlayProtocol { /// The overlay routing table of the local node. kbuckets: Arc>>, /// The subnetwork protocol of the overlay. - protocol: ProtocolId, + protocol: Subnetwork, /// A sender to send commands to the OverlayService. pub command_tx: UnboundedSender>, /// uTP controller. @@ -101,7 +102,7 @@ where discovery: Arc, utp_socket: Arc>, store: Arc>, - protocol: ProtocolId, + protocol: Subnetwork, validator: Arc, ) -> Self { let kbuckets = Arc::new(RwLock::new(KBucketsTable::new( @@ -156,7 +157,7 @@ where } /// Returns the subnetwork protocol of the overlay protocol. - pub fn protocol(&self) -> &ProtocolId { + pub fn protocol(&self) -> &Subnetwork { &self.protocol } diff --git a/portalnet/src/overlay/service.rs b/portalnet/src/overlay/service.rs index 308646582..6ca8f96f5 100644 --- a/portalnet/src/overlay/service.rs +++ b/portalnet/src/overlay/service.rs @@ -70,9 +70,10 @@ use ethportal_api::{ types::{ distance::{Distance, Metric}, enr::{Enr, SszEnr}, + network::Subnetwork, portal_wire::{ Accept, Content, CustomPayload, FindContent, FindNodes, Message, Nodes, Offer, Ping, - Pong, PopulatedOffer, ProtocolId, Request, Response, MAX_PORTAL_CONTENT_PAYLOAD_SIZE, + Pong, PopulatedOffer, Request, Response, MAX_PORTAL_CONTENT_PAYLOAD_SIZE, MAX_PORTAL_NODES_ENRS_SIZE, }, query_trace::QueryTrace, @@ -112,7 +113,7 @@ where /// The routing table of the local node. kbuckets: Arc>>, /// The protocol identifier. - protocol: ProtocolId, + protocol: Subnetwork, /// A queue of peers that require regular ping to check connectivity. /// Inserted entries expire after a fixed time. Nodes to be pinged are inserted with a timeout /// duration equal to some ping interval, and we continuously poll the queue to check for @@ -183,7 +184,7 @@ where kbuckets: Arc>>, bootnode_enrs: Vec, ping_queue_interval: Option, - protocol: ProtocolId, + protocol: Subnetwork, utp_controller: Arc, metrics: OverlayMetricsReporter, validator: Arc, @@ -464,7 +465,7 @@ where /// result is recorded when a pending bucket entry replaces a disconnected entry in the /// respective bucket. async fn bucket_maintenance_poll( - protocol: ProtocolId, + protocol: Subnetwork, kbuckets: &Arc>>, ) { future::poll_fn(move |_cx| { @@ -2615,7 +2616,7 @@ where /// Send `OverlayEvent` to the event stream. #[allow(dead_code)] // TODO: remove when used - fn send_event(&self, event: OverlayEvent, to: Option>) { + fn send_event(&self, event: OverlayEvent, to: Option>) { trace!( "Sending event={:?} to event-stream from protocol {}", event, @@ -2818,7 +2819,7 @@ mod tests { overlay_config.bucket_filter, ))); - let protocol = ProtocolId::History; + let protocol = Subnetwork::History; let active_outgoing_requests = Arc::new(RwLock::new(HashMap::new())); let peers_to_ping = HashSetDelay::default(); let (command_tx, command_rx) = mpsc::unbounded_channel(); diff --git a/portalnet/tests/overlay.rs b/portalnet/tests/overlay.rs index 892cccba3..051983eeb 100644 --- a/portalnet/tests/overlay.rs +++ b/portalnet/tests/overlay.rs @@ -17,7 +17,8 @@ use ethportal_api::{ content_key::overlay::IdentityContentKey, distance::XorMetric, enr::{Enr, SszEnr}, - portal_wire::{Content, Message, ProtocolId, MAINNET}, + network::Subnetwork, + portal_wire::{Content, Message, MAINNET}, }, utils::bytes::hex_encode_upper, }; @@ -31,7 +32,7 @@ use trin_validation::{oracle::HeaderOracle, validator::MockValidator}; async fn init_overlay( discovery: Arc, - protocol: ProtocolId, + subnetwork: Subnetwork, ) -> OverlayProtocol { let overlay_config = OverlayConfig::default(); @@ -53,7 +54,7 @@ async fn init_overlay( discovery, utp_socket, store, - protocol, + subnetwork, validator, ) .await @@ -68,17 +69,17 @@ async fn spawn_overlay( let overlay_protocol = *overlay.protocol(); tokio::spawn(async move { while let Some(talk_req) = talk_req_rx.recv().await { - let req_protocol = - MAINNET.get_protocol_id_from_hex(&hex_encode_upper(talk_req.protocol())); + let req_subnetwork = MAINNET + .get_subnetwork_from_protocol_identifier(&hex_encode_upper(talk_req.protocol())); - if let Ok(req_protocol) = req_protocol { - match (req_protocol, overlay_protocol) { - (ProtocolId::History, ProtocolId::History) - | (ProtocolId::State, ProtocolId::State) => overlay_tx.send(talk_req).unwrap(), - _ => panic!("Unexpected protocol"), + if let Ok(req_subnetwork) = req_subnetwork { + match (req_subnetwork, overlay_protocol) { + (Subnetwork::History, Subnetwork::History) + | (Subnetwork::State, Subnetwork::State) => overlay_tx.send(talk_req).unwrap(), + _ => panic!("Unexpected subnetwork"), } } else { - panic!("Invalid protocol"); + panic!("Invalid subnetwork"); } } }); @@ -102,7 +103,7 @@ async fn spawn_overlay( // Use sleeps to give time for background routing table processes. #[test_log::test(tokio::test)] async fn overlay() { - let protocol = ProtocolId::History; + let protocol = Subnetwork::History; let sleep_duration = Duration::from_millis(5); let ip_addr = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)); @@ -268,7 +269,7 @@ async fn overlay_event_stream() { let temp_dir = create_temp_test_dir().unwrap(); let discovery = Arc::new(Discovery::new(portal_config, temp_dir.path(), MAINNET.clone()).unwrap()); - let overlay = init_overlay(discovery, ProtocolId::Beacon).await; + let overlay = init_overlay(discovery, Subnetwork::Beacon).await; overlay.event_stream().await.unwrap(); temp_dir.close().unwrap(); diff --git a/rpc/src/lib.rs b/rpc/src/lib.rs index f35a27388..6345b62ec 100644 --- a/rpc/src/lib.rs +++ b/rpc/src/lib.rs @@ -61,6 +61,7 @@ pub async fn launch_jsonrpc_server( } Subnetwork::State => modules.push(PortalRpcModule::State), Subnetwork::Beacon => modules.push(PortalRpcModule::Beacon), + _ => return Err(RpcError::Custom("Unsupported subnetwork".to_string())), } } diff --git a/src/bin/purge_invalid_history_content.rs b/src/bin/purge_invalid_history_content.rs index 9fcf3b0e8..0a485565d 100644 --- a/src/bin/purge_invalid_history_content.rs +++ b/src/bin/purge_invalid_history_content.rs @@ -4,10 +4,7 @@ use clap::Parser; use discv5::enr::{CombinedKey, Enr}; use tracing::info; -use ethportal_api::types::{ - network::{Network, Subnetwork}, - portal_wire::ProtocolId, -}; +use ethportal_api::types::network::{Network, Subnetwork}; use portalnet::utils::db::{configure_node_data_dir, configure_trin_data_dir}; use trin_storage::{ versioned::{ContentType, IdIndexedV1StoreConfig}, @@ -39,7 +36,7 @@ pub fn main() -> Result<()> { ) .unwrap() .create(&Subnetwork::History); - let config = IdIndexedV1StoreConfig::new(ContentType::History, ProtocolId::History, config); + let config = IdIndexedV1StoreConfig::new(ContentType::History, Subnetwork::History, config); let sql_connection_pool = config.sql_connection_pool.clone(); let total_count = sql_connection_pool .get() diff --git a/tests/self_peertest.rs b/tests/self_peertest.rs index 9d716a657..fa437dead 100644 --- a/tests/self_peertest.rs +++ b/tests/self_peertest.rs @@ -8,7 +8,6 @@ use std::{ use ethportal_api::types::{ cli::{TrinConfig, DEFAULT_WEB3_HTTP_ADDRESS, DEFAULT_WEB3_IPC_PATH}, network::{Network, Subnetwork}, - portal_wire::ProtocolId, }; use ethportal_peertest as peertest; use ethportal_peertest::Peertest; @@ -39,20 +38,20 @@ async fn peertest_stateless() { peertest::scenarios::basic::test_discv5_routing_table_info(&target).await; peertest::scenarios::eth_rpc::test_eth_chain_id(&peertest).await; - for protocol in [ProtocolId::History, ProtocolId::Beacon, ProtocolId::State] { - peertest::scenarios::basic::test_routing_table_info(protocol, &target).await; - peertest::scenarios::basic::test_radius(protocol, &target).await; - peertest::scenarios::basic::test_add_enr(protocol, &target, &peertest).await; - peertest::scenarios::basic::test_get_enr(protocol, &target, &peertest).await; - peertest::scenarios::basic::test_delete_enr(protocol, &target, &peertest).await; - peertest::scenarios::basic::test_lookup_enr(protocol, &peertest).await; - peertest::scenarios::basic::test_ping(protocol, &target, &peertest).await; - peertest::scenarios::basic::test_find_nodes(protocol, &target, &peertest).await; - peertest::scenarios::basic::test_find_nodes_zero_distance(protocol, &target, &peertest) + for subnetwork in [Subnetwork::History, Subnetwork::Beacon, Subnetwork::State] { + peertest::scenarios::basic::test_routing_table_info(subnetwork, &target).await; + peertest::scenarios::basic::test_radius(subnetwork, &target).await; + peertest::scenarios::basic::test_add_enr(subnetwork, &target, &peertest).await; + peertest::scenarios::basic::test_get_enr(subnetwork, &target, &peertest).await; + peertest::scenarios::basic::test_delete_enr(subnetwork, &target, &peertest).await; + peertest::scenarios::basic::test_lookup_enr(subnetwork, &peertest).await; + peertest::scenarios::basic::test_ping(subnetwork, &target, &peertest).await; + peertest::scenarios::basic::test_find_nodes(subnetwork, &target, &peertest).await; + peertest::scenarios::basic::test_find_nodes_zero_distance(subnetwork, &target, &peertest) .await; - peertest::scenarios::find::test_recursive_find_nodes_self(protocol, &peertest).await; - peertest::scenarios::find::test_recursive_find_nodes_peer(protocol, &peertest).await; - peertest::scenarios::find::test_recursive_find_nodes_random(protocol, &peertest).await; + peertest::scenarios::find::test_recursive_find_nodes_self(subnetwork, &peertest).await; + peertest::scenarios::find::test_recursive_find_nodes_peer(subnetwork, &peertest).await; + peertest::scenarios::find::test_recursive_find_nodes_random(subnetwork, &peertest).await; } peertest::scenarios::basic::test_history_store(&target).await; @@ -345,7 +344,7 @@ async fn peertest_ping_cross_discv5_protocol_id() { "--network", &Network::Mainnet.to_string(), "--portal-subnetworks", - &Subnetwork::History.to_string(), + &Subnetwork::History.to_cli_arg(), "--external-address", external_addr.as_str(), "--web3-ipc-path", @@ -399,7 +398,7 @@ async fn setup_peertest( "--portal-subnetworks", &subnetworks .iter() - .map(|s| s.to_string()) + .map(|s| s.to_cli_arg()) .collect::>() .join(","), "--external-address", @@ -441,7 +440,7 @@ async fn setup_peertest_bridge( let external_addr = format!("{test_ip_addr}:{test_discovery_port}"); let subnetworks = subnetworks .iter() - .map(|s| s.to_string()) + .map(|s| s.to_cli_arg()) .collect::>() .join(","); diff --git a/trin-beacon/src/network.rs b/trin-beacon/src/network.rs index 954f9acdf..72714929e 100644 --- a/trin-beacon/src/network.rs +++ b/trin-beacon/src/network.rs @@ -7,7 +7,7 @@ use utp_rs::socket::UtpSocket; use crate::{storage::BeaconStorage, sync::BeaconSync, validation::BeaconValidator}; use ethportal_api::{ - types::{distance::XorMetric, enr::Enr, portal_wire::ProtocolId}, + types::{distance::XorMetric, enr::Enr, network::Subnetwork}, BeaconContentKey, }; use light_client::{consensus::rpc::portal_rpc::PortalRpc, database::FileDB, Client}; @@ -54,7 +54,7 @@ impl BeaconNetwork { discovery, utp_socket, storage, - ProtocolId::Beacon, + Subnetwork::Beacon, validator, ) .await; diff --git a/trin-beacon/src/storage.rs b/trin-beacon/src/storage.rs index 9ea34ea4f..9745137d3 100644 --- a/trin-beacon/src/storage.rs +++ b/trin-beacon/src/storage.rs @@ -13,8 +13,8 @@ use ethportal_api::{ LightClientUpdatesByRange, }, distance::Distance, + network::Subnetwork, portal::PaginateLocalContentInfo, - portal_wire::ProtocolId, }, BeaconContentKey, OverlayContentKey, RawContentKey, }; @@ -309,7 +309,7 @@ impl BeaconStorage { let storage = Self { node_data_dir: config.node_data_dir, sql_connection_pool: config.sql_connection_pool, - metrics: StorageMetricsReporter::new(ProtocolId::Beacon), + metrics: StorageMetricsReporter::new(Subnetwork::Beacon), cache: BeaconStorageCache::new(), }; diff --git a/trin-history/src/network.rs b/trin-history/src/network.rs index 75274ab44..ed4171d98 100644 --- a/trin-history/src/network.rs +++ b/trin-history/src/network.rs @@ -6,7 +6,7 @@ use utp_rs::socket::UtpSocket; use crate::storage::HistoryStorage; use ethportal_api::{ - types::{distance::XorMetric, enr::Enr, portal_wire::ProtocolId}, + types::{distance::XorMetric, enr::Enr, network::Subnetwork}, HistoryContentKey, }; use portalnet::{ @@ -54,7 +54,7 @@ impl HistoryNetwork { discovery, utp_socket, storage, - ProtocolId::History, + Subnetwork::History, validator, ) .await; diff --git a/trin-history/src/storage.rs b/trin-history/src/storage.rs index 475b09a70..ff90f3114 100644 --- a/trin-history/src/storage.rs +++ b/trin-history/src/storage.rs @@ -1,5 +1,5 @@ use ethportal_api::{ - types::{distance::Distance, portal::PaginateLocalContentInfo, portal_wire::ProtocolId}, + types::{distance::Distance, network::Subnetwork, portal::PaginateLocalContentInfo}, HistoryContentKey, OverlayContentKey, }; use trin_storage::{ @@ -51,7 +51,7 @@ impl ContentStore for HistoryStorage { impl HistoryStorage { pub fn new(config: PortalStorageConfig) -> Result { let sql_connection_pool = config.sql_connection_pool.clone(); - let config = IdIndexedV1StoreConfig::new(ContentType::History, ProtocolId::History, config); + let config = IdIndexedV1StoreConfig::new(ContentType::History, Subnetwork::History, config); Ok(Self { store: create_store(ContentType::History, config, sql_connection_pool)?, }) diff --git a/trin-metrics/src/labels.rs b/trin-metrics/src/labels.rs index 881e0cc1b..63cbbac42 100644 --- a/trin-metrics/src/labels.rs +++ b/trin-metrics/src/labels.rs @@ -1,21 +1,7 @@ -use ethportal_api::types::portal_wire::{ProtocolId, Request, Response}; +use ethportal_api::types::portal_wire::{Request, Response}; pub type MetricLabel = &'static str; -impl From for MetricLabel { - fn from(label: ProtocolLabel) -> Self { - match label { - ProtocolLabel::State => "state", - ProtocolLabel::VerkleState => "verkle_state", - ProtocolLabel::History => "history", - ProtocolLabel::TransactionGossip => "transaction_gossip", - ProtocolLabel::CanonicalIndices => "canonical_indices", - ProtocolLabel::Beacon => "beacon", - ProtocolLabel::Utp => "utp", - } - } -} - impl From for MetricLabel { fn from(label: MessageDirectionLabel) -> Self { match label { @@ -24,6 +10,7 @@ impl From for MetricLabel { } } } + impl From for MetricLabel { fn from(label: MessageLabel) -> Self { match label { @@ -38,6 +25,7 @@ impl From for MetricLabel { } } } + impl From for MetricLabel { fn from(label: UtpDirectionLabel) -> Self { match label { @@ -84,18 +72,6 @@ impl From<&Response> for MessageLabel { } } } -/// Protocol Labels -/// - These label values identify the protocol in the metrics -#[derive(Debug, Clone, Copy)] -pub enum ProtocolLabel { - State, - VerkleState, - History, - TransactionGossip, - CanonicalIndices, - Beacon, - Utp, -} /// Message Direction Labels pub enum MessageDirectionLabel { @@ -118,19 +94,6 @@ pub enum MessageLabel { Accept, } -impl From<&ProtocolId> for ProtocolLabel { - fn from(protocol: &ProtocolId) -> Self { - match protocol { - ProtocolId::State => Self::State, - ProtocolId::VerkleState => Self::VerkleState, - ProtocolId::History => Self::History, - ProtocolId::TransactionGossip => Self::TransactionGossip, - ProtocolId::CanonicalIndices => Self::CanonicalIndices, - ProtocolId::Beacon => Self::Beacon, - ProtocolId::Utp => Self::Utp, - } - } -} /// uTP Transfer Direction Labels #[derive(Debug, Clone, Copy)] pub enum UtpDirectionLabel { diff --git a/trin-metrics/src/storage.rs b/trin-metrics/src/storage.rs index cada23f41..2e5a415f0 100644 --- a/trin-metrics/src/storage.rs +++ b/trin-metrics/src/storage.rs @@ -1,6 +1,6 @@ use std::time::Duration; -use ethportal_api::types::{distance::Distance, portal_wire::ProtocolId}; +use ethportal_api::types::{distance::Distance, network::Subnetwork}; use prometheus_exporter::{ self, prometheus::{ @@ -90,10 +90,10 @@ pub struct StorageMetricsReporter { } impl StorageMetricsReporter { - pub fn new(protocol_id: ProtocolId) -> Self { + pub fn new(subnetwork: Subnetwork) -> Self { Self { storage_metrics: PORTALNET_METRICS.storage(), - protocol: protocol_id.to_string(), + protocol: subnetwork.to_string(), } } diff --git a/trin-state/src/network.rs b/trin-state/src/network.rs index 207fbd723..af9c040fe 100644 --- a/trin-state/src/network.rs +++ b/trin-state/src/network.rs @@ -6,7 +6,7 @@ use utp_rs::socket::UtpSocket; use crate::storage::StateStorage; use ethportal_api::{ - types::{distance::XorMetric, portal_wire::ProtocolId}, + types::{distance::XorMetric, network::Subnetwork}, StateContentKey, }; use portalnet::{ @@ -58,7 +58,7 @@ impl StateNetwork { discovery, utp_socket, storage, - ProtocolId::State, + Subnetwork::State, validator, ) .await; diff --git a/trin-state/src/storage.rs b/trin-state/src/storage.rs index 9a59782df..9bfa1b4f3 100644 --- a/trin-state/src/storage.rs +++ b/trin-state/src/storage.rs @@ -4,8 +4,8 @@ use ethportal_api::{ content_key::state::{AccountTrieNodeKey, ContractBytecodeKey, ContractStorageTrieNodeKey}, content_value::state::{ContractBytecode, TrieNode}, distance::Distance, + network::Subnetwork, portal::PaginateLocalContentInfo, - portal_wire::ProtocolId, }, ContentValue, OverlayContentKey, StateContentKey, StateContentValue, }; @@ -72,7 +72,7 @@ impl ContentStore for StateStorage { impl StateStorage { pub fn new(config: PortalStorageConfig) -> Result { let sql_connection_pool = config.sql_connection_pool.clone(); - let config = IdIndexedV1StoreConfig::new(ContentType::State, ProtocolId::State, config); + let config = IdIndexedV1StoreConfig::new(ContentType::State, Subnetwork::State, config); Ok(Self { store: create_store(ContentType::State, config, sql_connection_pool)?, }) diff --git a/trin-storage/src/config.rs b/trin-storage/src/config.rs index 0e1500a56..95c650b9a 100644 --- a/trin-storage/src/config.rs +++ b/trin-storage/src/config.rs @@ -63,6 +63,7 @@ impl PortalStorageConfigFactory { Subnetwork::History => Self::HISTORY_CAPACITY_WEIGHT, Subnetwork::State => Self::STATE_CAPACITY_WEIGHT, Subnetwork::Beacon => Self::BEACON_CAPACITY_WEIGHT, + _ => unreachable!("Subnetwork not activated: {subnetwork:?}"), } } } diff --git a/trin-storage/src/versioned/id_indexed_v1/config.rs b/trin-storage/src/versioned/id_indexed_v1/config.rs index 56f369829..b27d31e93 100644 --- a/trin-storage/src/versioned/id_indexed_v1/config.rs +++ b/trin-storage/src/versioned/id_indexed_v1/config.rs @@ -1,7 +1,7 @@ use std::path::PathBuf; use discv5::enr::NodeId; -use ethportal_api::types::portal_wire::ProtocolId; +use ethportal_api::types::network::Subnetwork; use r2d2::Pool; use r2d2_sqlite::SqliteConnectionManager; @@ -13,7 +13,7 @@ use super::pruning_strategy::PruningConfig; #[derive(Clone, Debug)] pub struct IdIndexedV1StoreConfig { pub content_type: ContentType, - pub network: ProtocolId, + pub subnetwork: Subnetwork, pub node_id: NodeId, pub node_data_dir: PathBuf, pub storage_capacity_bytes: u64, @@ -25,12 +25,12 @@ pub struct IdIndexedV1StoreConfig { impl IdIndexedV1StoreConfig { pub fn new( content_type: ContentType, - network: ProtocolId, + subnetwork: Subnetwork, config: PortalStorageConfig, ) -> Self { Self { content_type, - network, + subnetwork, node_id: config.node_id, node_data_dir: config.node_data_dir, storage_capacity_bytes: config.storage_capacity_bytes, diff --git a/trin-storage/src/versioned/id_indexed_v1/migration.rs b/trin-storage/src/versioned/id_indexed_v1/migration.rs index d06358f3c..4064911ed 100644 --- a/trin-storage/src/versioned/id_indexed_v1/migration.rs +++ b/trin-storage/src/versioned/id_indexed_v1/migration.rs @@ -50,7 +50,7 @@ mod tests { use std::collections::HashMap; use anyhow::Result; - use ethportal_api::{types::portal_wire::ProtocolId, IdentityContentKey, OverlayContentKey}; + use ethportal_api::{types::network::Subnetwork, IdentityContentKey, OverlayContentKey}; use rand::Rng; use crate::{ @@ -134,7 +134,7 @@ mod tests { legacy_history::create_store(&config)?; // migrate - let config = IdIndexedV1StoreConfig::new(ContentType::History, ProtocolId::History, config); + let config = IdIndexedV1StoreConfig::new(ContentType::History, Subnetwork::History, config); migrate_legacy_history_store(&config)?; // make sure we can initialize new store and that it's empty @@ -160,7 +160,7 @@ mod tests { } // migrate - let config = IdIndexedV1StoreConfig::new(ContentType::History, ProtocolId::History, config); + let config = IdIndexedV1StoreConfig::new(ContentType::History, Subnetwork::History, config); migrate_legacy_history_store(&config)?; // create IdIndexedV1Store and verify content diff --git a/trin-storage/src/versioned/id_indexed_v1/pruning_strategy.rs b/trin-storage/src/versioned/id_indexed_v1/pruning_strategy.rs index 8e6bb5d67..851d91732 100644 --- a/trin-storage/src/versioned/id_indexed_v1/pruning_strategy.rs +++ b/trin-storage/src/versioned/id_indexed_v1/pruning_strategy.rs @@ -197,7 +197,7 @@ mod tests { use std::path::PathBuf; use discv5::enr::NodeId; - use ethportal_api::types::portal_wire::ProtocolId; + use ethportal_api::types::network::Subnetwork; use r2d2::Pool; use r2d2_sqlite::SqliteConnectionManager; use rstest::rstest; @@ -215,7 +215,7 @@ mod tests { fn create_pruning_strategy(storage_capacity_bytes: u64) -> PruningStrategy { let config = IdIndexedV1StoreConfig { content_type: ContentType::State, - network: ProtocolId::State, + subnetwork: Subnetwork::State, node_id: NodeId::random(), node_data_dir: PathBuf::default(), storage_capacity_bytes, diff --git a/trin-storage/src/versioned/id_indexed_v1/store.rs b/trin-storage/src/versioned/id_indexed_v1/store.rs index 98c8b3580..e8498dab2 100644 --- a/trin-storage/src/versioned/id_indexed_v1/store.rs +++ b/trin-storage/src/versioned/id_indexed_v1/store.rs @@ -79,7 +79,7 @@ impl VersionedContentStore for IdIndexedV1Store< fn create(content_type: ContentType, config: Self::Config) -> Result { maybe_create_table_and_indexes(&content_type, &config.sql_connection_pool)?; - let protocol_id = config.network; + let subnetwork = config.subnetwork; let pruning_strategy = PruningStrategy::new(config.clone()); @@ -88,7 +88,7 @@ impl VersionedContentStore for IdIndexedV1Store< radius: Distance::MAX, pruning_strategy, usage_stats: UsageStats::default(), - metrics: StorageMetricsReporter::new(protocol_id), + metrics: StorageMetricsReporter::new(subnetwork), _phantom_content_key: PhantomData, }; store.init()?; @@ -543,7 +543,7 @@ fn maybe_create_table_and_indexes( mod tests { use anyhow::Result; use discv5::enr::NodeId; - use ethportal_api::{types::portal_wire::ProtocolId, IdentityContentKey}; + use ethportal_api::{types::network::Subnetwork, IdentityContentKey}; use rand::Rng; use tempfile::TempDir; @@ -565,7 +565,7 @@ mod tests { fn create_config(temp_dir: &TempDir, storage_capacity_bytes: u64) -> IdIndexedV1StoreConfig { IdIndexedV1StoreConfig { content_type: ContentType::State, - network: ProtocolId::State, + subnetwork: Subnetwork::State, node_id: NodeId::random(), node_data_dir: temp_dir.path().to_path_buf(), distance_fn: DistanceFunction::Xor, diff --git a/utp-testing/src/lib.rs b/utp-testing/src/lib.rs index 6800403d7..e402a9c2a 100644 --- a/utp-testing/src/lib.rs +++ b/utp-testing/src/lib.rs @@ -8,10 +8,7 @@ pub mod rpc; use crate::rpc::RpcServer; use discv5::TalkRequest; use ethportal_api::{ - types::{ - enr::Enr, - portal_wire::{ProtocolId, MAINNET}, - }, + types::{enr::Enr, network::Subnetwork, portal_wire::MAINNET}, utils::bytes::{hex_encode, hex_encode_upper}, }; use jsonrpsee::{ @@ -145,11 +142,11 @@ impl TestApp { // Forward discv5 uTP packets to uTP socket tokio::spawn(async move { while let Some(request) = talk_req_rx.recv().await { - let protocol_id = MAINNET - .get_protocol_id_from_hex(&hex_encode_upper(request.protocol())) + let subnetwork = MAINNET + .get_subnetwork_from_protocol_identifier(&hex_encode_upper(request.protocol())) .unwrap(); - if let ProtocolId::Utp = protocol_id { + if let Subnetwork::Utp = subnetwork { utp_talk_reqs_tx.send(request).unwrap(); }; }