-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: switch to use peer_id for send and recv (#5)
- Loading branch information
Showing
18 changed files
with
576 additions
and
418 deletions.
There are no files selected for viewing
This file contains 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 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 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 |
---|---|---|
|
@@ -2,27 +2,29 @@ use std::collections::BTreeMap; | |
|
||
use serde::{Deserialize, Serialize}; | ||
|
||
use super::PeerAddress; | ||
use crate::{NetworkAddress, PeerAddress}; | ||
|
||
use super::PeerId; | ||
|
||
const TIMEOUT_AFTER: u64 = 30_000; | ||
|
||
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] | ||
pub struct PeerDiscoverySync(Vec<(PeerAddress, u64)>); | ||
pub struct PeerDiscoverySync(Vec<(PeerId, u64, NetworkAddress)>); | ||
|
||
#[derive(Debug, Default)] | ||
pub struct PeerDiscovery { | ||
local: Option<PeerAddress>, | ||
remotes: BTreeMap<PeerAddress, u64>, | ||
local: Option<(PeerId, NetworkAddress)>, | ||
remotes: BTreeMap<PeerId, (u64, NetworkAddress)>, | ||
} | ||
|
||
impl PeerDiscovery { | ||
pub fn enable_local(&mut self, local: PeerAddress) { | ||
log::info!("[PeerDiscovery] enable local as {local}"); | ||
self.local = Some(local); | ||
pub fn enable_local(&mut self, peer_id: PeerId, address: NetworkAddress) { | ||
log::info!("[PeerDiscovery] enable local as {address}"); | ||
self.local = Some((peer_id, address)); | ||
} | ||
|
||
pub fn clear_timeout(&mut self, now_ms: u64) { | ||
self.remotes.retain(|peer, last_updated| { | ||
self.remotes.retain(|peer, (last_updated, _addr)| { | ||
if *last_updated + TIMEOUT_AFTER > now_ms { | ||
true | ||
} else { | ||
|
@@ -32,76 +34,82 @@ impl PeerDiscovery { | |
}); | ||
} | ||
|
||
pub fn create_sync_for(&self, now_ms: u64, dest: &PeerAddress) -> PeerDiscoverySync { | ||
let iter = self.local.iter().map(|p| (*p, now_ms)); | ||
PeerDiscoverySync(self.remotes.iter().filter(|(k, _)| !dest.eq(k)).map(|(k, v)| (*k, *v)).chain(iter).collect::<Vec<_>>()) | ||
pub fn create_sync_for(&self, now_ms: u64, dest: &PeerId) -> PeerDiscoverySync { | ||
let iter = self.local.iter().map(|(p, addr)| (*p, now_ms, addr.clone())); | ||
PeerDiscoverySync( | ||
self.remotes | ||
.iter() | ||
.filter(|(k, _)| !dest.eq(k)) | ||
.map(|(k, (v1, v2))| (*k, *v1, v2.clone())) | ||
.chain(iter) | ||
.collect::<Vec<_>>(), | ||
) | ||
} | ||
|
||
pub fn apply_sync(&mut self, now_ms: u64, sync: PeerDiscoverySync) { | ||
log::debug!("[PeerDiscovery] apply sync with addrs: {:?}", sync.0); | ||
for (peer, last_updated) in sync.0.into_iter() { | ||
for (peer, last_updated, address) in sync.0.into_iter() { | ||
if last_updated + TIMEOUT_AFTER > now_ms { | ||
if self.remotes.insert(peer, last_updated).is_none() { | ||
if self.remotes.insert(peer, (last_updated, address)).is_none() { | ||
log::info!("[PeerDiscovery] added new peer {peer}"); | ||
} | ||
} | ||
} | ||
} | ||
|
||
pub fn remotes(&self) -> impl Iterator<Item = &PeerAddress> { | ||
self.remotes.keys().into_iter() | ||
pub fn remotes(&self) -> impl Iterator<Item = PeerAddress> + '_ { | ||
self.remotes.iter().map(|(p, (_, a))| PeerAddress(*p, a.clone())) | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod test { | ||
use std::net::{IpAddr, Ipv4Addr, SocketAddr}; | ||
|
||
use crate::{discovery::PeerDiscoverySync, PeerAddress}; | ||
use crate::{discovery::PeerDiscoverySync, PeerAddress, PeerId}; | ||
|
||
use super::{PeerDiscovery, TIMEOUT_AFTER}; | ||
|
||
fn create_peer(i: u16) -> PeerAddress { | ||
SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), i).into() | ||
} | ||
|
||
#[test_log::test] | ||
fn create_local_sync() { | ||
let mut discovery = PeerDiscovery::default(); | ||
|
||
let peer1 = create_peer(1); | ||
let peer2 = create_peer(1); | ||
let peer1 = PeerId(1); | ||
let peer1_addr: PeerAddress = "[email protected]:9000".parse().expect("should parse peer address"); | ||
|
||
let peer2 = PeerId(2); | ||
|
||
assert_eq!(discovery.create_sync_for(0, &peer2), PeerDiscoverySync(vec![])); | ||
|
||
discovery.enable_local(peer1); | ||
discovery.enable_local(peer1, peer1_addr.network_address().clone()); | ||
|
||
assert_eq!(discovery.create_sync_for(100, &peer2), PeerDiscoverySync(vec![(peer1, 100)])); | ||
assert_eq!(discovery.create_sync_for(100, &peer2), PeerDiscoverySync(vec![(peer1, 100, peer1_addr.network_address().clone())])); | ||
assert_eq!(discovery.remotes().next(), None); | ||
} | ||
|
||
#[test_log::test] | ||
fn apply_sync() { | ||
let mut discovery = PeerDiscovery::default(); | ||
|
||
let peer1 = create_peer(1); | ||
let peer2 = create_peer(2); | ||
let peer1 = PeerId(1); | ||
let peer1_addr: PeerAddress = "[email protected]:9000".parse().expect("should parse peer address"); | ||
|
||
discovery.apply_sync(100, PeerDiscoverySync(vec![(peer1, 90)])); | ||
let peer2 = PeerId(2); | ||
|
||
assert_eq!(discovery.create_sync_for(100, &peer2), PeerDiscoverySync(vec![(peer1, 90)])); | ||
discovery.apply_sync(100, PeerDiscoverySync(vec![(peer1, 90, peer1_addr.network_address().clone())])); | ||
|
||
assert_eq!(discovery.create_sync_for(100, &peer2), PeerDiscoverySync(vec![(peer1, 90, peer1_addr.network_address().clone())])); | ||
assert_eq!(discovery.create_sync_for(100, &peer1), PeerDiscoverySync(vec![])); | ||
assert_eq!(discovery.remotes().collect::<Vec<_>>(), vec![&peer1]); | ||
assert_eq!(discovery.remotes().collect::<Vec<_>>(), vec![peer1_addr]); | ||
} | ||
|
||
#[test_log::test] | ||
fn apply_sync_timeout() { | ||
let mut discovery = PeerDiscovery::default(); | ||
|
||
let peer1 = create_peer(1); | ||
let peer2 = create_peer(2); | ||
let peer1 = PeerId(1); | ||
let peer1_addr: PeerAddress = "[email protected]:9000".parse().expect("should parse peer address"); | ||
|
||
let peer2 = PeerId(2); | ||
|
||
discovery.apply_sync(TIMEOUT_AFTER + 100, PeerDiscoverySync(vec![(peer1, 100)])); | ||
discovery.apply_sync(TIMEOUT_AFTER + 100, PeerDiscoverySync(vec![(peer1, 100, peer1_addr.network_address().clone())])); | ||
|
||
assert_eq!(discovery.create_sync_for(100, &peer2), PeerDiscoverySync(vec![])); | ||
assert_eq!(discovery.create_sync_for(100, &peer1), PeerDiscoverySync(vec![])); | ||
|
@@ -112,11 +120,12 @@ mod test { | |
fn clear_timeout() { | ||
let mut discovery = PeerDiscovery::default(); | ||
|
||
let peer1 = create_peer(1); | ||
let peer1 = PeerId(1); | ||
let peer1_addr: PeerAddress = "[email protected]:9000".parse().expect("should parse peer address"); | ||
|
||
discovery.apply_sync(100, PeerDiscoverySync(vec![(peer1, 90)])); | ||
discovery.apply_sync(100, PeerDiscoverySync(vec![(peer1, 90, peer1_addr.network_address().clone())])); | ||
|
||
assert_eq!(discovery.remotes().collect::<Vec<_>>(), vec![&peer1]); | ||
assert_eq!(discovery.remotes().collect::<Vec<_>>(), vec![peer1_addr]); | ||
|
||
discovery.clear_timeout(TIMEOUT_AFTER + 90); | ||
|
||
|
Oops, something went wrong.