Skip to content

Commit a1bedcd

Browse files
committed
Do not prevote to the block with irrelevant generation time
If the proposal generation time is 30 seconds or more before from now or if 5 seconds or more later from now, the block generation time is now considered irrelevant.
1 parent 0448a3c commit a1bedcd

File tree

1 file changed

+25
-9
lines changed

1 file changed

+25
-9
lines changed

core/src/consensus/tendermint/worker.rs

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use std::iter::Iterator;
1818
use std::mem;
1919
use std::sync::{Arc, Weak};
2020
use std::thread::{Builder, JoinHandle};
21+
use std::time::{Duration, SystemTime, UNIX_EPOCH};
2122

2223
use ccrypto::blake256;
2324
use ckey::{public_to_address, verify_schnorr, Address, SchnorrSignature};
@@ -651,11 +652,16 @@ impl Worker {
651652
// In the case, self.votes_received is not empty.
652653
self.request_messages_to_all(vote_step, &BitSet::all_set() - &self.votes_received);
653654
if !self.already_generated_message() {
654-
let block_hash = match &self.last_two_thirds_majority {
655+
let block_hash_candidate = match &self.last_two_thirds_majority {
655656
TwoThirdsMajority::Empty => self.proposal.imported_block_hash(),
656657
TwoThirdsMajority::Unlock(_) => self.proposal.imported_block_hash(),
657658
TwoThirdsMajority::Lock(_, block_hash) => Some(*block_hash),
658659
};
660+
let block_hash = block_hash_candidate.filter(|hash| {
661+
let block =
662+
self.client().block(&BlockId::Hash(*hash)).expect("Already got imported block hash");
663+
self.is_generation_time_relevant(&block.decode_header())
664+
});
659665
self.generate_and_broadcast_message(block_hash, is_restoring);
660666
}
661667
}
@@ -667,15 +673,10 @@ impl Worker {
667673
self.request_messages_to_all(vote_step, &BitSet::all_set() - &self.votes_received);
668674
if !self.already_generated_message() {
669675
let block_hash = match &self.last_two_thirds_majority {
670-
TwoThirdsMajority::Empty => None,
671-
TwoThirdsMajority::Unlock(_) => None,
672-
TwoThirdsMajority::Lock(locked_view, block_hash) => {
673-
if locked_view == &self.view {
674-
Some(*block_hash)
675-
} else {
676-
None
677-
}
676+
TwoThirdsMajority::Lock(locked_view, block_hash) if locked_view == &self.view => {
677+
Some(*block_hash)
678678
}
679+
_ => None,
679680
};
680681
self.generate_and_broadcast_message(block_hash, is_restoring);
681682
}
@@ -686,6 +687,21 @@ impl Worker {
686687
}
687688
}
688689

690+
fn is_generation_time_relevant(&self, block_header: &Header) -> bool {
691+
const ACCEPTABLE_FUTURE_GAP: Duration = Duration::from_secs(5);
692+
const ACCEPTABLE_PAST_GAP: Duration = Duration::from_secs(30);
693+
let now = SystemTime::now();
694+
let allowed_min = now - ACCEPTABLE_PAST_GAP;
695+
let allowed_max = now + ACCEPTABLE_FUTURE_GAP;
696+
let block_generation_time = UNIX_EPOCH.checked_add(Duration::from_secs(block_header.timestamp()));
697+
698+
match block_generation_time {
699+
Some(generation_time) => generation_time <= allowed_max && allowed_min <= generation_time,
700+
// Overflow occurred
701+
None => false,
702+
}
703+
}
704+
689705
fn locked_proposal_block(&self, locked_view: View) -> Result<encoded::Block, String> {
690706
let vote_step = VoteStep::new(self.height, locked_view, Step::Propose);
691707
let locked_proposal_hash = self.votes.get_block_hashes(&vote_step).first().cloned();

0 commit comments

Comments
 (0)