Skip to content

Commit

Permalink
review comments
Browse files Browse the repository at this point in the history
  • Loading branch information
hansieodendaal committed Sep 2, 2024
1 parent adaf47a commit 0f5cda8
Show file tree
Hide file tree
Showing 3 changed files with 170 additions and 43 deletions.
3 changes: 1 addition & 2 deletions base_layer/p2p/src/initialization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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 {
Expand Down
41 changes: 0 additions & 41 deletions base_layer/p2p/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<u8, anyhow::Error> {
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(())
}
169 changes: 169 additions & 0 deletions common/src/configuration/network.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,15 @@ use serde::{Deserialize, Serialize};

use crate::ConfigurationError;

const LIVENESS_WIRE_MODE: u8 = 0xa7;
const MAIN_NET_RANGE: std::ops::Range<u8> = 0..40;
const STAGE_NET_RANGE: std::ops::Range<u8> = 40..80;
const NEXT_NET_RANGE: std::ops::Range<u8> = 80..120;
const LOCAL_NET_RANGE: std::ops::Range<u8> = 120..160;
const IGOR_RANGE: std::ops::Range<u8> = 160..200;
const ESMERALDA_RANGE: std::ops::Range<u8> = 200..240;
const LEGACY_RANGE: [u8; 6] = [0x00, 0x01, 0x02, 0x10, 0x24, 0x26];

static CURRENT_NETWORK: OnceLock<Network> = OnceLock::new();

/// Represents the available Tari p2p networks. Only nodes with matching byte values will be able to connect, so these
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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());
}
},
}
}
}
}
}

0 comments on commit 0f5cda8

Please sign in to comment.