-
Notifications
You must be signed in to change notification settings - Fork 1.1k
feat(peer-store): introduce libp2p-peer-store #5724
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
Merged
+777
−0
Merged
Changes from all commits
Commits
Show all changes
49 commits
Select commit
Hold shift + click to select a range
1affefe
template implementation
drHuangMHT 8d4930a
implement in-memory store
drHuangMHT 9cb59c3
manifest update
drHuangMHT fbc1344
formatting
drHuangMHT 2bcfa7f
docs
drHuangMHT 6df6ee5
return iterator of references instead of heap allocation
drHuangMHT 99a6bfd
move conencted_peers out of Store
drHuangMHT 5c7ba32
use capped LruCache instead of uncapped HashMap for address records
drHuangMHT b6dcd59
update address book when a connection is established regardless of fu…
drHuangMHT cbb1906
provide address for dial
drHuangMHT 6270259
apply suggestions
drHuangMHT cc91ab5
garbage collect records, test
drHuangMHT f9b040e
documentation and formatting
drHuangMHT a9597da
clippy lint
drHuangMHT 0e6b280
simplify Store trait
drHuangMHT fe14c42
Merge branch 'master' into peer-store
drHuangMHT 92ac2fb
manifest and changelog
drHuangMHT 913ed1f
Merge branch 'peer-store' of https://github.com/drHuangMHT/rust-libp2…
drHuangMHT b8a7114
export at libp2p crate root
drHuangMHT 5f628fb
changelog for libp2p
drHuangMHT 121e91b
introduce PeerRecord
drHuangMHT 47048ec
remove borrowed type and unused associated type
drHuangMHT 9da96ff
move garbage collection to Store level
drHuangMHT 9945fd0
delay cloning of PeerRecord
drHuangMHT cb294c6
MemoryStore strict mode
drHuangMHT a9dc9aa
allow Store to report to Swarm
drHuangMHT c94f636
don't store connected peers
drHuangMHT a02f088
allow attaching custom data
drHuangMHT a909499
make Behaviour composable
drHuangMHT 7c4d9b4
event hierarchy rework
drHuangMHT 5639ae5
simplify Store trait
drHuangMHT a040e07
doc test
drHuangMHT 7c847a6
doc and manifests
drHuangMHT dee1897
Merge branch 'master' into peer-store
drHuangMHT 9af4c69
add peer-store to full feature set
drHuangMHT 9cb909b
simplify MemoryStore, serde support
drHuangMHT 9740566
Merge branch 'master' into peer-store
drHuangMHT 3ea8439
tests with Swarm and Identify
drHuangMHT cdb9188
docs
drHuangMHT 4a76192
clippy lint
drHuangMHT 082eb16
doc link
drHuangMHT 7063769
register waker for MemoryStore
drHuangMHT 06ed691
fix imports in doc test
drHuangMHT c9e2c0b
Merge branch 'master' into peer-store
drHuangMHT 00d8d33
fmt
drHuangMHT e6f3d46
remove serde related code
drHuangMHT 04014ec
Merge branch 'master' into peer-store
drHuangMHT fc15981
Merge branch 'master' into peer-store
jxs be8a497
do not publish
jxs File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
## 0.1.0 | ||
|
||
- Introduce `libp2p-peer-store`. | ||
See [PR 5724](https://github.com/libp2p/rust-libp2p/pull/5724). |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
[package] | ||
name = "libp2p-peer-store" | ||
edition = "2021" | ||
version = "0.1.0" | ||
authors = ["drHuangMHT <[email protected]>"] | ||
license = "MIT" | ||
repository = "https://github.com/libp2p/rust-libp2p" | ||
publish = false | ||
rust-version.workspace = true | ||
|
||
[dependencies] | ||
libp2p-core = { workspace = true } | ||
libp2p-swarm = { workspace = true } | ||
lru = "0.12.3" | ||
libp2p-identity = { workspace = true, optional = true } | ||
|
||
[dev-dependencies] | ||
tokio = { workspace = true, features = ["macros", "rt-multi-thread"] } | ||
libp2p-identity = { workspace = true, features = ["rand", "serde"] } | ||
libp2p = { workspace = true, features = ["macros", "identify"] } | ||
libp2p-swarm-test = { path = "../../swarm-test", features = ["tokio"] } | ||
serde_json = { version = "1.0.134" } | ||
|
||
[lints] | ||
workspace = true |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
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<T> { | ||
/// 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), | ||
drHuangMHT marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
drHuangMHT marked this conversation as resolved.
Show resolved
Hide resolved
|
||
/// Behaviour that maintains a peer address book. | ||
/// | ||
/// Usage: | ||
/// ``` | ||
/// use libp2p::swarm::NetworkBehaviour; | ||
/// use libp2p_peer_store::{memory_store::MemoryStore, Behaviour}; | ||
/// | ||
/// // `identify::Behaviour` broadcasts listen addresses of the peer, | ||
/// // `peer_store::Behaviour` will then capture the resulting | ||
/// // `FromSwarm::NewExternalAddrOfPeer` and add the addresses | ||
/// // to address book. | ||
/// #[derive(NetworkBehaviour)] | ||
/// struct ComposedBehaviour { | ||
/// peer_store: Behaviour<MemoryStore>, | ||
/// identify: libp2p::identify::Behaviour, | ||
/// } | ||
/// ``` | ||
drHuangMHT marked this conversation as resolved.
Show resolved
Hide resolved
|
||
pub struct Behaviour<S: Store> { | ||
/// The internal store. | ||
store: S, | ||
/// Pending Events to be emitted back to [`Swarm`](libp2p_swarm::Swarm). | ||
pending_events: VecDeque<Event<S::FromStore>>, | ||
} | ||
|
||
drHuangMHT marked this conversation as resolved.
Show resolved
Hide resolved
|
||
impl<'a, S> Behaviour<S> | ||
where | ||
S: Store + 'static, | ||
{ | ||
/// Build a new [`Behaviour`] with the given store. | ||
pub fn new(store: S) -> Self { | ||
Self { | ||
store, | ||
pending_events: VecDeque::new(), | ||
} | ||
} | ||
|
||
/// Try to get all observed address of the given peer. | ||
/// Returns `None` when the peer is not in the store. | ||
pub fn address_of_peer<'b>( | ||
&'a self, | ||
peer: &'b PeerId, | ||
) -> Option<impl Iterator<Item = &'a Multiaddr> + use<'a, 'b, S>> { | ||
self.store.addresses_of_peer(peer) | ||
} | ||
|
||
/// Get an immutable reference to the internal store. | ||
pub fn store(&self) -> &S { | ||
&self.store | ||
} | ||
|
||
/// Get a mutable reference to the internal store. | ||
pub fn store_mut(&mut self) -> &mut S { | ||
&mut self.store | ||
} | ||
|
||
fn handle_store_event(&mut self, event: crate::store::Event<<S as Store>::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<S> NetworkBehaviour for Behaviour<S> | ||
where | ||
S: Store + 'static, | ||
<S as Store>::FromStore: Send + Sync, | ||
{ | ||
type ConnectionHandler = dummy::ConnectionHandler; | ||
|
||
type ToSwarm = Event<S::FromStore>; | ||
|
||
fn handle_established_inbound_connection( | ||
&mut self, | ||
_connection_id: libp2p_swarm::ConnectionId, | ||
_peer: libp2p_core::PeerId, | ||
_local_addr: &libp2p_core::Multiaddr, | ||
_remote_addr: &libp2p_core::Multiaddr, | ||
) -> Result<libp2p_swarm::THandler<Self>, libp2p_swarm::ConnectionDenied> { | ||
Ok(dummy::ConnectionHandler) | ||
} | ||
|
||
fn handle_pending_outbound_connection( | ||
&mut self, | ||
_connection_id: libp2p_swarm::ConnectionId, | ||
maybe_peer: Option<PeerId>, | ||
_addresses: &[Multiaddr], | ||
_effective_role: libp2p_core::Endpoint, | ||
) -> Result<Vec<Multiaddr>, libp2p_swarm::ConnectionDenied> { | ||
if maybe_peer.is_none() { | ||
return Ok(Vec::new()); | ||
} | ||
let peer = maybe_peer.expect("already handled"); | ||
Ok(self | ||
.store | ||
.addresses_of_peer(&peer) | ||
.map(|i| i.cloned().collect()) | ||
.unwrap_or_default()) | ||
} | ||
|
||
fn handle_established_outbound_connection( | ||
&mut self, | ||
_connection_id: libp2p_swarm::ConnectionId, | ||
_peer: libp2p_core::PeerId, | ||
_addr: &libp2p_core::Multiaddr, | ||
_role_override: libp2p_core::Endpoint, | ||
_port_use: libp2p_core::transport::PortUse, | ||
) -> Result<libp2p_swarm::THandler<Self>, libp2p_swarm::ConnectionDenied> { | ||
Ok(dummy::ConnectionHandler) | ||
} | ||
|
||
fn on_swarm_event(&mut self, event: libp2p_swarm::FromSwarm) { | ||
self.store.on_swarm_event(&event); | ||
} | ||
|
||
fn on_connection_handler_event( | ||
&mut self, | ||
_peer_id: libp2p_core::PeerId, | ||
_connection_id: libp2p_swarm::ConnectionId, | ||
_event: libp2p_swarm::THandlerOutEvent<Self>, | ||
) { | ||
unreachable!("No event will be produced by a dummy handler.") | ||
} | ||
|
||
fn poll( | ||
&mut self, | ||
cx: &mut std::task::Context<'_>, | ||
) -> std::task::Poll<libp2p_swarm::ToSwarm<Self::ToSwarm, libp2p_swarm::THandlerInEvent<Self>>> | ||
{ | ||
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 | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
//! Implementation of peer store that stores address information | ||
//! about foreign peers. | ||
//! | ||
//! ## Important Discrepancies | ||
//! - **PeerStore is a local**: The peer store itself doesn't facilitate any information exchange | ||
//! between peers. You will need other protocols like `libp2p-kad` to share addresses you know | ||
//! across the network. | ||
//! - **PeerStore is a standalone**: Other protocols cannot expect the existence of PeerStore, and | ||
//! need to be manually hooked up to PeerStore in order to obtain information it provides. | ||
//! | ||
//! ## Usage | ||
//! Compose [`Behaviour`] with other [`NetworkBehaviour`](libp2p_swarm::NetworkBehaviour), | ||
//! and the PeerStore will automatically track addresses from | ||
//! [`FromSwarm::NewExternalAddrOfPeer`](libp2p_swarm::FromSwarm) | ||
//! and provide addresses when dialing peers(require `extend_addresses_through_behaviour` in | ||
//! [`DialOpts`](libp2p_swarm::dial_opts::DialOpts) when dialing). | ||
//! Other protocols need to be manually hooked up to obtain information from | ||
//! or provide information to PeerStore. | ||
|
||
mod behaviour; | ||
pub mod memory_store; | ||
mod store; | ||
|
||
pub use behaviour::{Behaviour, Event}; | ||
pub use store::Store; |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.