penalize for unknown headers
This commit is contained in:
parent
b69ef3eada
commit
746dcf503a
|
@ -280,7 +280,20 @@ impl<T> ClientCore for SynchronizationClientCore<T> where T: TaskExecutor {
|
|||
// => all headers are also unknown to us
|
||||
let header0 = headers[0].clone();
|
||||
if self.chain.block_state(&header0.raw.previous_header_hash) == BlockState::Unknown {
|
||||
warn!(target: "sync", "Previous header of the first header from peer#{} `headers` message is unknown. First: {}. Previous: {}", peer_index, header0.hash.to_reversed_str(), header0.raw.previous_header_hash.to_reversed_str());
|
||||
warn!(
|
||||
target: "sync",
|
||||
"Previous header of the first header from peer#{} `headers` message is unknown. First: {}. Previous: {}",
|
||||
peer_index,
|
||||
header0.hash.to_reversed_str(),
|
||||
header0.raw.previous_header_hash.to_reversed_str(),
|
||||
);
|
||||
|
||||
// there could be competing chains that are running the network with the same magic (like Zcash vs ZelCash)
|
||||
// => providing unknown headers. Penalize node so that it'll disconnect
|
||||
if self.peers_tasks.penalize(peer_index) {
|
||||
self.peers.misbehaving(peer_index, "Too many failures.");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -316,7 +316,7 @@ mod tests {
|
|||
use std::collections::HashSet;
|
||||
use primitives::hash::H256;
|
||||
use synchronization_peers::PeersImpl;
|
||||
use synchronization_peers_tasks::PeersTasks;
|
||||
use synchronization_peers_tasks::{PeersTasks, TrustLevel};
|
||||
use super::{ManagePeersConfig, ManageUnknownBlocksConfig, ManageOrphanTransactionsConfig, manage_synchronization_peers_blocks,
|
||||
manage_unknown_orphaned_blocks, manage_orphaned_transactions};
|
||||
use utils::{OrphanBlocksPool, OrphanTransactionsPool};
|
||||
|
@ -335,10 +335,12 @@ mod tests {
|
|||
fn manage_bad_peers() {
|
||||
use std::thread::sleep;
|
||||
use std::time::Duration;
|
||||
let config = ManagePeersConfig { new_block_failure_interval_ms: 0, ..Default::default() };
|
||||
let config = ManagePeersConfig { trusted_block_failure_interval_ms: 0, ..Default::default() };
|
||||
let mut peers = PeersTasks::default();
|
||||
peers.on_blocks_requested(1, &vec![H256::from(0)]);
|
||||
peers.on_blocks_requested(2, &vec![H256::from(1)]);
|
||||
peers.get_peer_stats_mut(1).unwrap().set_trust(TrustLevel::Trusted);
|
||||
peers.get_peer_stats_mut(2).unwrap().set_trust(TrustLevel::Trusted);
|
||||
sleep(Duration::from_millis(1));
|
||||
|
||||
let managed_tasks = manage_synchronization_peers_blocks(&config, Arc::new(PeersImpl::default()), &mut peers).0;
|
||||
|
|
|
@ -154,6 +154,12 @@ impl PeersTasks {
|
|||
self.stats.get(&peer_index)
|
||||
}
|
||||
|
||||
/// Get mutable reference to peer statistics
|
||||
#[cfg(test)]
|
||||
pub fn get_peer_stats_mut(&mut self, peer_index: PeerIndex) -> Option<&mut PeerStats> {
|
||||
self.stats.get_mut(&peer_index)
|
||||
}
|
||||
|
||||
/// Mark peer as useful.
|
||||
pub fn useful_peer(&mut self, peer_index: PeerIndex) {
|
||||
// if peer is unknown => insert to idle queue
|
||||
|
@ -304,12 +310,7 @@ impl PeersTasks {
|
|||
|
||||
/// We have failed to get block from peer during given period
|
||||
pub fn on_peer_block_failure(&mut self, peer_index: PeerIndex) -> bool {
|
||||
self.stats.get_mut(&peer_index)
|
||||
.map(|s| {
|
||||
s.failures += 1;
|
||||
s.failures > MAX_PEER_FAILURES
|
||||
})
|
||||
.unwrap_or_default()
|
||||
self.penalize(peer_index)
|
||||
}
|
||||
|
||||
/// We have failed to get headers from peer during given period
|
||||
|
@ -318,10 +319,20 @@ impl PeersTasks {
|
|||
self.headers_requests.remove(&peer_index);
|
||||
self.idle_for_headers.insert(peer_index);
|
||||
|
||||
self.penalize(peer_index)
|
||||
}
|
||||
|
||||
/// Penalize peer. Returns true if the peer score is too low to keep connection.
|
||||
pub fn penalize(&mut self, peer_index: PeerIndex) -> bool {
|
||||
self.stats.get_mut(&peer_index)
|
||||
.map(|s| {
|
||||
s.failures += 1;
|
||||
s.failures > MAX_PEER_FAILURES
|
||||
if s.trust == TrustLevel::Trusted {
|
||||
s.failures += 1;
|
||||
s.failures > MAX_PEER_FAILURES
|
||||
} else {
|
||||
s.failures = MAX_PEER_FAILURES;
|
||||
true
|
||||
}
|
||||
})
|
||||
.unwrap_or_default()
|
||||
}
|
||||
|
@ -374,6 +385,11 @@ impl PeerStats {
|
|||
pub fn trust(&self) -> TrustLevel {
|
||||
self.trust
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub fn set_trust(&mut self, trust: TrustLevel) {
|
||||
self.trust = trust;
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for Information {
|
||||
|
|
Loading…
Reference in New Issue