fix: Prevent stale nodes from updating chain head (#208)

This commit is contained in:
Maciej Hirsz
2019-12-06 13:30:30 +01:00
committed by GitHub
parent 516fb0376d
commit f2fc89e374
2 changed files with 50 additions and 35 deletions
+30 -22
View File
@@ -71,13 +71,6 @@ impl Chain {
self.aggregator.do_send(NodeCount(self.cid, self.nodes.len()));
}
fn update_average_block_time(&mut self, now: u64) {
if let Some(timestamp) = self.timestamp {
self.block_times.push(now - timestamp);
self.average_block_time = Some(self.block_times.average());
}
}
/// Check if the chain is stale (has not received a new best block in a while).
/// If so, find a new best block, ignoring any stale nodes and marking them as such.
fn update_stale_nodes(&mut self, now: u64) {
@@ -190,29 +183,34 @@ impl Handler<AddNode> for Chain {
}
}
impl Handler<UpdateNode> for Chain {
type Result = ();
impl Chain {
fn handle_block(&mut self, block: &Block, nid: NodeId) {
let mut propagation_time = None;
let now = now();
let nodes_len = self.nodes.len();
fn handle(&mut self, msg: UpdateNode, _: &mut Self::Context) {
let UpdateNode { nid, msg, raw } = msg;
self.update_stale_nodes(now);
if let Some(block) = msg.details.best_block() {
let mut propagation_time = None;
let now = now();
self.update_stale_nodes(now);
let node = match self.nodes.get_mut(nid) {
Some(node) => node,
None => return,
};
if node.update_block(*block) {
if block.height > self.best.height {
self.best = *block;
info!(
"[{}] [{}/{}] new best block ({}) {:?}",
self.label,
self.nodes.len(),
nodes_len,
self.feeds.len(),
self.best.height,
self.best.hash,
);
self.update_average_block_time(now);
if let Some(timestamp) = self.timestamp {
self.block_times.push(now - timestamp);
self.average_block_time = Some(self.block_times.average());
}
self.timestamp = Some(now);
self.serializer.push(feed::BestBlock(self.best.height, now, self.average_block_time));
propagation_time = Some(0);
@@ -222,12 +220,22 @@ impl Handler<UpdateNode> for Chain {
}
}
if let Some(node) = self.nodes.get_mut(nid) {
if let Some(details) = node.update_block(*block, now, propagation_time) {
self.serializer.push(feed::ImportedBlock(nid, details));
}
if let Some(details) = node.update_details(now, propagation_time) {
self.serializer.push(feed::ImportedBlock(nid, details));
}
}
}
}
impl Handler<UpdateNode> for Chain {
type Result = ();
fn handle(&mut self, msg: UpdateNode, _: &mut Self::Context) {
let UpdateNode { nid, msg, raw } = msg;
if let Some(block) = msg.details.best_block() {
self.handle_block(block, nid);
}
if let Some(node) = self.nodes.get_mut(nid) {
match msg.details {
+20 -13
View File
@@ -97,24 +97,31 @@ impl Node {
&self.best
}
pub fn update_block(&mut self, block: Block, timestamp: u64, propagation_time: Option<u64>) -> Option<&BlockDetails> {
pub fn update_block(&mut self, block: Block) -> bool {
if block.height > self.best.block.height {
self.stale = false;
self.best.block = block;
self.best.block_time = timestamp - self.best.block_timestamp;
self.best.block_timestamp = timestamp;
self.best.propagation_time = propagation_time;
if self.throttle < timestamp {
if self.best.block_time <= THROTTLE_THRESHOLD {
self.throttle = timestamp + THROTTLE_INTERVAL;
}
return Some(&self.best);
}
true
} else {
false
}
}
None
pub fn update_details(&mut self, timestamp: u64, propagation_time: Option<u64>) -> Option<&BlockDetails> {
self.best.block_time = timestamp - self.best.block_timestamp;
self.best.block_timestamp = timestamp;
self.best.propagation_time = propagation_time;
if self.throttle < timestamp {
if self.best.block_time <= THROTTLE_THRESHOLD {
self.throttle = timestamp + THROTTLE_INTERVAL;
}
Some(&self.best)
} else {
None
}
}
pub fn update_hardware(&mut self, interval: &SystemInterval) -> bool {