Skip to content

Commit

Permalink
protocols/kad: Support multiple protocol names (#2846)
Browse files Browse the repository at this point in the history
Add support for multiple Kademlia protocol names to allow
protocol name upgrades.
  • Loading branch information
dmitry-markin committed Sep 3, 2022
1 parent 89f898c commit cee199a
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 12 deletions.
6 changes: 6 additions & 0 deletions protocols/kad/CHANGELOG.md
@@ -1,7 +1,13 @@
# 0.40.0 [unreleased]

- Add support for multiple protocol names. Update `Kademlia`, `KademliaConfig`,
and `KademliaProtocolConfig` accordingly. See [Issue 2837]. See [PR 2846].

- Update to `libp2p-swarm` `v0.39.0`.

[Issue 2837]: https://github.com/libp2p/rust-libp2p/issues/2837
[PR 2846]: https://github.com/libp2p/rust-libp2p/pull/2846

# 0.39.0

- Update prost requirement from 0.10 to 0.11 which no longer installs the protoc Protobuf compiler.
Expand Down
22 changes: 18 additions & 4 deletions protocols/kad/src/behaviour.rs
Expand Up @@ -214,14 +214,28 @@ impl Default for KademliaConfig {
}

impl KademliaConfig {
/// Sets custom protocol names.
///
/// Kademlia nodes only communicate with other nodes using the same protocol
/// name. Using custom name(s) therefore allows to segregate the DHT from
/// others, if that is desired.
///
/// More than one protocol name can be supplied. In this case the node will
/// be able to talk to other nodes supporting any of the provided names.
/// Multiple names must be used with caution to avoid network partitioning.
pub fn set_protocol_names(&mut self, names: Vec<Cow<'static, [u8]>>) -> &mut Self {
self.protocol_config.set_protocol_names(names);
self
}

/// Sets a custom protocol name.
///
/// Kademlia nodes only communicate with other nodes using the same protocol
/// name. Using a custom name therefore allows to segregate the DHT from
/// others, if that is desired.
#[deprecated(since = "0.40.0", note = "use `set_protocol_names()` instead")]
pub fn set_protocol_name(&mut self, name: impl Into<Cow<'static, [u8]>>) -> &mut Self {
self.protocol_config.set_protocol_name(name);
self
self.set_protocol_names(std::iter::once(name.into()).collect())
}

/// Sets the timeout for a single query.
Expand Down Expand Up @@ -403,8 +417,8 @@ where
}

/// Get the protocol name of this kademlia instance.
pub fn protocol_name(&self) -> &[u8] {
self.protocol_config.protocol_name()
pub fn protocol_names(&self) -> &[Cow<'static, [u8]>] {
self.protocol_config.protocol_names()
}

/// Creates a new `Kademlia` network behaviour with the given configuration.
Expand Down
23 changes: 15 additions & 8 deletions protocols/kad/src/protocol.rs
Expand Up @@ -142,21 +142,28 @@ impl From<KadPeer> for proto::message::Peer {
// `OutboundUpgrade` to be just a single message
#[derive(Debug, Clone)]
pub struct KademliaProtocolConfig {
protocol_name: Cow<'static, [u8]>,
protocol_names: Vec<Cow<'static, [u8]>>,
/// Maximum allowed size of a packet.
max_packet_size: usize,
}

impl KademliaProtocolConfig {
/// Returns the configured protocol name.
pub fn protocol_name(&self) -> &[u8] {
&self.protocol_name
pub fn protocol_names(&self) -> &[Cow<'static, [u8]>] {
&self.protocol_names
}

/// Modifies the protocol name used on the wire. Can be used to create incompatibilities
/// Modifies the protocol names used on the wire. Can be used to create incompatibilities
/// between networks on purpose.
pub fn set_protocol_names(&mut self, names: Vec<Cow<'static, [u8]>>) {
self.protocol_names = names;
}

/// Sets single protocol name used on the wire. Can be used to create incompatibilities
/// between networks on purpose.
#[deprecated(since = "0.40.0", note = "use `set_protocol_names()` instead")]
pub fn set_protocol_name(&mut self, name: impl Into<Cow<'static, [u8]>>) {
self.protocol_name = name.into();
self.set_protocol_names(std::iter::once(name.into()).collect());
}

/// Modifies the maximum allowed size of a single Kademlia packet.
Expand All @@ -168,18 +175,18 @@ impl KademliaProtocolConfig {
impl Default for KademliaProtocolConfig {
fn default() -> Self {
KademliaProtocolConfig {
protocol_name: Cow::Borrowed(DEFAULT_PROTO_NAME),
protocol_names: iter::once(Cow::Borrowed(DEFAULT_PROTO_NAME)).collect(),
max_packet_size: DEFAULT_MAX_PACKET_SIZE,
}
}
}

impl UpgradeInfo for KademliaProtocolConfig {
type Info = Cow<'static, [u8]>;
type InfoIter = iter::Once<Self::Info>;
type InfoIter = std::vec::IntoIter<Self::Info>;

fn protocol_info(&self) -> Self::InfoIter {
iter::once(self.protocol_name.clone())
self.protocol_names.clone().into_iter()
}
}

Expand Down

0 comments on commit cee199a

Please sign in to comment.