Skip to content

Commit 33201e2

Browse files
committed
Do not precommit 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 33201e2

File tree

1 file changed

+26
-8
lines changed

1 file changed

+26
-8
lines changed

core/src/consensus/tendermint/worker.rs

Lines changed: 26 additions & 8 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};
@@ -667,15 +668,17 @@ impl Worker {
667668
self.request_messages_to_all(vote_step, &BitSet::all_set() - &self.votes_received);
668669
if !self.already_generated_message() {
669670
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-
}
671+
TwoThirdsMajority::Lock(locked_view, block_hash)
672+
if locked_view == &self.view && {
673+
let locked_proposal_block = self
674+
.locked_proposal_block(*locked_view)
675+
.expect("In precommit step, block was imported and we have hash");
676+
self.is_generation_time_relevant(&locked_proposal_block.decode_header())
677+
} =>
678+
{
679+
Some(*block_hash)
678680
}
681+
_ => None,
679682
};
680683
self.generate_and_broadcast_message(block_hash, is_restoring);
681684
}
@@ -686,6 +689,21 @@ impl Worker {
686689
}
687690
}
688691

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

0 commit comments

Comments
 (0)