mirror of
https://github.com/fluencelabs/rust-libp2p
synced 2025-07-31 00:41:59 +00:00
Add dumb peerstore for feedback
This commit is contained in:
@@ -5,6 +5,7 @@ members = [
|
||||
"datastore",
|
||||
"libp2p-host",
|
||||
"libp2p-peer",
|
||||
"libp2p-peerstore",
|
||||
"libp2p-transport",
|
||||
"libp2p-tcp-transport",
|
||||
]
|
||||
|
9
libp2p-peerstore/Cargo.toml
Normal file
9
libp2p-peerstore/Cargo.toml
Normal file
@@ -0,0 +1,9 @@
|
||||
[package]
|
||||
name = "libp2p-peerstore"
|
||||
version = "0.1.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
|
||||
[dependencies]
|
||||
error-chain = "0.11"
|
||||
multiaddr = "0.2"
|
||||
libp2p-peer = { path = "../libp2p-peer" }
|
6
libp2p-peerstore/src/lib.rs
Normal file
6
libp2p-peerstore/src/lib.rs
Normal file
@@ -0,0 +1,6 @@
|
||||
#[macro_use] extern crate error_chain;
|
||||
extern crate multiaddr;
|
||||
extern crate libp2p_peer as peer;
|
||||
|
||||
mod memory_peerstore;
|
||||
mod peerstore;
|
126
libp2p-peerstore/src/memory_peerstore.rs
Normal file
126
libp2p-peerstore/src/memory_peerstore.rs
Normal file
@@ -0,0 +1,126 @@
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::collections::hash_map;
|
||||
use multiaddr::Multiaddr;
|
||||
use peer::PeerId;
|
||||
use peerstore::*;
|
||||
|
||||
pub struct MemoryPeerstore<T> {
|
||||
store: HashMap<PeerId, PeerInfo<T>>,
|
||||
}
|
||||
|
||||
impl<T> MemoryPeerstore<T> {
|
||||
pub fn new() -> MemoryPeerstore<T> {
|
||||
MemoryPeerstore {
|
||||
store: HashMap::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Peerstore<T> for MemoryPeerstore<T> {
|
||||
/// Returns a list of peers in this Peerstore
|
||||
fn peers(&self) -> Vec<&PeerId> {
|
||||
// this is terrible but I honestly can't think of any other way than to hand off ownership
|
||||
// through this type of allocation or handing off the entire hashmap and letting people do what they
|
||||
// want with that
|
||||
self.store.keys().collect()
|
||||
}
|
||||
/// Returns the PeerInfo for a specific peer in this peer store, or None if it doesn't exist.
|
||||
fn peer_info(&self, peer_id: &PeerId) -> Option<&PeerInfo<T>> {
|
||||
self.store.get(peer_id)
|
||||
}
|
||||
|
||||
/// Try to get a property for a given peer
|
||||
fn get_data(&self, peer_id: &PeerId, key: &str) -> Option<&T> {
|
||||
match self.store.get(peer_id) {
|
||||
None => None,
|
||||
Some(peer_info) => peer_info.get_data(key),
|
||||
}
|
||||
}
|
||||
/// Try to set a property for a given peer
|
||||
fn put_data(&mut self, peer_id: &PeerId, key: String, val: T) -> Result<()> {
|
||||
match self.store.get_mut(peer_id) {
|
||||
None => Err(Error::from_kind(ErrorKind::NoSuchPeer((*peer_id).clone()))),
|
||||
Some(mut peer_info) => {
|
||||
peer_info.set_data(key, val);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Adds an address to a peer
|
||||
fn add_addr(&mut self, peer_id: &PeerId, addr: Multiaddr, ttl: TTL) {
|
||||
match self.store.get_mut(peer_id) {
|
||||
None => (),
|
||||
Some(peer_info) => peer_info.add_addr(addr),
|
||||
}
|
||||
}
|
||||
|
||||
// AddAddrs gives AddrManager addresses to use, with a given ttl
|
||||
// (time-to-live), after which the address is no longer valid.
|
||||
// If the manager has a longer TTL, the operation is a no-op for that address
|
||||
fn add_addrs(&mut self, peer_id: &PeerId, addrs: Vec<Multiaddr>, ttl: TTL) {
|
||||
match self.store.get_mut(peer_id) {
|
||||
None => (),
|
||||
Some(peer_info) => {
|
||||
for addr in addrs {
|
||||
peer_info.add_addr(addr)
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// SetAddr calls mgr.SetAddrs(p, addr, ttl)
|
||||
fn set_addr(&mut self, peer_id: &PeerId, addr: Multiaddr, ttl: TTL) {
|
||||
self.set_addrs(peer_id, vec![addr], ttl)
|
||||
}
|
||||
|
||||
// SetAddrs sets the ttl on addresses. This clears any TTL there previously.
|
||||
// This is used when we receive the best estimate of the validity of an address.
|
||||
fn set_addrs(&mut self, peer_id: &PeerId, addrs: Vec<Multiaddr>, ttl: TTL) {
|
||||
match self.store.get_mut(peer_id) {
|
||||
None => (),
|
||||
Some(peer_info) => peer_info.set_addrs(addrs),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns all known (and valid) addresses for a given peer
|
||||
fn addrs(&self, peer_id: &PeerId) -> &[Multiaddr] {
|
||||
match self.store.get(peer_id) {
|
||||
None => &[],
|
||||
Some(peer_info) => peer_info.get_addrs(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Removes all previously stored addresses
|
||||
fn clear_addrs(&mut self, peer_id: &PeerId) {
|
||||
match self.store.get_mut(peer_id) {
|
||||
None => (),
|
||||
Some(peer_info) => peer_info.set_addrs(vec![]),
|
||||
}
|
||||
}
|
||||
|
||||
/// Get public key for a peer
|
||||
fn get_pub_key(&self, peer_id: &PeerId) -> Option<&[u8]> {
|
||||
self.store.get(peer_id).map(|peer_info| peer_info.get_public_key())
|
||||
}
|
||||
|
||||
/// Set public key for a peer
|
||||
fn set_pub_key(&mut self, peer_id: &PeerId, key: Vec<u8>) {
|
||||
self.store.get_mut(peer_id).map(|peer_info| peer_info.set_public_key(key));
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use peer::PeerId;
|
||||
use super::{Peerstore, MemoryPeerstore};
|
||||
|
||||
#[test]
|
||||
fn insert_get_and_list() {
|
||||
let peer_id = PeerId::new(vec![1,2,3]);
|
||||
let mut peer_store: MemoryPeerstore<u8> = MemoryPeerstore::new();
|
||||
peer_store.put(&peer_id, "test", 123u8);
|
||||
let got = peer_store.get(&peer_id, "test").expect("should be able to fetch");
|
||||
assert_eq!(*got, 123u8);
|
||||
}
|
||||
}
|
87
libp2p-peerstore/src/peerstore.rs
Normal file
87
libp2p-peerstore/src/peerstore.rs
Normal file
@@ -0,0 +1,87 @@
|
||||
use std::time;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use multiaddr::Multiaddr;
|
||||
use peer::PeerId;
|
||||
|
||||
error_chain! {
|
||||
errors {
|
||||
NoSuchPeer(p: PeerId) {
|
||||
description("tried operating on Peerstore with unknown PeerID")
|
||||
display("invalid PeerId: '{}'", p)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub type TTL = time::Duration;
|
||||
|
||||
pub struct PeerInfo<T> {
|
||||
public_key: Vec<u8>,
|
||||
addrs: Vec<Multiaddr>,
|
||||
data: HashMap<String, T>,
|
||||
}
|
||||
|
||||
impl<T> PeerInfo<T> {
|
||||
pub fn get_public_key(&self) -> &[u8] {
|
||||
&self.public_key
|
||||
}
|
||||
pub fn set_public_key(&mut self, key: Vec<u8>) {
|
||||
self.public_key = key;
|
||||
}
|
||||
pub fn get_addrs(&self) -> &[Multiaddr] {
|
||||
&self.addrs
|
||||
}
|
||||
pub fn set_addrs(&mut self, addrs: Vec<Multiaddr>) {
|
||||
self.addrs = addrs;
|
||||
}
|
||||
pub fn add_addr(&mut self, addr: Multiaddr) {
|
||||
self.addrs.push(addr); // TODO: This is stupid, a more advanced thing using TTLs need to be implemented
|
||||
self.addrs.dedup();
|
||||
}
|
||||
pub fn get_data(&self, key: &str) -> Option<&T> {
|
||||
self.data.get(key)
|
||||
}
|
||||
pub fn set_data(&mut self, key: String, val: T) -> Option<T> {
|
||||
self.data.insert(key, val)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Peerstore<T> {
|
||||
/// Returns a list of peers in this Peerstore
|
||||
fn peers(&self) -> Vec<&PeerId>;
|
||||
|
||||
/// Returns the PeerInfo for a specific peer in this peer store, or None if it doesn't exist.
|
||||
fn peer_info(&self, peer_id: &PeerId) -> Option<&PeerInfo<T>>;
|
||||
|
||||
/// Try to get a property for a given peer
|
||||
fn get_data(&self, peer_id: &PeerId, key: &str) -> Option<&T>;
|
||||
|
||||
/// Try to set a property for a given peer
|
||||
fn put_data(&mut self, peer_id: &PeerId, key: String, val: T) -> Result<()>;
|
||||
|
||||
/// Adds an address to a peer
|
||||
fn add_addr(&mut self, peer_id: &PeerId, addr: Multiaddr, ttl: TTL);
|
||||
|
||||
// AddAddrs gives AddrManager addresses to use, with a given ttl
|
||||
// (time-to-live), after which the address is no longer valid.
|
||||
// If the manager has a longer TTL, the operation is a no-op for that address
|
||||
fn add_addrs(&mut self, peer_id: &PeerId, addrs: Vec<Multiaddr>, ttl: TTL);
|
||||
|
||||
// SetAddr calls mgr.SetAddrs(p, addr, ttl)
|
||||
fn set_addr(&mut self, peer_id: &PeerId, addr: Multiaddr, ttl: TTL);
|
||||
|
||||
// SetAddrs sets the ttl on addresses. This clears any TTL there previously.
|
||||
// This is used when we receive the best estimate of the validity of an address.
|
||||
fn set_addrs(&mut self, peer_id: &PeerId, addrs: Vec<Multiaddr>, ttl: TTL);
|
||||
|
||||
/// Returns all known (and valid) addresses for a given peer
|
||||
fn addrs(&self, peer_id: &PeerId) -> &[Multiaddr];
|
||||
|
||||
/// Removes all previously stored addresses
|
||||
fn clear_addrs(&mut self, peer_id: &PeerId);
|
||||
|
||||
/// Get public key for a peer
|
||||
fn get_pub_key(&self, peer_id: &PeerId) -> Option<&[u8]>;
|
||||
|
||||
/// Set public key for a peer
|
||||
fn set_pub_key(&mut self, peer_id: &PeerId, key: Vec<u8>);
|
||||
}
|
Reference in New Issue
Block a user