mirror of
https://github.com/mimblewimble/grin.git
synced 2025-01-21 03:21:08 +03:00
kick stuck peer out of connected peers. (#1782)
* cherry-picking commit 7754adb8
from master for #1746
This commit is contained in:
parent
d65a9adb59
commit
53b10a083c
5 changed files with 31 additions and 1 deletions
|
@ -66,6 +66,10 @@ pub const TESTNET2_INITIAL_DIFFICULTY: u64 = 1000;
|
|||
/// a 30x Cuckoo adjustment factor
|
||||
pub const TESTNET3_INITIAL_DIFFICULTY: u64 = 30000;
|
||||
|
||||
/// If a peer's last updated difficulty is 2 hours ago and its difficulty's lower than ours,
|
||||
/// we're sure this peer is a stuck node, and we will kick out such kind of stuck peers.
|
||||
pub const STUCK_PEER_KICK_TIME: i64 = 2 * 3600 * 1000;
|
||||
|
||||
/// Testnet 4 initial block difficulty
|
||||
/// 1_000 times natural scale factor for cuckatoo29
|
||||
pub const TESTNET4_INITIAL_DIFFICULTY: u64 = 1_000 * (2<<(29-24)) * 29;
|
||||
|
|
|
@ -102,6 +102,7 @@ impl Handshake {
|
|||
total_difficulty: shake.total_difficulty,
|
||||
height: 0,
|
||||
last_seen: Utc::now(),
|
||||
stuck_detector: Utc::now(),
|
||||
})),
|
||||
direction: Direction::Outbound,
|
||||
};
|
||||
|
@ -161,6 +162,7 @@ impl Handshake {
|
|||
total_difficulty: hand.total_difficulty,
|
||||
height: 0,
|
||||
last_seen: Utc::now(),
|
||||
stuck_detector: Utc::now(),
|
||||
})),
|
||||
direction: Direction::Inbound,
|
||||
};
|
||||
|
|
|
@ -18,9 +18,9 @@ use std::sync::{Arc, RwLock};
|
|||
|
||||
use chrono::prelude::{DateTime, Utc};
|
||||
use conn;
|
||||
use core::core;
|
||||
use core::core::hash::{Hash, Hashed};
|
||||
use core::pow::Difficulty;
|
||||
use core::{core, global};
|
||||
use handshake::Handshake;
|
||||
use msg::{self, BanReason, GetPeerAddrs, Locator, Ping, TxHashSetRequest};
|
||||
use protocol::Protocol;
|
||||
|
@ -140,6 +140,18 @@ impl Peer {
|
|||
State::Banned == *self.state.read().unwrap()
|
||||
}
|
||||
|
||||
/// Whether this peer is stuck on sync.
|
||||
pub fn is_stuck(&self) -> (bool, Difficulty) {
|
||||
let peer_live_info = self.info.live_info.read().unwrap();
|
||||
let now = Utc::now().timestamp_millis();
|
||||
// if last updated difficulty is 2 hours ago, we're sure this peer is a stuck node.
|
||||
if now > peer_live_info.stuck_detector.timestamp_millis() + global::STUCK_PEER_KICK_TIME {
|
||||
(true, peer_live_info.total_difficulty)
|
||||
} else {
|
||||
(false, peer_live_info.total_difficulty)
|
||||
}
|
||||
}
|
||||
|
||||
/// Set this peer status to banned
|
||||
pub fn set_banned(&self) {
|
||||
*self.state.write().unwrap() = State::Banned;
|
||||
|
|
|
@ -424,6 +424,14 @@ impl Peers {
|
|||
} else if !peer.is_connected() {
|
||||
debug!(LOGGER, "clean_peers {:?}, not connected", peer.info.addr);
|
||||
rm.push(peer.clone());
|
||||
} else {
|
||||
let (stuck, diff) = peer.is_stuck();
|
||||
if stuck && diff < self.adapter.total_difficulty() {
|
||||
debug!(LOGGER, "clean_peers {:?}, stuck peer", peer.info.addr);
|
||||
peer.stop();
|
||||
let _ = self.update_state(peer.info.addr, State::Defunct);
|
||||
rm.push(peer.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -241,6 +241,7 @@ pub struct PeerLiveInfo {
|
|||
pub total_difficulty: Difficulty,
|
||||
pub height: u64,
|
||||
pub last_seen: DateTime<Utc>,
|
||||
pub stuck_detector: DateTime<Utc>,
|
||||
}
|
||||
|
||||
/// General information about a connected peer that's useful to other modules.
|
||||
|
@ -274,6 +275,9 @@ impl PeerInfo {
|
|||
/// Takes a write lock on the live_info.
|
||||
pub fn update(&self, height: u64, total_difficulty: Difficulty) {
|
||||
let mut live_info = self.live_info.write().unwrap();
|
||||
if total_difficulty != live_info.total_difficulty {
|
||||
live_info.stuck_detector = Utc::now();
|
||||
}
|
||||
live_info.height = height;
|
||||
live_info.total_difficulty = total_difficulty;
|
||||
live_info.last_seen = Utc::now()
|
||||
|
|
Loading…
Reference in a new issue