diff --git a/misc/peer-store/src/behaviour.rs b/misc/peer-store/src/behaviour.rs index 36bbd11d2c1..2b88c2f8fa5 100644 --- a/misc/peer-store/src/behaviour.rs +++ b/misc/peer-store/src/behaviour.rs @@ -1,24 +1,8 @@ -use std::{collections::VecDeque, task::Poll}; - use libp2p_core::{Multiaddr, PeerId}; use libp2p_swarm::{dummy, NetworkBehaviour}; use crate::store::Store; -/// Events generated by [`Behaviour`] and emitted back to [`Swarm`](libp2p_swarm::Swarm). -#[derive(Debug, Clone)] -pub enum Event { - /// The peer's record has been updated. - /// Manually updating a record will always emit this event - /// even if it provides no new information. - RecordUpdated { - /// The peer that has an update. - peer: PeerId, - }, - /// Event from the internal store. - Store(T), -} - /// Behaviour that maintains a peer address book. /// /// Usage: @@ -39,8 +23,6 @@ pub enum Event { pub struct Behaviour { /// The internal store. store: S, - /// Pending Events to be emitted back to [`Swarm`](libp2p_swarm::Swarm). - pending_events: VecDeque>, } impl<'a, S> Behaviour @@ -49,10 +31,7 @@ where { /// Build a new [`Behaviour`] with the given store. pub fn new(store: S) -> Self { - Self { - store, - pending_events: VecDeque::new(), - } + Self { store } } /// Try to get all observed address of the given peer. @@ -73,24 +52,16 @@ where pub fn store_mut(&mut self) -> &mut S { &mut self.store } - - fn handle_store_event(&mut self, event: crate::store::Event<::FromStore>) { - use crate::store::Event::*; - match event { - RecordUpdated(peer) => self.pending_events.push_back(Event::RecordUpdated { peer }), - Store(ev) => self.pending_events.push_back(Event::Store(ev)), - } - } } impl NetworkBehaviour for Behaviour where S: Store + 'static, - ::FromStore: Send + Sync, + ::Event: Send + Sync, { type ConnectionHandler = dummy::ConnectionHandler; - type ToSwarm = Event; + type ToSwarm = S::Event; fn handle_established_inbound_connection( &mut self, @@ -149,13 +120,8 @@ where cx: &mut std::task::Context<'_>, ) -> std::task::Poll>> { - if let Some(ev) = self.store.poll(cx) { - self.handle_store_event(ev); - }; - - if let Some(ev) = self.pending_events.pop_front() { - return Poll::Ready(libp2p_swarm::ToSwarm::GenerateEvent(ev)); - } - Poll::Pending + self.store + .poll(cx) + .map(libp2p_swarm::ToSwarm::GenerateEvent) } } diff --git a/misc/peer-store/src/lib.rs b/misc/peer-store/src/lib.rs index e306b828f51..31f7eb6497c 100644 --- a/misc/peer-store/src/lib.rs +++ b/misc/peer-store/src/lib.rs @@ -21,5 +21,5 @@ mod behaviour; pub mod memory_store; mod store; -pub use behaviour::{Behaviour, Event}; +pub use behaviour::Behaviour; pub use store::Store; diff --git a/misc/peer-store/src/memory_store.rs b/misc/peer-store/src/memory_store.rs index 49e542a9e2f..946b0a3aa4f 100644 --- a/misc/peer-store/src/memory_store.rs +++ b/misc/peer-store/src/memory_store.rs @@ -11,7 +11,7 @@ use std::{ collections::{HashMap, VecDeque}, num::NonZeroUsize, - task::Waker, + task::{Poll, Waker}, }; use libp2p_core::{Multiaddr, PeerId}; @@ -20,11 +20,31 @@ use lru::LruCache; use super::Store; -/// Event from the store and emitted to [`Swarm`](libp2p_swarm::Swarm). +/// Event emitted from the [`MemoryStore`] to the [`Swarm`](libp2p_swarm::Swarm). #[derive(Debug, Clone)] pub enum Event { - /// Custom data of the peer has been updated. - CustomDataUpdated(PeerId), + /// A new peer address has been added to the store. + PeerAddressAdded { + /// ID of the peer for which the address was added. + peer_id: PeerId, + /// The added address. + address: Multiaddr, + /// Whether the address will be kept in the store after a dial-failure. + /// + /// Set to `true` when an address was added explicitly through + /// [`MemoryStore::add_address`], `false` if the address was discovered through the + /// swarm or other behaviors. + /// + /// Only relevant when [`Config::is_remove_addr_on_dial_error`] is `true`. + is_permanent: bool, + }, + /// A peer address has been removed from the store. + PeerAddressRemoved { + /// ID of the peer for which the address was removed. + peer_id: PeerId, + /// The removed address. + address: Multiaddr, + }, } /// A in-memory store that uses LRU cache for bounded storage of addresses @@ -34,7 +54,7 @@ pub struct MemoryStore { /// The internal store. records: HashMap>, /// Events to emit to [`Behaviour`](crate::Behaviour) and [`Swarm`](libp2p_swarm::Swarm). - pending_events: VecDeque>, + pending_events: VecDeque, /// Config of the store. config: Config, /// Waker for store events. @@ -52,7 +72,7 @@ impl MemoryStore { } } - /// Update an address record and notify swarm if the address is new. + /// Add an address for a peer. /// /// The added address will NOT be removed from the store on dial failure. If the added address /// is supposed to be cleared from the store on dial failure, add it by emitting @@ -60,59 +80,62 @@ impl MemoryStore { /// [`Swarm::add_peer_address`](libp2p_swarm::Swarm::add_peer_address). /// /// Returns `true` if the address is new. - pub fn update_address(&mut self, peer: &PeerId, address: &Multiaddr) -> bool { - let is_updated = self.update_address_silent(peer, address, true); - if is_updated { - self.push_event_and_wake(crate::store::Event::RecordUpdated(*peer)); - } - is_updated + pub fn add_address(&mut self, peer: &PeerId, address: &Multiaddr) -> bool { + self.add_address_inner(peer, address, true) } - /// Update an address record without notifying swarm. + /// Update an address record and notify the swarm. /// /// Returns `true` if the address is new. - fn update_address_silent( + fn add_address_inner( &mut self, peer: &PeerId, address: &Multiaddr, - permanent: bool, + is_permanent: bool, ) -> bool { - if let Some(record) = self.records.get_mut(peer) { - return record.update_address(address, permanent); + let record = self + .records + .entry(*peer) + .or_insert(PeerRecord::new(self.config.record_capacity)); + let is_new = record.add_address(address, is_permanent); + if is_new { + self.push_event_and_wake(Event::PeerAddressAdded { + peer_id: *peer, + address: address.clone(), + is_permanent, + }); } - let mut new_record = PeerRecord::new(self.config.record_capacity); - new_record.update_address(address, permanent); - self.records.insert(*peer, new_record); - true + is_new } /// Remove an address record. /// /// Returns `true` when the address existed. pub fn remove_address(&mut self, peer: &PeerId, address: &Multiaddr) -> bool { - let is_updated = self.remove_address_silent(peer, address, true); - if is_updated { - self.push_event_and_wake(crate::store::Event::RecordUpdated(*peer)); - } - is_updated + self.remove_address_inner(peer, address, true) } - /// Remove an address record without notifying swarm. + /// Remove an address record and notify the swarm. /// /// Returns `true` when the address is removed, `false` if the address didn't exist /// or the address is permanent and `force` false. - fn remove_address_silent(&mut self, peer: &PeerId, address: &Multiaddr, force: bool) -> bool { + fn remove_address_inner(&mut self, peer: &PeerId, address: &Multiaddr, force: bool) -> bool { if let Some(record) = self.records.get_mut(peer) { if record.remove_address(address, force) { if record.addresses.is_empty() && record.custom_data.is_none() { self.records.remove(peer); } + self.push_event_and_wake(Event::PeerAddressRemoved { + peer_id: *peer, + address: address.clone(), + }); return true; } } false } + /// Get a reference to a peer's custom data. pub fn get_custom_data(&self, peer: &PeerId) -> Option<&T> { self.records.get(peer).and_then(|r| r.get_custom_data()) } @@ -129,14 +152,8 @@ impl MemoryStore { None } - /// Insert the data and notify the swarm about the update, dropping the old data if it exists. + /// Insert the data, dropping the old data if it exists. pub fn insert_custom_data(&mut self, peer: &PeerId, custom_data: T) { - self.insert_custom_data_silent(peer, custom_data); - self.push_event_and_wake(crate::store::Event::Store(Event::CustomDataUpdated(*peer))); - } - - /// Insert the data without notifying the swarm. Old data will be dropped if it exists. - fn insert_custom_data_silent(&mut self, peer: &PeerId, custom_data: T) { if let Some(r) = self.records.get_mut(peer) { return r.insert_custom_data(custom_data); } @@ -145,18 +162,8 @@ impl MemoryStore { self.records.insert(*peer, new_record); } - /// Get a mutable reference to a peer's custom data. If it exists, the swarm is notified about - /// its modification, regardless of whether it will actually be modified. + /// Get a mutable reference to a peer's custom data. pub fn get_custom_data_mut(&mut self, peer: &PeerId) -> Option<&mut T> { - // We have to do this separately to avoid a double borrow. - if self - .records - .get(peer) - .is_some_and(|r| r.get_custom_data().is_some()) - { - self.push_event_and_wake(crate::store::Event::Store(Event::CustomDataUpdated(*peer))); - }; - self.records .get_mut(peer) .and_then(|r| r.get_custom_data_mut()) @@ -167,13 +174,14 @@ impl MemoryStore { self.records.iter() } - /// Iterate over all internal records mutably. - /// Will not wake up the task. + /// Iterate over all internal records mutably. + /// + /// Changes to the records will not generate an event. pub fn record_iter_mut(&mut self) -> impl Iterator)> { self.records.iter_mut() } - fn push_event_and_wake(&mut self, event: crate::store::Event) { + fn push_event_and_wake(&mut self, event: Event) { self.pending_events.push_back(event); if let Some(waker) = self.waker.take() { waker.wake(); // wake up because of update @@ -182,14 +190,12 @@ impl MemoryStore { } impl Store for MemoryStore { - type FromStore = Event; + type Event = Event; fn on_swarm_event(&mut self, swarm_event: &FromSwarm) { match swarm_event { FromSwarm::NewExternalAddrOfPeer(info) => { - if self.update_address_silent(&info.peer_id, info.addr, false) { - self.push_event_and_wake(crate::store::Event::RecordUpdated(info.peer_id)); - } + self.add_address_inner(&info.peer_id, info.addr, false); } FromSwarm::ConnectionEstablished(ConnectionEstablished { peer_id, @@ -197,18 +203,12 @@ impl Store for MemoryStore { endpoint, .. }) if endpoint.is_dialer() => { - let mut is_record_updated = false; if self.config.remove_addr_on_dial_error { for failed_addr in *failed_addresses { - is_record_updated |= - self.remove_address_silent(peer_id, failed_addr, false); + self.remove_address_inner(peer_id, failed_addr, false); } } - is_record_updated |= - self.update_address_silent(peer_id, endpoint.get_remote_address(), false); - if is_record_updated { - self.push_event_and_wake(crate::store::Event::RecordUpdated(*peer_id)); - } + self.add_address_inner(peer_id, endpoint.get_remote_address(), false); } FromSwarm::DialFailure(info) => { if !self.config.remove_addr_on_dial_error { @@ -221,31 +221,15 @@ impl Store for MemoryStore { }; match info.error { - DialError::LocalPeerId { .. } => { - // The stored peer is the local peer. Remove peer fully. - if self.records.remove(&peer).is_some() { - self.push_event_and_wake(crate::store::Event::RecordUpdated(peer)); - } - } DialError::WrongPeerId { obtained, address } => { // The stored peer id is incorrect, remove incorrect and add correct one. - if self.remove_address_silent(&peer, address, false) { - self.push_event_and_wake(crate::store::Event::RecordUpdated(peer)); - if self.update_address_silent(obtained, address, false) { - self.push_event_and_wake(crate::store::Event::RecordUpdated( - *obtained, - )); - } + if self.remove_address_inner(&peer, address, false) { + self.add_address_inner(obtained, address, false); } } DialError::Transport(errors) => { - // Remove all attempted addresses. - let mut is_record_updated = false; for (addr, _) in errors { - is_record_updated |= self.remove_address_silent(&peer, addr, false); - } - if is_record_updated { - self.push_event_and_wake(crate::store::Event::RecordUpdated(peer)); + self.remove_address_inner(&peer, addr, false); } } _ => {} @@ -259,14 +243,14 @@ impl Store for MemoryStore { self.records.get(peer).map(|record| record.addresses()) } - fn poll( - &mut self, - cx: &mut std::task::Context<'_>, - ) -> Option> { - if self.pending_events.is_empty() { - self.waker = Some(cx.waker().clone()); + fn poll(&mut self, cx: &mut std::task::Context<'_>) -> Poll { + match self.pending_events.pop_front() { + Some(ev) => Poll::Ready(ev), + None => { + self.waker = Some(cx.waker().clone()); + Poll::Pending + } } - self.pending_events.pop_front() } } @@ -348,14 +332,16 @@ impl PeerRecord { /// insert it to the front if not. /// /// Returns true when the address is new. - pub fn update_address(&mut self, address: &Multiaddr, permanent: bool) -> bool { + pub fn add_address(&mut self, address: &Multiaddr, is_permanent: bool) -> bool { if let Some(was_permanent) = self.addresses.get(address) { - if !*was_permanent && permanent { - self.addresses.get_or_insert(address.clone(), || permanent); + if !*was_permanent && is_permanent { + self.addresses + .get_or_insert(address.clone(), || is_permanent); } return false; } - self.addresses.get_or_insert(address.clone(), || permanent); + self.addresses + .get_or_insert(address.clone(), || is_permanent); true } @@ -385,18 +371,22 @@ impl PeerRecord { pub fn insert_custom_data(&mut self, custom_data: T) { let _ = self.custom_data.insert(custom_data); } + + pub fn is_empty(&self) -> bool { + self.addresses.is_empty() && self.custom_data.is_none() + } } #[cfg(test)] mod test { use std::{num::NonZero, str::FromStr}; - use libp2p::Swarm; - use libp2p_core::{Multiaddr, PeerId}; - use libp2p_swarm::{NetworkBehaviour, SwarmEvent}; + use libp2p::identify; + use libp2p_core::{multiaddr::Protocol, Multiaddr, PeerId}; + use libp2p_swarm::{NetworkBehaviour, Swarm, SwarmEvent}; use libp2p_swarm_test::SwarmExt; - use super::MemoryStore; + use super::{Event, MemoryStore}; use crate::Store; #[test] @@ -406,9 +396,9 @@ mod test { let addr1 = Multiaddr::from_str("/ip4/127.0.0.1").expect("parsing to succeed"); let addr2 = Multiaddr::from_str("/ip4/127.0.0.2").expect("parsing to succeed"); let addr3 = Multiaddr::from_str("/ip4/127.0.0.3").expect("parsing to succeed"); - store.update_address(&peer, &addr1); - store.update_address(&peer, &addr2); - store.update_address(&peer, &addr3); + store.add_address(&peer, &addr1); + store.add_address(&peer, &addr2); + store.add_address(&peer, &addr3); assert!( store .records @@ -418,7 +408,7 @@ mod test { .collect::>() == vec![&addr3, &addr2, &addr1] ); - store.update_address(&peer, &addr1); + store.add_address(&peer, &addr1); assert!( store .records @@ -428,7 +418,7 @@ mod test { .collect::>() == vec![&addr1, &addr3, &addr2] ); - store.update_address(&peer, &addr3); + store.add_address(&peer, &addr3); assert!( store .records @@ -446,7 +436,7 @@ mod test { let peer = PeerId::random(); for i in 1..10 { let addr_string = format!("/ip4/127.0.0.{}", i); - store.update_address( + store.add_address( &peer, &Multiaddr::from_str(&addr_string).expect("parsing to succeed"), ); @@ -472,15 +462,20 @@ mod test { async fn expect_record_update( swarm: &mut Swarm>, expected_peer: PeerId, + expected_address: Option<&Multiaddr>, ) { - swarm - .wait(|ev| match ev { - SwarmEvent::Behaviour(crate::Event::RecordUpdated { peer }) => { - (peer == expected_peer).then_some(()) - } - _ => None, - }) - .await + match swarm.next_behaviour_event().await { + Event::PeerAddressAdded { + peer_id, + address, + is_permanent, + } => { + assert_eq!(peer_id, expected_peer); + assert!(expected_address.is_none_or(|a| *a == address)); + assert!(!is_permanent) + } + ev => panic!("Unexpected event {:?}.", ev), + } } let store1: MemoryStore<()> = MemoryStore::new( @@ -497,19 +492,13 @@ mod test { let rt = tokio::runtime::Runtime::new().unwrap(); rt.block_on(async { - let (listen_addr, _) = swarm1.listen().with_memory_addr_external().await; + let (mut listen_addr, _) = swarm1.listen().with_memory_addr_external().await; let swarm1_peer_id = *swarm1.local_peer_id(); let swarm2_peer_id = *swarm2.local_peer_id(); - swarm2.dial(listen_addr.clone()).expect("dial to succeed"); - let handle = spawn_wait_conn_established(swarm1); - swarm2 - .wait(|ev| match ev { - SwarmEvent::ConnectionEstablished { .. } => Some(()), - _ => None, - }) - .await; - let mut swarm1 = handle.await.expect("future to complete"); - expect_record_update(&mut swarm2, swarm1_peer_id).await; + swarm2.connect(&mut swarm1).await; + + listen_addr.push(Protocol::P2p(swarm1_peer_id)); + expect_record_update(&mut swarm2, swarm1_peer_id, Some(&listen_addr)).await; assert!(swarm2 .behaviour() .address_of_peer(&swarm1_peer_id) @@ -520,8 +509,8 @@ mod test { .behaviour() .address_of_peer(&swarm2_peer_id) .is_none()); - let (new_listen_addr, _) = swarm1.listen().with_memory_addr_external().await; - let handle = spawn_wait_conn_established(swarm1); + let (mut new_listen_addr, _) = swarm1.listen().with_memory_addr_external().await; + tokio::spawn(swarm1.loop_on_next()); swarm2 .dial( libp2p_swarm::dial_opts::DialOpts::peer_id(swarm1_peer_id) @@ -536,19 +525,19 @@ mod test { _ => None, }) .await; - handle.await.expect("future to complete"); - expect_record_update(&mut swarm2, swarm1_peer_id).await; + new_listen_addr.push(Protocol::P2p(swarm1_peer_id)); + expect_record_update(&mut swarm2, swarm1_peer_id, Some(&new_listen_addr)).await; // The address in store will contain peer ID. let new_listen_addr = new_listen_addr .with_p2p(swarm1_peer_id) .expect("extend to succeed"); - assert!( + assert_eq!( swarm2 .behaviour() .address_of_peer(&swarm1_peer_id) .expect("peer to exist") - .collect::>() - == vec![&new_listen_addr, &listen_addr] + .collect::>(), + vec![&new_listen_addr, &listen_addr] ); }) } @@ -558,17 +547,29 @@ mod test { #[derive(NetworkBehaviour)] struct Behaviour { peer_store: crate::Behaviour, - identify: libp2p::identify::Behaviour, + identify: identify::Behaviour, } - async fn expect_record_update(swarm: &mut Swarm, expected_peer: PeerId) { - swarm - .wait(|ev| match ev { - SwarmEvent::Behaviour(BehaviourEvent::PeerStore( - crate::Event::RecordUpdated { peer }, - )) => (peer == expected_peer).then_some(()), - _ => None, - }) - .await + async fn expect_record_update( + swarm: &mut Swarm, + expected_peer: PeerId, + expected_address: Option<&Multiaddr>, + ) { + loop { + match swarm.next_behaviour_event().await { + BehaviourEvent::PeerStore(Event::PeerAddressAdded { + peer_id, + address, + is_permanent, + }) => { + assert_eq!(peer_id, expected_peer); + assert!(expected_address.is_none_or(|a| *a == address)); + assert!(!is_permanent); + break; + } + ev @ BehaviourEvent::PeerStore(_) => panic!("Unexpected event {:?}.", ev), + _ => {} + } + } } fn build_swarm() -> Swarm { Swarm::new_ephemeral_tokio(|kp| Behaviour { @@ -576,7 +577,7 @@ mod test { crate::memory_store::Config::default() .set_record_capacity(NonZero::new(4).expect("4 > 0")), )), - identify: libp2p::identify::Behaviour::new(libp2p::identify::Config::new( + identify: identify::Behaviour::new(identify::Config::new( "/TODO/0.0.1".to_string(), kp.public(), )), @@ -587,29 +588,32 @@ mod test { let rt = tokio::runtime::Runtime::new().unwrap(); rt.block_on(async { - let (listen_addr, _) = swarm1.listen().with_memory_addr_external().await; + let (mut listen_addr, _) = swarm1.listen().with_memory_addr_external().await; let swarm1_peer_id = *swarm1.local_peer_id(); let swarm2_peer_id = *swarm2.local_peer_id(); - swarm2.dial(listen_addr.clone()).expect("dial to succeed"); - let handle = spawn_wait_conn_established(swarm1); - let mut swarm2 = spawn_wait_conn_established(swarm2) - .await - .expect("future to complete"); - let mut swarm1 = handle.await.expect("future to complete"); - expect_record_update(&mut swarm2, swarm1_peer_id).await; - assert!(swarm2 - .behaviour() - .peer_store - .address_of_peer(&swarm1_peer_id) - .expect("swarm should be connected and record about it should be created") - .any(|addr| *addr == listen_addr)); - assert!(swarm1 - .behaviour() - .peer_store - .address_of_peer(&swarm2_peer_id) - .is_none()); - swarm1.next_swarm_event().await; // skip `identify::Event::Sent` - swarm1.next_swarm_event().await; // skip `identify::Event::Received` + swarm2.connect(&mut swarm1).await; + + listen_addr.push(Protocol::P2p(swarm1_peer_id)); + expect_record_update(&mut swarm2, swarm1_peer_id, Some(&listen_addr)).await; + + assert_eq!( + swarm2 + .behaviour() + .peer_store + .address_of_peer(&swarm1_peer_id) + .expect("swarm should be connected and record about it should be created") + .collect::>(), + vec![&listen_addr] + ); + + assert!(matches!( + swarm1.next_behaviour_event().await, + BehaviourEvent::Identify(identify::Event::Sent { .. }) + )); + assert!(matches!( + swarm1.next_behaviour_event().await, + BehaviourEvent::Identify(identify::Event::Received { .. }) + )); let (new_listen_addr, _) = swarm1.listen().with_memory_addr_external().await; swarm1.behaviour_mut().identify.push([swarm2_peer_id]); tokio::spawn(swarm1.loop_on_next()); @@ -617,32 +621,18 @@ mod test { // 2 pair of mem and tcp address for two calls to `::listen()` // with one address already present through direct connection. // FLAKY: tcp addresses are not explicitly marked as external addresses. - expect_record_update(&mut swarm2, swarm1_peer_id).await; - expect_record_update(&mut swarm2, swarm1_peer_id).await; - expect_record_update(&mut swarm2, swarm1_peer_id).await; + expect_record_update(&mut swarm2, swarm1_peer_id, None).await; + expect_record_update(&mut swarm2, swarm1_peer_id, None).await; + expect_record_update(&mut swarm2, swarm1_peer_id, None).await; // The address in store won't contain peer ID because it is from Identify. - assert!(swarm2 + let known_listen_addresses = swarm2 .behaviour() .peer_store .address_of_peer(&swarm1_peer_id) .expect("peer to exist") - .any(|addr| *addr == new_listen_addr)); - }) - } - - fn spawn_wait_conn_established(mut swarm: Swarm) -> tokio::task::JoinHandle> - where - T: NetworkBehaviour + Send + Sync, - Swarm: SwarmExt, - { - tokio::spawn(async move { - swarm - .wait(|ev| match ev { - SwarmEvent::ConnectionEstablished { .. } => Some(()), - _ => None, - }) - .await; - swarm + .collect::>(); + assert!(known_listen_addresses.contains(&&new_listen_addr)); + assert_eq!(known_listen_addresses.len(), 4) }) } } diff --git a/misc/peer-store/src/store.rs b/misc/peer-store/src/store.rs index 1226c8f6071..adf5087b80d 100644 --- a/misc/peer-store/src/store.rs +++ b/misc/peer-store/src/store.rs @@ -1,4 +1,7 @@ -use std::{fmt::Debug, task::Context}; +use std::{ + fmt::Debug, + task::{Context, Poll}, +}; use libp2p_core::{Multiaddr, PeerId}; use libp2p_swarm::FromSwarm; @@ -7,7 +10,7 @@ use libp2p_swarm::FromSwarm; pub trait Store { /// Event generated by the store and emitted to [`Swarm`](libp2p_swarm::Swarm). /// [`Behaviour`](crate::Behaviour) cannot handle this event. - type FromStore: Debug + Send; + type Event: Debug + Send; /// How this store handles events from [`Swarm`](libp2p_swarm::Swarm). fn on_swarm_event(&mut self, event: &FromSwarm); @@ -18,14 +21,5 @@ pub trait Store { /// Polls for things that the store should do. /// The task should be waked up to emit events to [`Behaviour`](crate::Behaviour) and /// [`Swarm`](libp2p_swarm::Swarm). - fn poll(&mut self, cx: &mut Context<'_>) -> Option>; -} - -/// Event that will be handled by [`Behaviour`](crate::Behaviour). -pub enum Event { - /// An address record has been updated. - RecordUpdated(PeerId), - /// Event generated by the store. - /// [`Behaviour`](crate::Behaviour) can only forward the event to swarm. - Store(T), + fn poll(&mut self, cx: &mut Context<'_>) -> Poll; }