-
Notifications
You must be signed in to change notification settings - Fork 7
Connectivity Report spam mitigations #314
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,7 +9,7 @@ use crate::{ | |
| }; | ||
| use std::{ | ||
| collections::BTreeMap, | ||
| time::{Duration, Instant}, | ||
| time::{Duration, Instant, UNIX_EPOCH}, | ||
| }; | ||
|
|
||
| use super::{ | ||
|
|
@@ -261,8 +261,8 @@ impl HbbftEarlyEpochEndManager { | |
| } | ||
| } | ||
|
|
||
| /// decides on the memorium data if we should update to contract data. | ||
| /// end executes them. | ||
| /// decides on the memorium data if we should update to contract data, | ||
| /// and sends out transactions to do so. | ||
| pub fn decide( | ||
| &mut self, | ||
| memorium: &HbbftMessageMemorium, | ||
|
|
@@ -286,25 +286,51 @@ impl HbbftEarlyEpochEndManager { | |
| debug!(target: "engine", "early-epoch-end: detected attempt to break because of is_major_syncing() instead of is_synincg()no decision: syncing"); | ||
| } | ||
|
|
||
| let block_num = if let Some(block) = full_client.block(BlockId::Latest) { | ||
| block.number() | ||
| let (block_num, block_time) = if let Some(block) = full_client.block(BlockId::Latest) { | ||
| (block.number(), block.timestamp()) | ||
| } else { | ||
| error!(target:"engine", "early-epoch-end: could not retrieve latest block."); | ||
| return; | ||
| }; | ||
|
|
||
| let treshold: u64 = 2; | ||
| // start of implementation for: | ||
| // https://github.com/DMDcoin/diamond-node/issues/243 | ||
| // connectivity reports should not trigger if there is no block production | ||
| let now = UNIX_EPOCH.elapsed().expect("Time not available").as_secs(); | ||
| // this should hold true. | ||
| if now >= block_time { | ||
| let elapsed_since_last_block = now - block_time; | ||
| // todo: this is max blocktime (heartbeat) x 2, better read the maximum blocktime. | ||
| // on phoenix protocol triggers, this would also skip the sending of disconnectivity reports. | ||
| if elapsed_since_last_block > 10 * 60 { | ||
| info!(target:"engine", "skipping early-epoch-end: now {now} ; block_time {block_time}: Block WAS created in the future ?!?! :-x. not sending early epoch end reports."); | ||
| return; | ||
| } | ||
| } else { | ||
| // if the newest block is from the future, something very problematic happened. | ||
| // the system clock could be wrong. | ||
| // or the blockchain really produces blocks from the future. | ||
| // we are just not sending reports in this case. | ||
|
|
||
| error!(target:"engine", "early-epoch-end: now {now} ; block_time {block_time}: Block WAS created in the future ?!?! :-x. not sending early epoch end reports."); | ||
|
||
| return; | ||
| } | ||
| // end of implementation for: | ||
| // https://github.com/DMDcoin/diamond-node/issues/243 | ||
|
|
||
| let threshold: u64 = 2; | ||
|
|
||
| // todo: read this out from contracts: ConnectivityTrackerHbbft -> reportDisallowPeriod | ||
| // requires us to update the Contracts ABIs: | ||
| // https://github.com/DMDcoin/diamond-node/issues/115 | ||
| let treshold_time = Duration::from_secs(12 * 60); // 12 Minutes = 1 times the heartbeat + 2 minutes as grace period. | ||
| let threshold_time = Duration::from_secs(12 * 60); // 12 Minutes = 1 times the heartbeat + 2 minutes as grace period. | ||
|
|
||
| if self.start_time.elapsed() < treshold_time { | ||
| debug!(target: "engine", "early-epoch-end: no decision: Treshold time not reached."); | ||
| if self.start_time.elapsed() < threshold_time { | ||
| debug!(target: "engine", "early-epoch-end: no decision: Threshold time not reached."); | ||
| return; | ||
| } | ||
|
|
||
| if block_num < self.start_block + treshold { | ||
| if block_num < self.start_block + threshold { | ||
| // not enought blocks have passed this epoch, | ||
| // to judge other nodes. | ||
| debug!(target: "engine", "early-epoch-end: no decision: not enough blocks."); | ||
|
|
@@ -328,7 +354,7 @@ impl HbbftEarlyEpochEndManager { | |
| if let Some(node_history) = epoch_history.get_history_for_node(validator) { | ||
| let last_message_time = node_history.get_last_good_message_time(); | ||
| let last_message_time_lateness = last_message_time.elapsed(); | ||
| if last_message_time_lateness > treshold_time { | ||
| if last_message_time_lateness > threshold_time { | ||
| // we do not have to send notification, if we already did so. | ||
| if !self.is_reported(client, validator_address) { | ||
| // this function will also add the validator to the list of flagged validators. | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -60,7 +60,7 @@ use super::{ | |||||
| sealing::{self, RlpSig, Sealing}, | ||||||
| }; | ||||||
| use crate::engines::hbbft::hbbft_message_memorium::HbbftMessageDispatcher; | ||||||
| use std::{ops::Deref, sync::atomic::Ordering}; | ||||||
| use std::sync::atomic::Ordering; | ||||||
|
|
||||||
| // Internal representation for storing deferred outgoing consensus messages. | ||||||
| struct StoredOutgoingMessage { | ||||||
|
|
@@ -194,6 +194,8 @@ const ENGINE_VALIDATOR_CANDIDATE_ACTIONS: TimerToken = 4; | |||||
| // Check for current Phoenix Protocol phase | ||||||
| const ENGINE_PHOENIX_CHECK: TimerToken = 5; | ||||||
|
|
||||||
| const HBBFT_CONNECTIVITY_TOKEN: TimerToken = 6; | ||||||
|
|
||||||
| impl TransitionHandler { | ||||||
| fn handle_shutdown_on_missing_block_import( | ||||||
| &self, | ||||||
|
|
@@ -383,6 +385,12 @@ impl IoHandler<()> for TransitionHandler { | |||||
| .unwrap_or_else( | ||||||
| |e| warn!(target: "consensus", "ENGINE_PHOENIX_CHECK Timer failed: {}.", e), | ||||||
| ); | ||||||
|
|
||||||
| // early epoch end connecitity token should be the same length then the max blocktime. | ||||||
| io.register_timer(HBBFT_CONNECTIVITY_TOKEN, Duration::from_secs(300)) | ||||||
| .unwrap_or_else( | ||||||
| |e| warn!(target: "consensus", "ENGINE_PHOENIX_CHECK Timer failed: {}.", e), | ||||||
|
||||||
| |e| warn!(target: "consensus", "ENGINE_PHOENIX_CHECK Timer failed: {}.", e), | |
| |e| warn!(target: "consensus", "HBBFT_CONNECTIVITY_TOKEN Timer failed: {}.", e), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Grammar issue: "Block WAS created" should use "was" in lowercase for consistent sentence capitalization.