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
|
/// a 30x Cuckoo adjustment factor
|
||||||
pub const TESTNET3_INITIAL_DIFFICULTY: u64 = 30000;
|
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
|
/// Testnet 4 initial block difficulty
|
||||||
/// 1_000 times natural scale factor for cuckatoo29
|
/// 1_000 times natural scale factor for cuckatoo29
|
||||||
pub const TESTNET4_INITIAL_DIFFICULTY: u64 = 1_000 * (2<<(29-24)) * 29;
|
pub const TESTNET4_INITIAL_DIFFICULTY: u64 = 1_000 * (2<<(29-24)) * 29;
|
||||||
|
|
|
@ -102,6 +102,7 @@ impl Handshake {
|
||||||
total_difficulty: shake.total_difficulty,
|
total_difficulty: shake.total_difficulty,
|
||||||
height: 0,
|
height: 0,
|
||||||
last_seen: Utc::now(),
|
last_seen: Utc::now(),
|
||||||
|
stuck_detector: Utc::now(),
|
||||||
})),
|
})),
|
||||||
direction: Direction::Outbound,
|
direction: Direction::Outbound,
|
||||||
};
|
};
|
||||||
|
@ -161,6 +162,7 @@ impl Handshake {
|
||||||
total_difficulty: hand.total_difficulty,
|
total_difficulty: hand.total_difficulty,
|
||||||
height: 0,
|
height: 0,
|
||||||
last_seen: Utc::now(),
|
last_seen: Utc::now(),
|
||||||
|
stuck_detector: Utc::now(),
|
||||||
})),
|
})),
|
||||||
direction: Direction::Inbound,
|
direction: Direction::Inbound,
|
||||||
};
|
};
|
||||||
|
|
|
@ -18,9 +18,9 @@ use std::sync::{Arc, RwLock};
|
||||||
|
|
||||||
use chrono::prelude::{DateTime, Utc};
|
use chrono::prelude::{DateTime, Utc};
|
||||||
use conn;
|
use conn;
|
||||||
use core::core;
|
|
||||||
use core::core::hash::{Hash, Hashed};
|
use core::core::hash::{Hash, Hashed};
|
||||||
use core::pow::Difficulty;
|
use core::pow::Difficulty;
|
||||||
|
use core::{core, global};
|
||||||
use handshake::Handshake;
|
use handshake::Handshake;
|
||||||
use msg::{self, BanReason, GetPeerAddrs, Locator, Ping, TxHashSetRequest};
|
use msg::{self, BanReason, GetPeerAddrs, Locator, Ping, TxHashSetRequest};
|
||||||
use protocol::Protocol;
|
use protocol::Protocol;
|
||||||
|
@ -140,6 +140,18 @@ impl Peer {
|
||||||
State::Banned == *self.state.read().unwrap()
|
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
|
/// Set this peer status to banned
|
||||||
pub fn set_banned(&self) {
|
pub fn set_banned(&self) {
|
||||||
*self.state.write().unwrap() = State::Banned;
|
*self.state.write().unwrap() = State::Banned;
|
||||||
|
|
|
@ -424,6 +424,14 @@ impl Peers {
|
||||||
} else if !peer.is_connected() {
|
} else if !peer.is_connected() {
|
||||||
debug!(LOGGER, "clean_peers {:?}, not connected", peer.info.addr);
|
debug!(LOGGER, "clean_peers {:?}, not connected", peer.info.addr);
|
||||||
rm.push(peer.clone());
|
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 total_difficulty: Difficulty,
|
||||||
pub height: u64,
|
pub height: u64,
|
||||||
pub last_seen: DateTime<Utc>,
|
pub last_seen: DateTime<Utc>,
|
||||||
|
pub stuck_detector: DateTime<Utc>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// General information about a connected peer that's useful to other modules.
|
/// 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.
|
/// Takes a write lock on the live_info.
|
||||||
pub fn update(&self, height: u64, total_difficulty: Difficulty) {
|
pub fn update(&self, height: u64, total_difficulty: Difficulty) {
|
||||||
let mut live_info = self.live_info.write().unwrap();
|
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.height = height;
|
||||||
live_info.total_difficulty = total_difficulty;
|
live_info.total_difficulty = total_difficulty;
|
||||||
live_info.last_seen = Utc::now()
|
live_info.last_seen = Utc::now()
|
||||||
|
|
Loading…
Reference in a new issue