From 0f5cda8f6b09d917bfd2ab590dc1886932a2373e Mon Sep 17 00:00:00 2001 From: Hansie Odendaal Date: Mon, 2 Sep 2024 14:40:09 +0200 Subject: [PATCH] review comments --- base_layer/p2p/src/initialization.rs | 3 +- base_layer/p2p/src/lib.rs | 41 ------- common/src/configuration/network.rs | 169 +++++++++++++++++++++++++++ 3 files changed, 170 insertions(+), 43 deletions(-) diff --git a/base_layer/p2p/src/initialization.rs b/base_layer/p2p/src/initialization.rs index 69d2e9cae88..f46e5f7410b 100644 --- a/base_layer/p2p/src/initialization.rs +++ b/base_layer/p2p/src/initialization.rs @@ -81,7 +81,6 @@ use tower::ServiceBuilder; use crate::{ comms_connector::{InboundDomainConnector, PubsubDomainConnector}, config::{P2pConfig, PeerSeedsConfig}, - get_network_wire_byte, peer_seeds::{DnsSeedResolver, SeedPeer}, transport::{TorTransportConfig, TransportType}, TransportConfig, @@ -560,7 +559,7 @@ impl ServiceInitializer for P2pInitializer { .with_node_info(NodeNetworkInfo { major_version: MAJOR_NETWORK_VERSION, minor_version: MINOR_NETWORK_VERSION, - network_wire_byte: get_network_wire_byte(self.network)?, + network_wire_byte: self.network.as_wire_byte(), user_agent: self.user_agent.clone(), }) .with_minimize_connections(if self.config.dht.minimize_connections { diff --git a/base_layer/p2p/src/lib.rs b/base_layer/p2p/src/lib.rs index 4c8f5f5377d..5763213f5ed 100644 --- a/base_layer/p2p/src/lib.rs +++ b/base_layer/p2p/src/lib.rs @@ -57,44 +57,3 @@ pub const MAJOR_NETWORK_VERSION: u8 = 0; /// Minor network version. This should change with each time the network protocol has changed in a backward-compatible /// way. pub const MINOR_NETWORK_VERSION: u8 = 0; - -// This function returns the network wire byte for any chosen network. Increase these numbers for any given network when -// network traffic separation is required. -// Note: Do not re-use previous values. -fn get_network_wire_byte(network: Network) -> Result { - let network_wire_byte = match network { - Network::MainNet => 0, - Network::StageNet => 40, - Network::NextNet => 80, - Network::LocalNet => 120, - Network::Igor => 160, - Network::Esmeralda => 200, - }; - verify_network_wire_byte_range(network_wire_byte, network)?; - Ok(network_wire_byte) -} - -// This function bins the range of u8 numbers for any chosen network to a valid network_wire_byte_range. -// Note: Do not change these ranges. -fn verify_network_wire_byte_range(network_wire_byte: u8, network: Network) -> Result<(), anyhow::Error> { - if network_wire_byte == 0x46 { - return Err(anyhow::anyhow!("Invalid network wire byte, cannot be 0x46 (E)")); - } - - let valid = match network { - Network::MainNet => (0..40).contains(&network_wire_byte), - Network::StageNet => (40..80).contains(&network_wire_byte), - Network::NextNet => (80..120).contains(&network_wire_byte), - Network::LocalNet => (120..160).contains(&network_wire_byte), - Network::Igor => (160..200).contains(&network_wire_byte), - Network::Esmeralda => (200..240).contains(&network_wire_byte), - }; - if !valid { - return Err(anyhow::anyhow!( - "Invalid network wire byte `{}` for network `{}`", - network_wire_byte, - network - )); - } - Ok(()) -} diff --git a/common/src/configuration/network.rs b/common/src/configuration/network.rs index bf265fa9b13..2ab695384bf 100644 --- a/common/src/configuration/network.rs +++ b/common/src/configuration/network.rs @@ -32,6 +32,15 @@ use serde::{Deserialize, Serialize}; use crate::ConfigurationError; +const LIVENESS_WIRE_MODE: u8 = 0xa7; +const MAIN_NET_RANGE: std::ops::Range = 0..40; +const STAGE_NET_RANGE: std::ops::Range = 40..80; +const NEXT_NET_RANGE: std::ops::Range = 80..120; +const LOCAL_NET_RANGE: std::ops::Range = 120..160; +const IGOR_RANGE: std::ops::Range = 160..200; +const ESMERALDA_RANGE: std::ops::Range = 200..240; +const LEGACY_RANGE: [u8; 6] = [0x00, 0x01, 0x02, 0x10, 0x24, 0x26]; + static CURRENT_NETWORK: OnceLock = OnceLock::new(); /// Represents the available Tari p2p networks. Only nodes with matching byte values will be able to connect, so these @@ -86,6 +95,66 @@ impl Network { LocalNet => "localnet", } } + + /// This function returns the network wire byte for any chosen network. Increase these numbers for any given network + /// when network traffic separation is required. + /// Note: Do not re-use previous values. + pub fn as_wire_byte(self) -> u8 { + let wire_byte = match self { + // Choose a value in 'MAIN_NET_RANGE' or assign 'self.as_byte()' + Network::MainNet => self.as_byte(), + // Choose a value in 'STAGE_NET_RANGE' or assign 'self.as_byte()' + Network::StageNet => self.as_byte(), + // Choose a value in 'NEXT_NET_RANGE' or assign 'self.as_byte()' + Network::NextNet => self.as_byte(), + // Choose a value in 'LOCAL_NET_RANGE' or assign 'self.as_byte()' + Network::LocalNet => self.as_byte(), + // Choose a value in 'IGOR_RANGE' or assign 'self.as_byte()' + Network::Igor => self.as_byte(), + // Choose a value in 'ESMERALDA_RANGE' or assign 'self.as_byte()' + Network::Esmeralda => self.as_byte(), + }; + // The error is squashed to make this method infallible, and the method is called here to ensure that the + // range constants are used. + let _unused = self.verify_network_wire_byte_range(wire_byte); + wire_byte + } + + // Helper function to verify the network wire byte range + fn verify_network_wire_byte_range(&self, network_wire_byte: u8) -> Result<(), String> { + // 'LIVENESS_WIRE_MODE' is reserved for '0xa7' + if network_wire_byte == LIVENESS_WIRE_MODE { + return Err("Invalid network wire byte, cannot be '0x46', reserved for 'LIVENESS_WIRE_MODE'".to_string()); + } + + // Legacy compatibility + if network_wire_byte == self.as_byte() { + return Ok(()); + } + if LEGACY_RANGE.contains(&network_wire_byte) { + return Err(format!( + "Invalid network wire byte `{}` for network `{}`", + network_wire_byte, self + )); + } + + // Verify binned values + let valid = match self { + Network::MainNet => MAIN_NET_RANGE.contains(&network_wire_byte), + Network::StageNet => STAGE_NET_RANGE.contains(&network_wire_byte), + Network::NextNet => NEXT_NET_RANGE.contains(&network_wire_byte), + Network::LocalNet => LOCAL_NET_RANGE.contains(&network_wire_byte), + Network::Igor => IGOR_RANGE.contains(&network_wire_byte), + Network::Esmeralda => ESMERALDA_RANGE.contains(&network_wire_byte), + }; + if !valid { + return Err(format!( + "Invalid network wire byte `{}` for network `{}`", + network_wire_byte, self + )); + } + Ok(()) + } } /// The default network for all applications @@ -236,4 +305,104 @@ mod test { assert_eq!(Network::try_from(0x24).unwrap(), Network::Igor); assert_eq!(Network::try_from(0x26).unwrap(), Network::Esmeralda); } + + #[test] + fn test_as_wire_byte() { + for network in vec![ + Network::MainNet, + Network::StageNet, + Network::NextNet, + Network::LocalNet, + Network::Igor, + Network::Esmeralda, + ] { + assert!(network.verify_network_wire_byte_range(LIVENESS_WIRE_MODE).is_err()); + + let wire_byte = Network::as_wire_byte(network); + assert!(network.verify_network_wire_byte_range(wire_byte).is_ok()); + + for val in 0..255 { + match network { + Network::MainNet => { + if val == LIVENESS_WIRE_MODE { + assert!(network.verify_network_wire_byte_range(val).is_err()); + } else if val == Network::MainNet.as_byte() { + assert!(network.verify_network_wire_byte_range(val).is_ok()); + } else if LEGACY_RANGE.contains(&val) { + assert!(network.verify_network_wire_byte_range(val).is_err()); + } else if MAIN_NET_RANGE.contains(&val) { + assert!(network.verify_network_wire_byte_range(val).is_ok()); + } else { + assert!(network.verify_network_wire_byte_range(val).is_err()); + } + }, + Network::StageNet => { + if val == LIVENESS_WIRE_MODE { + assert!(network.verify_network_wire_byte_range(val).is_err()); + } else if val == Network::StageNet.as_byte() { + assert!(network.verify_network_wire_byte_range(val).is_ok()); + } else if LEGACY_RANGE.contains(&val) { + assert!(network.verify_network_wire_byte_range(val).is_err()); + } else if STAGE_NET_RANGE.contains(&val) { + assert!(network.verify_network_wire_byte_range(val).is_ok()); + } else { + assert!(network.verify_network_wire_byte_range(val).is_err()); + } + }, + Network::NextNet => { + if val == LIVENESS_WIRE_MODE { + assert!(network.verify_network_wire_byte_range(val).is_err()); + } else if val == Network::NextNet.as_byte() { + assert!(network.verify_network_wire_byte_range(val).is_ok()); + } else if LEGACY_RANGE.contains(&val) { + assert!(network.verify_network_wire_byte_range(val).is_err()); + } else if NEXT_NET_RANGE.contains(&val) { + assert!(network.verify_network_wire_byte_range(val).is_ok()); + } else { + assert!(network.verify_network_wire_byte_range(val).is_err()); + } + }, + Network::LocalNet => { + if val == LIVENESS_WIRE_MODE { + assert!(network.verify_network_wire_byte_range(val).is_err()); + } else if val == Network::LocalNet.as_byte() { + assert!(network.verify_network_wire_byte_range(val).is_ok()); + } else if LEGACY_RANGE.contains(&val) { + assert!(network.verify_network_wire_byte_range(val).is_err()); + } else if LOCAL_NET_RANGE.contains(&val) { + assert!(network.verify_network_wire_byte_range(val).is_ok()); + } else { + assert!(network.verify_network_wire_byte_range(val).is_err()); + } + }, + Network::Igor => { + if val == LIVENESS_WIRE_MODE { + assert!(network.verify_network_wire_byte_range(val).is_err()); + } else if val == Network::Igor.as_byte() { + assert!(network.verify_network_wire_byte_range(val).is_ok()); + } else if LEGACY_RANGE.contains(&val) { + assert!(network.verify_network_wire_byte_range(val).is_err()); + } else if IGOR_RANGE.contains(&val) { + assert!(network.verify_network_wire_byte_range(val).is_ok()); + } else { + assert!(network.verify_network_wire_byte_range(val).is_err()); + } + }, + Network::Esmeralda => { + if val == LIVENESS_WIRE_MODE { + assert!(network.verify_network_wire_byte_range(val).is_err()); + } else if val == Network::Esmeralda.as_byte() { + assert!(network.verify_network_wire_byte_range(val).is_ok()); + } else if LEGACY_RANGE.contains(&val) { + assert!(network.verify_network_wire_byte_range(val).is_err()); + } else if ESMERALDA_RANGE.contains(&val) { + assert!(network.verify_network_wire_byte_range(val).is_ok()); + } else { + assert!(network.verify_network_wire_byte_range(val).is_err()); + } + }, + } + } + } + } }