Use socket addr instead of Ip for the address book

This commit is contained in:
Dr Maxim Orlovsky 2022-11-29 17:03:21 +01:00 committed by Alexis Sellier
parent c597b6989e
commit da55e521a1
No known key found for this signature in database
3 changed files with 29 additions and 31 deletions

View File

@ -9,7 +9,7 @@ use std::collections::hash_map::Entry;
use std::collections::{BTreeMap, HashMap, HashSet}; use std::collections::{BTreeMap, HashMap, HashSet};
use std::ops::{Deref, DerefMut}; use std::ops::{Deref, DerefMut};
use std::sync::Arc; use std::sync::Arc;
use std::{fmt, net, net::IpAddr, str}; use std::{fmt, net, str};
use crossbeam_channel as chan; use crossbeam_channel as chan;
use fastrand::Rng; use fastrand::Rng;
@ -489,13 +489,12 @@ where
} }
} }
pub fn attempted(&mut self, addr: &std::net::SocketAddr) { pub fn attempted(&mut self, addr: &net::SocketAddr) {
let address = Address::from(*addr); let address = Address::from(*addr);
let ip = addr.ip();
let persistent = self.config.is_persistent(&address); let persistent = self.config.is_persistent(&address);
let peer = self let peer = self
.sessions .sessions
.entry(ip) .entry(*addr)
.or_insert_with(|| Session::new(*addr, Link::Outbound, persistent, self.rng.clone())); .or_insert_with(|| Session::new(*addr, Link::Outbound, persistent, self.rng.clone()));
peer.attempted(); peer.attempted();
@ -510,16 +509,15 @@ where
} }
pub fn connected(&mut self, addr: net::SocketAddr, link: Link) { pub fn connected(&mut self, addr: net::SocketAddr, link: Link) {
let ip = addr.ip();
let address = addr.into(); let address = addr.into();
debug!("Connected to {} ({:?})", ip, link); debug!("Connected to {} ({:?})", addr, link);
// For outbound connections, we are the first to say "Hello". // For outbound connections, we are the first to say "Hello".
// For inbound connections, we wait for the remote to say "Hello" first. // For inbound connections, we wait for the remote to say "Hello" first.
// TODO: How should we deal with multiple peers connecting from the same IP address? // TODO: How should we deal with multiple peers connecting from the same IP address?
if link.is_outbound() { if link.is_outbound() {
if let Some(peer) = self.sessions.get_mut(&ip) { if let Some(peer) = self.sessions.get_mut(&addr) {
if link.is_outbound() { if link.is_outbound() {
self.reactor.write_all( self.reactor.write_all(
addr, addr,
@ -535,7 +533,7 @@ where
} }
} else { } else {
self.sessions.insert( self.sessions.insert(
ip, addr,
Session::new( Session::new(
addr, addr,
Link::Inbound, Link::Inbound,
@ -548,16 +546,15 @@ where
pub fn disconnected( pub fn disconnected(
&mut self, &mut self,
addr: &std::net::SocketAddr, addr: &net::SocketAddr,
reason: &nakamoto::DisconnectReason<DisconnectReason>, reason: &nakamoto::DisconnectReason<DisconnectReason>,
) { ) {
let since = self.local_time(); let since = self.local_time();
let address = Address::from(*addr); let address = Address::from(*addr);
let ip = addr.ip();
debug!("Disconnected from {} ({})", ip, reason); debug!("Disconnected from {} ({})", addr, reason);
if let Some(session) = self.sessions.get_mut(&ip) { if let Some(session) = self.sessions.get_mut(addr) {
session.state = session::State::Disconnected { since }; session.state = session::State::Disconnected { since };
// Attempt to re-connect to persistent peers. // Attempt to re-connect to persistent peers.
@ -574,7 +571,7 @@ where
// with exponential back-off. // with exponential back-off.
debug!( debug!(
"Reconnecting to {} (attempts={})...", "Reconnecting to {} (attempts={})...",
ip, addr,
session.attempts() session.attempts()
); );
@ -583,7 +580,7 @@ where
self.reactor.connect(*addr); self.reactor.connect(*addr);
} else { } else {
self.sessions.remove(&ip); self.sessions.remove(addr);
self.maintain_connections(); self.maintain_connections();
} }
} }
@ -769,9 +766,8 @@ where
remote: &net::SocketAddr, remote: &net::SocketAddr,
message: Message, message: Message,
) -> Result<(), session::Error> { ) -> Result<(), session::Error> {
let peer_ip = remote.ip(); let Some(peer) = self.sessions.get_mut(remote) else {
let Some(peer) = self.sessions.get_mut(&peer_ip) else { return Err(session::Error::NotFound(*remote));
return Err(session::Error::NotFound(remote.ip()));
}; };
peer.last_active = self.clock.local_time(); peer.last_active = self.clock.local_time();
@ -826,7 +822,7 @@ where
let relay_to = self let relay_to = self
.sessions .sessions
.negotiated() .negotiated()
.filter(|(ip, _, _)| **ip != remote.ip()) .filter(|(addr, _, _)| *addr != remote)
.filter(|(_, id, _)| **id != ann.node); .filter(|(_, id, _)| **id != ann.node);
self.reactor.relay(ann.clone(), relay_to.map(|(_, _, p)| p)); self.reactor.relay(ann.clone(), relay_to.map(|(_, _, p)| p));
@ -1182,7 +1178,7 @@ impl Node {
#[derive(Debug)] #[derive(Debug)]
/// Holds currently (or recently) connected peers. /// Holds currently (or recently) connected peers.
pub struct Sessions(AddressBook<IpAddr, Session>); pub struct Sessions(AddressBook<net::SocketAddr, Session>);
impl Sessions { impl Sessions {
pub fn new(rng: Rng) -> Self { pub fn new(rng: Rng) -> Self {
@ -1194,23 +1190,25 @@ impl Sessions {
} }
/// Iterator over fully negotiated peers. /// Iterator over fully negotiated peers.
pub fn negotiated(&self) -> impl Iterator<Item = (&IpAddr, &NodeId, &Session)> + Clone { pub fn negotiated(
&self,
) -> impl Iterator<Item = (&net::SocketAddr, &NodeId, &Session)> + Clone {
self.0 self.0
.iter() .iter()
.filter_map(move |(ip, sess)| match &sess.state { .filter_map(move |(addr, sess)| match &sess.state {
session::State::Negotiated { id, .. } => Some((ip, id, sess)), session::State::Negotiated { id, .. } => Some((addr, id, sess)),
_ => None, _ => None,
}) })
} }
/// Iterator over mutable fully negotiated peers. /// Iterator over mutable fully negotiated peers.
pub fn negotiated_mut(&mut self) -> impl Iterator<Item = (&IpAddr, &mut Session)> { pub fn negotiated_mut(&mut self) -> impl Iterator<Item = (&net::SocketAddr, &mut Session)> {
self.0.iter_mut().filter(move |(_, p)| p.is_negotiated()) self.0.iter_mut().filter(move |(_, p)| p.is_negotiated())
} }
} }
impl Deref for Sessions { impl Deref for Sessions {
type Target = AddressBook<IpAddr, Session>; type Target = AddressBook<net::SocketAddr, Session>;
fn deref(&self) -> &Self::Target { fn deref(&self) -> &Self::Target {
&self.0 &self.0

View File

@ -44,7 +44,7 @@ pub enum Error {
#[error("invalid announcement timestamp: {0}")] #[error("invalid announcement timestamp: {0}")]
InvalidTimestamp(u64), InvalidTimestamp(u64),
#[error("session not found for address `{0}`")] #[error("session not found for address `{0}`")]
NotFound(net::IpAddr), NotFound(net::SocketAddr),
#[error("verification failed on fetch: {0}")] #[error("verification failed on fetch: {0}")]
VerificationFailed(#[from] storage::VerifyError), VerificationFailed(#[from] storage::VerifyError),
#[error("peer misbehaved")] #[error("peer misbehaved")]

View File

@ -133,8 +133,8 @@ fn test_outbound_connection() {
.map(|(ip, _, _)| *ip) .map(|(ip, _, _)| *ip)
.collect::<Vec<_>>(); .collect::<Vec<_>>();
assert!(peers.contains(&eve.ip)); assert!(peers.contains(&eve.addr()));
assert!(peers.contains(&bob.ip)); assert!(peers.contains(&bob.addr()));
} }
#[test] #[test]
@ -153,8 +153,8 @@ fn test_inbound_connection() {
.map(|(ip, _, _)| *ip) .map(|(ip, _, _)| *ip)
.collect::<Vec<_>>(); .collect::<Vec<_>>();
assert!(peers.contains(&eve.ip)); assert!(peers.contains(&eve.addr()));
assert!(peers.contains(&bob.ip)); assert!(peers.contains(&bob.addr()));
} }
#[test] #[test]
@ -719,8 +719,8 @@ fn test_persistent_peer_reconnect() {
.negotiated() .negotiated()
.map(|(ip, _, _)| *ip) .map(|(ip, _, _)| *ip)
.collect::<Vec<_>>(); .collect::<Vec<_>>();
assert!(ips.contains(&bob.ip)); assert!(ips.contains(&bob.addr()));
assert!(ips.contains(&eve.ip)); assert!(ips.contains(&eve.addr()));
// ... Negotiated ... // ... Negotiated ...
// //