From 1a2e12279c1166aab0c240eeb06ef4d211c713c8 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sun, 31 Jul 2022 18:58:27 +0900 Subject: [PATCH 1/9] swarm/src/behaviour: Deprecate NetworkBehaviourEventProcess In preparation for https://github.com/libp2p/rust-libp2p/pull/2751. --- swarm/CHANGELOG.md | 67 +++++++++++++++++++++++++++++++++++ swarm/src/behaviour.rs | 30 +++++++--------- swarm/src/behaviour/either.rs | 8 ++--- swarm/src/behaviour/toggle.rs | 8 ++--- swarm/src/lib.rs | 5 +-- 5 files changed, 90 insertions(+), 28 deletions(-) diff --git a/swarm/CHANGELOG.md b/swarm/CHANGELOG.md index 02edf9beef4..8a35d60eca2 100644 --- a/swarm/CHANGELOG.md +++ b/swarm/CHANGELOG.md @@ -1,5 +1,72 @@ # 0.38.0 [unreleased] +- Deprecate `NetworkBehaviourEventProcess`. When deriving `NetworkBehaviour` on a custom `struct` users + should bring their own `OutEvent` via `#[behaviour(out_event = "MyBehaviourEvent")]`. + + See [`NetworkBehaviour` + documentation](https://docs.rs/libp2p/latest/libp2p/swarm/trait.NetworkBehaviour.html) for + details. + + Previously + + ``` rust + #[derive(NetworkBehaviour)] + #[behaviour(event_process = true)] + struct MyBehaviour { + floodsub: Gossipsub, + mdns: Mdns, + } + + impl NetworkBehaviourEventProcess for MyBehaviour { + fn inject_event(&mut self, message: GossipsubEvent) { + todo!("Handle event") + } + } + + impl NetworkBehaviourEventProcess for MyBehaviour { + fn inject_event(&mut self, message: MdnsEvent) { + todo!("Handle event") + } + } + ``` + + Now + + ``` rust + #[derive(NetworkBehaviour)] + #[behaviour(out_event = "MyBehaviourEvent")] + struct MyBehaviour { + floodsub: Gossipsub, + mdns: Mdns, + } + + enum MyBehaviourEvent { + Floodsub(FloodsubEvent), + Mdns(MdnsEvent), + } + + impl From for MyBehaviourEvent { + fn from(event: GossipsubEvent) -> Self { + MyBehaviourEvent::Gossipsub(event) + } + } + + impl From for MyBehaviourEvent { + fn from(event: MdnsEvent) -> Self { + MyBehaviourEvent::Mdns(event) + } + } + + match swarm.next().await.unwrap() { + SwarmEvent::Behaviour(MyBehaviourEvent::Gossipsub(event)) => { + todo!("Handle event") + } + SwarmEvent::Behaviour(MyBehaviourEvent::Mdns(event)) => { + todo!("Handle event") + } + } + ``` + - Update dial address concurrency factor to `8`, thus dialing up to 8 addresses concurrently for a single connection attempt. See `Swarm::dial_concurrency_factor` and [PR 2741]. - Update to `libp2p-core` `v0.35.0`. diff --git a/swarm/src/behaviour.rs b/swarm/src/behaviour.rs index 3dd6ddf9588..49a52e174c1 100644 --- a/swarm/src/behaviour.rs +++ b/swarm/src/behaviour.rs @@ -79,16 +79,11 @@ pub(crate) type THandlerOutEvent = /// it will delegate to each `struct` member and return a concatenated array of all addresses /// returned by the struct members. /// -/// When creating a custom [`NetworkBehaviour`], you must choose one of two methods to respond to -/// incoming events: -/// * One option is setting a custom `out_event` with `#[behaviour(out_event = "AnotherType")]`. -/// In this case, events generated by the custom [`NetworkBehaviour`] struct members will be -/// converted to your custom `out_event` for you to handle after polling the swarm. -/// * Alternatively, users that need access to the root [`NetworkBehaviour`] implementation while -/// processing emitted events, can specify `#[behaviour(event_process = true)]` (default is false). -/// Events generated by the behaviour's struct members are delegated to [`NetworkBehaviourEventProcess`] -/// trait implementations. Those must be provided by the user on the type that [`NetworkBehaviour`] -/// is derived on. +/// Events ([`NetworkBehaviour::OutEvent`]) returned by each `struct` member are wrapped in a new +/// `enum` event, with an `enum` variant for each `struct` member. Users can define this event +/// `enum` themselves and provide the name to the derive macro via `#[behaviour(out_event = +/// "MyCustomOutEvent")]`. If the user does not specify an `out_event`, the derive macro generates +/// the event definition itself, naming it `Event`. /// /// When setting a custom `out_event`, the aforementioned conversion of each of the event types /// generated by the struct members to the custom `out_event` is handled by [`From`] @@ -123,14 +118,6 @@ pub(crate) type THandlerOutEvent = /// } /// ``` /// -/// When using `event_process = true` the [`NetworkBehaviourEventProcess`] trait implementations -/// are granted exclusive access to the [`NetworkBehaviour`], therefore -/// [blocking code](https://ryhl.io/blog/async-what-is-blocking/) in these implementations will -/// block the entire [`Swarm`](crate::Swarm) from processing new events, since the swarm cannot progress -/// without also having exclusive access to the [`NetworkBehaviour`]. A better alternative is to execute -/// blocking or asynchronous logic on a separate task, perhaps with the help of a bounded channel to -/// maintain backpressure. The sender for the channel could be included in the NetworkBehaviours constructor. -/// /// Optionally one can provide a custom `poll` function through the `#[behaviour(poll_method = /// "poll")]` attribute. This function must have the same signature as the [`NetworkBehaviour#poll`] /// function and will be called last within the generated [`NetworkBehaviour`] implementation. @@ -340,6 +327,13 @@ pub trait PollParameters { /// /// You can opt out of this behaviour through `#[behaviour(event_process = false)]`. See the /// documentation of [`NetworkBehaviour`] for details. +#[deprecated( + since = "0.38.0", + note = "Use `#[behaviour(out_event = \"MyBehaviourEvent\")]` instead. See \ + https://github.com/libp2p/rust-libp2p/blob/master/swarm/CHANGELOG.md#0380 \ + for instructions on how to migrate. Will be removed with \ + https://github.com/libp2p/rust-libp2p/pull/2751." +)] pub trait NetworkBehaviourEventProcess { /// Called when one of the fields of the type you're deriving `NetworkBehaviour` on generates /// an event. diff --git a/swarm/src/behaviour/either.rs b/swarm/src/behaviour/either.rs index 54e60e77b3a..fc4c50e63ef 100644 --- a/swarm/src/behaviour/either.rs +++ b/swarm/src/behaviour/either.rs @@ -19,10 +19,9 @@ // DEALINGS IN THE SOFTWARE. use crate::handler::{either::IntoEitherHandler, ConnectionHandler, IntoConnectionHandler}; -use crate::{ - DialError, NetworkBehaviour, NetworkBehaviourAction, NetworkBehaviourEventProcess, - PollParameters, -}; +#[allow(deprecated)] +pub use crate::NetworkBehaviourEventProcess; +use crate::{DialError, NetworkBehaviour, NetworkBehaviourAction, PollParameters}; use either::Either; use libp2p_core::{ connection::ConnectionId, transport::ListenerId, ConnectedPoint, Multiaddr, PeerId, @@ -237,6 +236,7 @@ where } } +#[allow(deprecated)] impl NetworkBehaviourEventProcess for Either where diff --git a/swarm/src/behaviour/toggle.rs b/swarm/src/behaviour/toggle.rs index 50ea6487770..64ebdf779e5 100644 --- a/swarm/src/behaviour/toggle.rs +++ b/swarm/src/behaviour/toggle.rs @@ -23,10 +23,9 @@ use crate::handler::{ KeepAlive, SubstreamProtocol, }; use crate::upgrade::{InboundUpgradeSend, OutboundUpgradeSend, SendWrapper}; -use crate::{ - DialError, NetworkBehaviour, NetworkBehaviourAction, NetworkBehaviourEventProcess, - PollParameters, -}; +#[allow(deprecated)] +pub use crate::NetworkBehaviourEventProcess; +use crate::{DialError, NetworkBehaviour, NetworkBehaviourAction, PollParameters}; use either::Either; use libp2p_core::{ connection::ConnectionId, @@ -233,6 +232,7 @@ where } } +#[allow(deprecated)] impl NetworkBehaviourEventProcess for Toggle where TBehaviour: NetworkBehaviourEventProcess, diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index f32c2df56bf..cc5cbb836eb 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -63,9 +63,10 @@ pub mod behaviour; pub mod dial_opts; pub mod handler; +#[allow(deprecated)] +pub use behaviour::NetworkBehaviourEventProcess; pub use behaviour::{ - CloseConnection, NetworkBehaviour, NetworkBehaviourAction, NetworkBehaviourEventProcess, - NotifyHandler, PollParameters, + CloseConnection, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, }; pub use connection::{ ConnectionCounters, ConnectionError, ConnectionLimit, ConnectionLimits, PendingConnectionError, From 8d5f6a5098ac6eb9e12ec9376e29832c72121621 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sun, 31 Jul 2022 21:14:12 +0900 Subject: [PATCH 2/9] swarm/src/behaviour: Remove mention OutEvent generation --- swarm/src/behaviour.rs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/swarm/src/behaviour.rs b/swarm/src/behaviour.rs index 49a52e174c1..b4035f247a7 100644 --- a/swarm/src/behaviour.rs +++ b/swarm/src/behaviour.rs @@ -80,14 +80,13 @@ pub(crate) type THandlerOutEvent = /// returned by the struct members. /// /// Events ([`NetworkBehaviour::OutEvent`]) returned by each `struct` member are wrapped in a new -/// `enum` event, with an `enum` variant for each `struct` member. Users can define this event +/// `enum` event, with an `enum` variant for each `struct` member. Users need to define this event /// `enum` themselves and provide the name to the derive macro via `#[behaviour(out_event = -/// "MyCustomOutEvent")]`. If the user does not specify an `out_event`, the derive macro generates -/// the event definition itself, naming it `Event`. +/// "MyCustomOutEvent")]`. /// -/// When setting a custom `out_event`, the aforementioned conversion of each of the event types -/// generated by the struct members to the custom `out_event` is handled by [`From`] -/// implementations the user needs to provide. +/// The aforementioned conversion of each of the event types generated by the struct members to the +/// custom `out_event` is handled by [`From`] implementations which the user needs to define in +/// addition to the event `enum` itself. /// /// ``` rust /// # use libp2p::identify::{Identify, IdentifyEvent}; From 4fd026601145a64166657a3a2fc5bd4b341a0d34 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Wed, 10 Aug 2022 16:54:36 +0900 Subject: [PATCH 3/9] swarm/CHANGELOG: Mention autogeneration of outevent --- swarm/CHANGELOG.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/swarm/CHANGELOG.md b/swarm/CHANGELOG.md index 779768293f1..0fa13703b24 100644 --- a/swarm/CHANGELOG.md +++ b/swarm/CHANGELOG.md @@ -1,7 +1,8 @@ # 0.38.0 [unreleased] -- Deprecate `NetworkBehaviourEventProcess`. When deriving `NetworkBehaviour` on a custom `struct` users - should bring their own `OutEvent` via `#[behaviour(out_event = "MyBehaviourEvent")]`. +- Remove `NetworkBehaviourEventProcess`. When deriving `NetworkBehaviour` on a custom `struct` users + should either bring their own `OutEvent` via `#[behaviour(out_event = "MyBehaviourEvent")]` or, + when not specified, have the derive macro generate one for the user. See [`NetworkBehaviour` documentation](https://docs.rs/libp2p/latest/libp2p/swarm/trait.NetworkBehaviour.html) for @@ -67,10 +68,6 @@ } ``` -- Update dial address concurrency factor to `8`, thus dialing up to 8 addresses concurrently for a single connection attempt. See `Swarm::dial_concurrency_factor` and [PR 2741]. - -- Update to `libp2p-core` `v0.35.0`. - - When deriving `NetworkBehaviour` on a custom `struct` where the user does not specify their own `OutEvent` via `#[behaviour(out_event = "MyBehaviourEvent")]` and where the user does not enable `#[behaviour(event_process = true)]`, then the derive macro generates an `OutEvent` definition for @@ -80,6 +77,10 @@ documentation](https://docs.rs/libp2p/latest/libp2p/swarm/trait.NetworkBehaviour.html) for details. +- Update dial address concurrency factor to `8`, thus dialing up to 8 addresses concurrently for a single connection attempt. See `Swarm::dial_concurrency_factor` and [PR 2741]. + +- Update to `libp2p-core` `v0.35.0`. + [PR 2741]: https://github.com/libp2p/rust-libp2p/pull/2741/ # 0.37.0 From 0662d374c033661fce1cbefbe4d600af51b01de7 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Fri, 12 Aug 2022 09:48:41 +0200 Subject: [PATCH 4/9] Update swarm/CHANGELOG.md Co-authored-by: Elena Frank --- swarm/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swarm/CHANGELOG.md b/swarm/CHANGELOG.md index 0fa13703b24..7eafd18846c 100644 --- a/swarm/CHANGELOG.md +++ b/swarm/CHANGELOG.md @@ -1,6 +1,6 @@ # 0.38.0 [unreleased] -- Remove `NetworkBehaviourEventProcess`. When deriving `NetworkBehaviour` on a custom `struct` users +- Deprecate `NetworkBehaviourEventProcess`. When deriving `NetworkBehaviour` on a custom `struct` users should either bring their own `OutEvent` via `#[behaviour(out_event = "MyBehaviourEvent")]` or, when not specified, have the derive macro generate one for the user. From 5e29c347514877ae056d68c91d883a5509a356af Mon Sep 17 00:00:00 2001 From: Max Inden Date: Fri, 12 Aug 2022 09:49:03 +0200 Subject: [PATCH 5/9] Update swarm/CHANGELOG.md Co-authored-by: Elena Frank --- swarm/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swarm/CHANGELOG.md b/swarm/CHANGELOG.md index 7eafd18846c..5be72dc6581 100644 --- a/swarm/CHANGELOG.md +++ b/swarm/CHANGELOG.md @@ -14,7 +14,7 @@ #[derive(NetworkBehaviour)] #[behaviour(event_process = true)] struct MyBehaviour { - floodsub: Gossipsub, + gossipsub: Gossipsub, mdns: Mdns, } From df819140e58dab1b419444424dc9820dab06ea6d Mon Sep 17 00:00:00 2001 From: Max Inden Date: Fri, 12 Aug 2022 09:49:11 +0200 Subject: [PATCH 6/9] Update swarm/CHANGELOG.md Co-authored-by: Elena Frank --- swarm/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swarm/CHANGELOG.md b/swarm/CHANGELOG.md index 5be72dc6581..e60a0e85e73 100644 --- a/swarm/CHANGELOG.md +++ b/swarm/CHANGELOG.md @@ -37,7 +37,7 @@ #[derive(NetworkBehaviour)] #[behaviour(out_event = "MyBehaviourEvent")] struct MyBehaviour { - floodsub: Gossipsub, + gossipsub: Gossipsub, mdns: Mdns, } From 8c154526cbe94bca6a3be0737bd0bcf1be70387d Mon Sep 17 00:00:00 2001 From: Max Inden Date: Fri, 12 Aug 2022 09:49:19 +0200 Subject: [PATCH 7/9] Update swarm/CHANGELOG.md Co-authored-by: Elena Frank --- swarm/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swarm/CHANGELOG.md b/swarm/CHANGELOG.md index e60a0e85e73..603a2ca23b4 100644 --- a/swarm/CHANGELOG.md +++ b/swarm/CHANGELOG.md @@ -42,7 +42,7 @@ } enum MyBehaviourEvent { - Floodsub(FloodsubEvent), + Gossipsub(GossipsubEvent), Mdns(MdnsEvent), } From b5cd98da4ed8f5d4869668a5961fa0bd51d81df2 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Fri, 12 Aug 2022 16:52:47 +0900 Subject: [PATCH 8/9] swarm/CHANGELOG: Link entries to PRs --- swarm/CHANGELOG.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/swarm/CHANGELOG.md b/swarm/CHANGELOG.md index 603a2ca23b4..a235c0ae2bc 100644 --- a/swarm/CHANGELOG.md +++ b/swarm/CHANGELOG.md @@ -5,8 +5,8 @@ when not specified, have the derive macro generate one for the user. See [`NetworkBehaviour` - documentation](https://docs.rs/libp2p/latest/libp2p/swarm/trait.NetworkBehaviour.html) for - details. + documentation](https://docs.rs/libp2p/latest/libp2p/swarm/trait.NetworkBehaviour.html) and [PR + 2784] for details. Previously @@ -74,14 +74,16 @@ the user. See [`NetworkBehaviour` - documentation](https://docs.rs/libp2p/latest/libp2p/swarm/trait.NetworkBehaviour.html) for - details. + documentation](https://docs.rs/libp2p/latest/libp2p/swarm/trait.NetworkBehaviour.html) and [PR + 2792] for details. - Update dial address concurrency factor to `8`, thus dialing up to 8 addresses concurrently for a single connection attempt. See `Swarm::dial_concurrency_factor` and [PR 2741]. - Update to `libp2p-core` `v0.35.0`. [PR 2741]: https://github.com/libp2p/rust-libp2p/pull/2741/ +[PR 2784]: https://github.com/libp2p/rust-libp2p/pull/2784 +[PR 2792]: https://github.com/libp2p/rust-libp2p/pull/2792 # 0.37.0 From 0f3ef691ff1499c3fb85f96c21a26b44fea28e23 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Fri, 12 Aug 2022 16:58:23 +0900 Subject: [PATCH 9/9] examples/: Remove usage of NetworkBehaviourEventProcess --- examples/chat-tokio.rs | 80 ++++++++------ examples/chat.rs | 4 +- examples/distributed-key-value-store.rs | 94 ++++++++-------- examples/ipfs-private.rs | 141 +++++++++++++----------- 4 files changed, 172 insertions(+), 147 deletions(-) diff --git a/examples/chat-tokio.rs b/examples/chat-tokio.rs index 66c25205246..a082f3ef113 100644 --- a/examples/chat-tokio.rs +++ b/examples/chat-tokio.rs @@ -44,7 +44,7 @@ use libp2p::{ mdns::{Mdns, MdnsEvent}, mplex, noise, - swarm::{dial_opts::DialOpts, NetworkBehaviourEventProcess, SwarmBuilder, SwarmEvent}, + swarm::{SwarmBuilder, SwarmEvent}, // `TokioTcpTransport` is available through the `tcp-tokio` feature. tcp::TokioTcpTransport, Multiaddr, @@ -82,47 +82,29 @@ async fn main() -> Result<(), Box> { // Create a Floodsub topic let floodsub_topic = floodsub::Topic::new("chat"); - // We create a custom network behaviour that combines floodsub and mDNS. - // The derive generates a delegating `NetworkBehaviour` impl which in turn - // requires the implementations of `NetworkBehaviourEventProcess` for - // the events of each behaviour. + // We create a custom behaviour that combines floodsub and mDNS. + // The derive generates a delegating `NetworkBehaviour` impl. #[derive(NetworkBehaviour)] - #[behaviour(event_process = true)] + #[behaviour(out_event = "MyBehaviourEvent")] struct MyBehaviour { floodsub: Floodsub, mdns: Mdns, } - impl NetworkBehaviourEventProcess for MyBehaviour { - // Called when `floodsub` produces an event. - fn inject_event(&mut self, message: FloodsubEvent) { - if let FloodsubEvent::Message(message) = message { - println!( - "Received: '{:?}' from {:?}", - String::from_utf8_lossy(&message.data), - message.source - ); - } + enum MyBehaviourEvent { + Floodsub(FloodsubEvent), + Mdns(MdnsEvent), + } + + impl From for MyBehaviourEvent { + fn from(event: FloodsubEvent) -> Self { + MyBehaviourEvent::Floodsub(event) } } - impl NetworkBehaviourEventProcess for MyBehaviour { - // Called when `mdns` produces an event. - fn inject_event(&mut self, event: MdnsEvent) { - match event { - MdnsEvent::Discovered(list) => { - for (peer, _) in list { - self.floodsub.add_node_to_partial_view(peer); - } - } - MdnsEvent::Expired(list) => { - for (peer, _) in list { - if !self.mdns.has_node(&peer) { - self.floodsub.remove_node_from_partial_view(&peer); - } - } - } - } + impl From for MyBehaviourEvent { + fn from(event: MdnsEvent) -> Self { + MyBehaviourEvent::Mdns(event) } } @@ -166,8 +148,36 @@ async fn main() -> Result<(), Box> { swarm.behaviour_mut().floodsub.publish(floodsub_topic.clone(), line.as_bytes()); } event = swarm.select_next_some() => { - if let SwarmEvent::NewListenAddr { address, .. } = event { - println!("Listening on {:?}", address); + match event { + SwarmEvent::NewListenAddr { address, .. } => { + println!("Listening on {:?}", address); + } + SwarmEvent::Behaviour(MyBehaviourEvent::Floodsub(event)) => { + if let FloodsubEvent::Message(message) = event { + println!( + "Received: '{:?}' from {:?}", + String::from_utf8_lossy(&message.data), + message.source + ); + } + } + SwarmEvent::Behaviour(MyBehaviourEvent::Mdns(event)) => { + match event { + MdnsEvent::Discovered(list) => { + for (peer, _) in list { + swarm.behaviour_mut().floodsub.add_node_to_partial_view(peer); + } + } + MdnsEvent::Expired(list) => { + for (peer, _) in list { + if !swarm.behaviour().mdns.has_node(&peer) { + swarm.behaviour_mut().floodsub.remove_node_from_partial_view(&peer); + } + } + } + } + } + _ => {} } } } diff --git a/examples/chat.rs b/examples/chat.rs index d03c0a6f3e5..b9569142a41 100644 --- a/examples/chat.rs +++ b/examples/chat.rs @@ -79,9 +79,7 @@ async fn main() -> Result<(), Box> { let floodsub_topic = floodsub::Topic::new("chat"); // We create a custom network behaviour that combines floodsub and mDNS. - // In the future, we want to improve libp2p to make this easier to do. - // Use the derive to generate delegating NetworkBehaviour impl and require the - // NetworkBehaviourEventProcess implementations below. + // Use the derive to generate delegating NetworkBehaviour impl. #[derive(NetworkBehaviour)] #[behaviour(out_event = "OutEvent")] struct MyBehaviour { diff --git a/examples/distributed-key-value-store.rs b/examples/distributed-key-value-store.rs index 6bf28bf0ff9..7fef717cf78 100644 --- a/examples/distributed-key-value-store.rs +++ b/examples/distributed-key-value-store.rs @@ -50,7 +50,7 @@ use libp2p::kad::{ use libp2p::{ development_transport, identity, mdns::{Mdns, MdnsConfig, MdnsEvent}, - swarm::{NetworkBehaviourEventProcess, SwarmEvent}, + swarm::SwarmEvent, NetworkBehaviour, PeerId, Swarm, }; use std::error::Error; @@ -68,28 +68,60 @@ async fn main() -> Result<(), Box> { // We create a custom network behaviour that combines Kademlia and mDNS. #[derive(NetworkBehaviour)] - #[behaviour(event_process = true)] + #[behaviour(out_event = "MyBehaviourEvent")] struct MyBehaviour { kademlia: Kademlia, mdns: Mdns, } - impl NetworkBehaviourEventProcess for MyBehaviour { - // Called when `mdns` produces an event. - fn inject_event(&mut self, event: MdnsEvent) { - if let MdnsEvent::Discovered(list) = event { - for (peer_id, multiaddr) in list { - self.kademlia.add_address(&peer_id, multiaddr); - } - } + enum MyBehaviourEvent { + Kademlia(KademliaEvent), + Mdns(MdnsEvent), + } + + impl From for MyBehaviourEvent { + fn from(event: KademliaEvent) -> Self { + MyBehaviourEvent::Kademlia(event) + } + } + + impl From for MyBehaviourEvent { + fn from(event: MdnsEvent) -> Self { + MyBehaviourEvent::Mdns(event) } } - impl NetworkBehaviourEventProcess for MyBehaviour { - // Called when `kademlia` produces an event. - fn inject_event(&mut self, message: KademliaEvent) { - match message { - KademliaEvent::OutboundQueryCompleted { result, .. } => match result { + // Create a swarm to manage peers and events. + let mut swarm = { + // Create a Kademlia behaviour. + let store = MemoryStore::new(local_peer_id); + let kademlia = Kademlia::new(local_peer_id, store); + let mdns = task::block_on(Mdns::new(MdnsConfig::default()))?; + let behaviour = MyBehaviour { kademlia, mdns }; + Swarm::new(transport, behaviour, local_peer_id) + }; + + // Read full lines from stdin + let mut stdin = io::BufReader::new(io::stdin()).lines().fuse(); + + // Listen on all interfaces and whatever port the OS assigns. + swarm.listen_on("/ip4/0.0.0.0/tcp/0".parse()?)?; + + // Kick it off. + loop { + select! { + line = stdin.select_next_some() => handle_input_line(&mut swarm.behaviour_mut().kademlia, line.expect("Stdin not to close")), + event = swarm.select_next_some() => match event { + SwarmEvent::NewListenAddr { address, .. } => { + println!("Listening in {:?}", address); + }, + SwarmEvent::Behaviour(MyBehaviourEvent::Mdns(MdnsEvent::Discovered(list))) => { + for (peer_id, multiaddr) in list { + swarm.behaviour_mut().kademlia.add_address(&peer_id, multiaddr); + } + } + SwarmEvent::Behaviour(MyBehaviourEvent::Kademlia(KademliaEvent::OutboundQueryCompleted { result, ..})) => { + match result { QueryResult::GetProviders(Ok(ok)) => { for peer in ok.providers { println!( @@ -137,38 +169,10 @@ async fn main() -> Result<(), Box> { eprintln!("Failed to put provider record: {:?}", err); } _ => {} - }, - _ => {} + } } + _ => {} } - } - - // Create a swarm to manage peers and events. - let mut swarm = { - // Create a Kademlia behaviour. - let store = MemoryStore::new(local_peer_id); - let kademlia = Kademlia::new(local_peer_id, store); - let mdns = task::block_on(Mdns::new(MdnsConfig::default()))?; - let behaviour = MyBehaviour { kademlia, mdns }; - Swarm::new(transport, behaviour, local_peer_id) - }; - - // Read full lines from stdin - let mut stdin = io::BufReader::new(io::stdin()).lines().fuse(); - - // Listen on all interfaces and whatever port the OS assigns. - swarm.listen_on("/ip4/0.0.0.0/tcp/0".parse()?)?; - - // Kick it off. - loop { - select! { - line = stdin.select_next_some() => handle_input_line(&mut swarm.behaviour_mut().kademlia, line.expect("Stdin not to close")), - event = swarm.select_next_some() => match event { - SwarmEvent::NewListenAddr { address, .. } => { - println!("Listening in {:?}", address); - }, - _ => {} - } } } } diff --git a/examples/ipfs-private.rs b/examples/ipfs-private.rs index 113bdf988f2..00b529bf6f2 100644 --- a/examples/ipfs-private.rs +++ b/examples/ipfs-private.rs @@ -41,9 +41,10 @@ use libp2p::{ identify::{Identify, IdentifyConfig, IdentifyEvent}, identity, multiaddr::Protocol, - noise, ping, + noise, + ping::{self, PingEvent}, pnet::{PnetConfig, PreSharedKey}, - swarm::{NetworkBehaviourEventProcess, SwarmEvent}, + swarm::SwarmEvent, tcp::TcpTransport, yamux::YamuxConfig, Multiaddr, NetworkBehaviour, PeerId, Swarm, Transport, @@ -157,78 +158,34 @@ async fn main() -> Result<(), Box> { // We create a custom network behaviour that combines gossipsub, ping and identify. #[derive(NetworkBehaviour)] - #[behaviour(event_process = true)] + #[behaviour(out_event = "MyBehaviourEvent")] struct MyBehaviour { gossipsub: Gossipsub, identify: Identify, ping: ping::Behaviour, } - impl NetworkBehaviourEventProcess for MyBehaviour { - // Called when `identify` produces an event. - fn inject_event(&mut self, event: IdentifyEvent) { - println!("identify: {:?}", event); + enum MyBehaviourEvent { + Gossipsub(GossipsubEvent), + Identify(IdentifyEvent), + Ping(PingEvent), + } + + impl From for MyBehaviourEvent { + fn from(event: GossipsubEvent) -> Self { + MyBehaviourEvent::Gossipsub(event) } } - impl NetworkBehaviourEventProcess for MyBehaviour { - // Called when `gossipsub` produces an event. - fn inject_event(&mut self, event: GossipsubEvent) { - match event { - GossipsubEvent::Message { - propagation_source: peer_id, - message_id: id, - message, - } => println!( - "Got message: {} with id: {} from peer: {:?}", - String::from_utf8_lossy(&message.data), - id, - peer_id - ), - _ => {} - } + impl From for MyBehaviourEvent { + fn from(event: IdentifyEvent) -> Self { + MyBehaviourEvent::Identify(event) } } - impl NetworkBehaviourEventProcess for MyBehaviour { - // Called when `ping` produces an event. - fn inject_event(&mut self, event: ping::Event) { - match event { - ping::Event { - peer, - result: Result::Ok(ping::Success::Ping { rtt }), - } => { - println!( - "ping: rtt to {} is {} ms", - peer.to_base58(), - rtt.as_millis() - ); - } - ping::Event { - peer, - result: Result::Ok(ping::Success::Pong), - } => { - println!("ping: pong from {}", peer.to_base58()); - } - ping::Event { - peer, - result: Result::Err(ping::Failure::Timeout), - } => { - println!("ping: timeout to {}", peer.to_base58()); - } - ping::Event { - peer, - result: Result::Err(ping::Failure::Unsupported), - } => { - println!("ping: {} does not support ping protocol", peer.to_base58()); - } - ping::Event { - peer, - result: Result::Err(ping::Failure::Other { error }), - } => { - println!("ping: ping::Failure with {}: {}", peer.to_base58(), error); - } - } + impl From for MyBehaviourEvent { + fn from(event: PingEvent) -> Self { + MyBehaviourEvent::Ping(event) } } @@ -282,8 +239,64 @@ async fn main() -> Result<(), Box> { } }, event = swarm.select_next_some() => { - if let SwarmEvent::NewListenAddr { address, .. } = event { - println!("Listening on {:?}", address); + match event { + SwarmEvent::NewListenAddr { address, .. } => { + println!("Listening on {:?}", address); + } + SwarmEvent::Behaviour(MyBehaviourEvent::Identify(event)) => { + println!("identify: {:?}", event); + } + SwarmEvent::Behaviour(MyBehaviourEvent::Gossipsub(GossipsubEvent::Message { + propagation_source: peer_id, + message_id: id, + message, + })) => { + println!( + "Got message: {} with id: {} from peer: {:?}", + String::from_utf8_lossy(&message.data), + id, + peer_id + ) + } + SwarmEvent::Behaviour(MyBehaviourEvent::Ping(event)) => { + match event { + ping::Event { + peer, + result: Result::Ok(ping::Success::Ping { rtt }), + } => { + println!( + "ping: rtt to {} is {} ms", + peer.to_base58(), + rtt.as_millis() + ); + } + ping::Event { + peer, + result: Result::Ok(ping::Success::Pong), + } => { + println!("ping: pong from {}", peer.to_base58()); + } + ping::Event { + peer, + result: Result::Err(ping::Failure::Timeout), + } => { + println!("ping: timeout to {}", peer.to_base58()); + } + ping::Event { + peer, + result: Result::Err(ping::Failure::Unsupported), + } => { + println!("ping: {} does not support ping protocol", peer.to_base58()); + } + ping::Event { + peer, + result: Result::Err(ping::Failure::Other { error }), + } => { + println!("ping: ping::Failure with {}: {}", peer.to_base58(), error); + } + } + } + _ => {} } } }