Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix!: use configured network string in networking protocol #864

Merged
merged 1 commit into from
Jan 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion applications/tari_indexer/src/bootstrap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ pub async fn spawn_services(
tari_networking::Config {
listener_port: config.indexer.p2p.listener_port,
swarm: SwarmConfig {
protocol_version: "/tari/devnet/0.0.1".try_into().unwrap(),
protocol_version: format!("/tari/{}/0.0.1", config.network).parse().unwrap(),
user_agent: "/tari/indexer/0.0.1".to_string(),
enable_mdns: config.indexer.p2p.enable_mdns,
..Default::default()
Expand Down
2 changes: 1 addition & 1 deletion applications/tari_validator_node/src/bootstrap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ pub async fn spawn_services(
tari_networking::Config {
listener_port: config.validator_node.p2p.listener_port,
swarm: SwarmConfig {
protocol_version: "/tari/devnet/0.0.1".try_into().unwrap(),
protocol_version: format!("/tari/{}/0.0.1", config.network).parse().unwrap(),
user_agent: "/tari/validator/0.0.1".to_string(),
enable_mdns: config.validator_node.p2p.enable_mdns,
..Default::default()
Expand Down
2 changes: 1 addition & 1 deletion networking/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ pub use config::*;
pub use connection::*;
pub use handle::*;
pub use spawn::*;
pub use tari_swarm::{is_supported_multiaddr, Config as SwarmConfig, TariNetwork};
pub use tari_swarm::{is_supported_multiaddr, Config as SwarmConfig};

#[async_trait]
pub trait NetworkingService<TMsg> {
Expand Down
11 changes: 3 additions & 8 deletions networking/core/src/worker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ use tari_swarm::{
peersync,
substream,
substream::{NegotiatedSubstream, ProtocolNotification, StreamId},
ProtocolVersion,
TariNodeBehaviourEvent,
TariSwarm,
};
Expand Down Expand Up @@ -697,14 +696,10 @@ where
}

fn on_peer_identified(&mut self, peer_id: PeerId, info: identify::Info) -> Result<(), NetworkingError> {
if !self
.config
.swarm
.protocol_version
.is_compatible(&ProtocolVersion::try_from(info.protocol_version.as_str())?)
{
if !self.config.swarm.protocol_version.is_compatible(&info.protocol_version) {
info!(target: LOG_TARGET, "🚨 Peer {} is using an incompatible protocol version: {}. Our version {}", peer_id, info.protocol_version, self.config.swarm.protocol_version);
// Errors just indicate that there was no connection to the peer.
// Error can be ignored as the docs indicate that an error only occurs if there was no connection to the
// peer.
let _ignore = self.swarm.disconnect_peer_id(peer_id);
return Ok(());
}
Expand Down
4 changes: 2 additions & 2 deletions networking/swarm/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::protocol_version::ProtocolVersion;

#[derive(Debug, Clone)]
pub struct Config {
pub protocol_version: ProtocolVersion<'static>,
pub protocol_version: ProtocolVersion,
pub user_agent: String,
pub messaging_protocol: String,
pub ping: ping::Config,
Expand All @@ -22,7 +22,7 @@ pub struct Config {
impl Default for Config {
fn default() -> Self {
Self {
protocol_version: "/tari/devnet/0.0.1".try_into().unwrap(),
protocol_version: "/tari/localnet/0.0.1".parse().unwrap(),
user_agent: "/tari/unknown/0.0.1".to_string(),
messaging_protocol: "/tari/messaging/0.0.1".to_string(),
ping: ping::Config::default(),
Expand Down
6 changes: 4 additions & 2 deletions networking/swarm/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ pub enum TariSwarmError {
InvalidProtocol(#[from] InvalidProtocol),
#[error("Behaviour error: {0}")]
BehaviourError(String),
#[error("Failed to parse protocol version field '{field}'")]
ProtocolVersionParseFailed { field: &'static str },
#[error("'{given}' is not a valid protocol version string")]
ProtocolVersionParseFailed { given: String },
#[error("Invalid version string: {given}")]
InvalidVersionString { given: String },
}
2 changes: 0 additions & 2 deletions networking/swarm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,11 @@
mod behaviour;
mod config;
mod error;
mod network;
mod protocol_version;

pub use behaviour::*;
pub use config::*;
pub use error::*;
pub use network::*;
pub use protocol_version::*;

pub type TariSwarm<TMsg> = libp2p::Swarm<TariNodeBehaviour<TMsg>>;
Expand Down
36 changes: 0 additions & 36 deletions networking/swarm/src/network.rs

This file was deleted.

107 changes: 58 additions & 49 deletions networking/swarm/src/protocol_version.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,84 +3,93 @@

use std::{fmt, fmt::Display, str::FromStr};

use crate::{TariNetwork, TariSwarmError};
use crate::TariSwarmError;

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ProtocolVersion<'a> {
domain: &'a str,
network: TariNetwork,
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ProtocolVersion {
domain: String,
network: String,
version: Version,
}

impl<'a> ProtocolVersion<'a> {
pub const fn new(domain: &'a str, network: TariNetwork, version: Version) -> Self {
impl ProtocolVersion {
pub const fn new(domain: String, network: String, version: Version) -> Self {
Self {
domain,
network,
version,
}
}

pub const fn domain(&self) -> &'a str {
self.domain
pub fn domain(&self) -> &str {
&self.domain
}

pub const fn network(&self) -> TariNetwork {
self.network
pub fn network(&self) -> &str {
&self.network
}

pub const fn version(&self) -> Version {
self.version
}

pub fn is_compatible(&self, other: &ProtocolVersion) -> bool {
self.domain == other.domain && self.network == other.network && self.version.semantic_version_eq(&other.version)
pub fn is_compatible(&self, protocol_str: &str) -> bool {
let Some((domain, network, version)) = parse_protocol_str(protocol_str) else {
return false;
};
self.domain == domain && self.network == network && self.version.semantic_version_eq(&version)
}
}

impl PartialEq<String> for ProtocolVersion<'_> {
impl PartialEq<String> for ProtocolVersion {
fn eq(&self, other: &String) -> bool {
let mut parts = other.split('/');
let Some(domain) = parts.next() else {
return false;
};

let Some(network) = parts.next() else {
return false;
};

let Some(version) = parts.next().and_then(|s| s.parse().ok()) else {
let Some((domain, network, version)) = parse_protocol_str(other) else {
return false;
};
self.domain == domain && self.network == network && self.version == version
}
}

self.domain == domain && self.network.as_str() == network && self.version == version
impl Display for ProtocolVersion {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "/{}/{}/{}", self.domain, self.network, self.version)
}
}

impl<'a> TryFrom<&'a str> for ProtocolVersion<'a> {
type Error = TariSwarmError;
impl FromStr for ProtocolVersion {
type Err = TariSwarmError;

fn try_from(value: &'a str) -> Result<Self, Self::Error> {
fn from_str(value: &str) -> Result<Self, Self::Err> {
let mut parts = value.split('/');
// Must have a leading '/'
let leading = parts.next();
if leading.filter(|l| l.is_empty()).is_none() {
return Err(TariSwarmError::ProtocolVersionParseFailed { field: "leading '/'" });
return Err(TariSwarmError::ProtocolVersionParseFailed {
given: value.to_string(),
});
}

let mut next = move |field| parts.next().ok_or(TariSwarmError::ProtocolVersionParseFailed { field });
Ok(Self::new(
next("domain")?,
next("network")?.parse()?,
next("version")?.parse()?,
))
let Some((domain, network, version)) = parse_protocol_str(value) else {
return Err(TariSwarmError::ProtocolVersionParseFailed {
given: value.to_string(),
});
};
Ok(Self::new(domain.to_string(), network.to_string(), version))
}
}

impl Display for ProtocolVersion<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "/{}/{}/{}", self.domain, self.network, self.version)
fn parse_protocol_str(protocol_str: &str) -> Option<(&str, &str, Version)> {
let mut parts = protocol_str.split('/');
// Must have a leading '/'
let leading = parts.next()?;
if !leading.is_empty() {
return None;
}

let domain = parts.next()?;
let network = parts.next()?;
let version = parts.next().and_then(|s| s.parse().ok())?;
Some((domain, network, version))
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
Expand Down Expand Up @@ -129,17 +138,17 @@ impl FromStr for Version {
fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut parts = s.split('.');

let mut next = move |field| {
let mut next = move || {
parts
.next()
.ok_or(TariSwarmError::ProtocolVersionParseFailed { field })?
.ok_or(TariSwarmError::InvalidVersionString { given: s.to_string() })?
.parse()
.map_err(|_| TariSwarmError::ProtocolVersionParseFailed { field })
.map_err(|_| TariSwarmError::InvalidVersionString { given: s.to_string() })
};
Ok(Self {
major: next("version.major")?,
minor: next("version.minor")?,
patch: next("version.patch")?,
major: next()?,
minor: next()?,
patch: next()?,
})
}
}
Expand All @@ -156,13 +165,13 @@ mod tests {

#[test]
fn it_parses_correctly() {
let version = ProtocolVersion::try_from("/tari/devnet/0.0.1").unwrap();
let version = ProtocolVersion::from_str("/tari/igor/1.2.3").unwrap();
assert_eq!(version.domain(), "tari");
assert_eq!(version.network(), TariNetwork::DevNet);
assert_eq!(version.network(), "igor");
assert_eq!(version.version(), Version {
major: 0,
minor: 0,
patch: 1
major: 1,
minor: 2,
patch: 3
});
}
}
Loading