mirror of
https://github.com/mimblewimble/grin.git
synced 2025-02-08 12:21:09 +03:00
Peer is_known robustness (#3040)
* add some test coverage around peers map (peer_addr hashing impl) * make is_known a bit more robust * fix typos
This commit is contained in:
parent
95004a4b96
commit
28d5ee8242
3 changed files with 30 additions and 14 deletions
|
@ -97,15 +97,19 @@ impl Peers {
|
||||||
self.save_peer(&peer_data)
|
self.save_peer(&peer_data)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_known(&self, addr: PeerAddr) -> bool {
|
/// Check if this peer address is already known (are we already connected to it)?
|
||||||
|
/// We try to get the read lock but if we experience contention
|
||||||
|
/// and this attempt fails then return an error allowing the caller
|
||||||
|
/// to decide how best to handle this.
|
||||||
|
pub fn is_known(&self, addr: PeerAddr) -> Result<bool, Error> {
|
||||||
let peers = match self.peers.try_read_for(LOCK_TIMEOUT) {
|
let peers = match self.peers.try_read_for(LOCK_TIMEOUT) {
|
||||||
Some(peers) => peers,
|
Some(peers) => peers,
|
||||||
None => {
|
None => {
|
||||||
error!("is_known: failed to get peers lock");
|
error!("is_known: failed to get peers lock");
|
||||||
return false;
|
return Err(Error::Internal);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
peers.contains_key(&addr)
|
Ok(peers.contains_key(&addr))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get vec of peers we are currently connected to.
|
/// Get vec of peers we are currently connected to.
|
||||||
|
|
|
@ -224,10 +224,22 @@ impl Server {
|
||||||
debug!("Peer {} banned, refusing connection.", peer_addr);
|
debug!("Peer {} banned, refusing connection.", peer_addr);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if self.peers.is_known(peer_addr) {
|
// The call to is_known() can fail due to contention on the peers map.
|
||||||
|
// If it fails we want to default to refusing the connection.
|
||||||
|
match self.peers.is_known(peer_addr) {
|
||||||
|
Ok(true) => {
|
||||||
debug!("Peer {} already known, refusing connection.", peer_addr);
|
debug!("Peer {} already known, refusing connection.", peer_addr);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
Err(_) => {
|
||||||
|
error!(
|
||||||
|
"Peer {} is_known check failed, refusing connection.",
|
||||||
|
peer_addr
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
|
@ -239,15 +239,15 @@ fn monitor_peers(
|
||||||
max_peer_attempts as usize,
|
max_peer_attempts as usize,
|
||||||
);
|
);
|
||||||
|
|
||||||
for p in new_peers.iter().filter(|p| !peers.is_known(p.addr)) {
|
// Only queue up connection attempts for candidate peers where we
|
||||||
trace!(
|
// are confident we do not yet know about this peer.
|
||||||
"monitor_peers: on {}:{}, queue to soon try {}",
|
// The call to is_known() may fail due to contention on the peers map.
|
||||||
config.host,
|
// Do not attempt any connection where is_known() fails for any reason.
|
||||||
config.port,
|
for p in new_peers {
|
||||||
p.addr,
|
if let Ok(false) = peers.is_known(p.addr) {
|
||||||
);
|
|
||||||
tx.send(p.addr).unwrap();
|
tx.send(p.addr).unwrap();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if we have any pre-existing peer in db. If so, start with those,
|
// Check if we have any pre-existing peer in db. If so, start with those,
|
||||||
|
|
Loading…
Reference in a new issue