Skip to content

Commit e7d86fb

Browse files
committed
Fix the condition to check whether the new block could change the best block
When a new block is imported in Tendermint consensus, CodeChain checks the conditions below to judge whether it is safe to change the best block: First, whether the score is higher than before. Second, whether the height of a new block is higher than the finalized block's height. This commit fixes the code that is calculating the finalized block's height erroneously.
1 parent 9d3955b commit e7d86fb

File tree

5 files changed

+23
-29
lines changed

5 files changed

+23
-29
lines changed

core/src/blockchain/blockchain.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -184,17 +184,19 @@ impl BlockChain {
184184
let new_header = new_block.header_view();
185185
let parent_hash_of_new_block = new_header.parent_hash();
186186
let parent_details_of_new_block = self.block_details(&parent_hash_of_new_block).expect("Invalid parent hash");
187+
let prev_best_proposal_hash = self.best_proposal_block_hash();
188+
let prev_best_hash = self.best_block_hash();
187189

188190
if parent_details_of_new_block.total_score + new_header.score() > self.best_proposal_block_detail().total_score
189-
&& engine.can_change_canon_chain(&new_header)
191+
&& engine.can_change_canon_chain(&new_header, prev_best_hash, prev_best_proposal_hash)
190192
{
191193
cinfo!(
192194
BLOCKCHAIN,
193195
"Block #{}({}) has higher total score, changing the best proposal/canonical chain.",
194196
new_header.number(),
195197
new_header.hash()
196198
);
197-
let prev_best_hash = self.best_block_hash();
199+
198200
let route = tree_route(self, prev_best_hash, parent_hash_of_new_block)
199201
.expect("blocks being imported always within recent history; qed");
200202

core/src/blockchain/headerchain.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -242,9 +242,11 @@ impl HeaderChain {
242242
fn best_header_changed(&self, new_header: &HeaderView, engine: &dyn CodeChainEngine) -> BestHeaderChanged {
243243
let parent_hash_of_new_header = new_header.parent_hash();
244244
let parent_details_of_new_header = self.block_details(&parent_hash_of_new_header).expect("Invalid parent hash");
245+
let prev_best_proposal_hash = self.best_proposal_header_hash();
246+
let prev_best_hash = self.best_header_hash();
245247
let is_new_best = parent_details_of_new_header.total_score + new_header.score()
246248
> self.best_proposal_header_detail().total_score
247-
&& engine.can_change_canon_chain(&new_header);
249+
&& engine.can_change_canon_chain(&new_header, prev_best_hash, prev_best_proposal_hash);
248250

249251
if is_new_best {
250252
ctrace!(
@@ -256,7 +258,6 @@ impl HeaderChain {
256258
// on new best block we need to make sure that all ancestors
257259
// are moved to "canon chain"
258260
// find the route between old best block and the new one
259-
let prev_best_hash = self.best_header_hash();
260261
let route = tree_route(self, prev_best_hash, parent_hash_of_new_header)
261262
.expect("blocks being imported always within recent history; qed");
262263

core/src/consensus/mod.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -266,10 +266,15 @@ pub trait ConsensusEngine: Sync + Send {
266266
header.hash()
267267
}
268268

269-
/// In PoW consensus, the higher scored block became the best block.
269+
/// In PoW consensus, the higher scored block becomes the best block.
270270
/// In Tendermint consensus, the highest scored block may not be the best block.
271-
/// Only the child of the current best block could be the next best block in Tendermint consensus.
272-
fn can_change_canon_chain(&self, _header: &HeaderView) -> bool {
271+
/// Only the descendant of the current best block could be the next best block in Tendermint consensus.
272+
fn can_change_canon_chain(
273+
&self,
274+
_new_header: &HeaderView,
275+
_previous_best_hash: H256,
276+
_previous_best_proposal_hash: H256,
277+
) -> bool {
273278
true
274279
}
275280

core/src/consensus/tendermint/engine.rs

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -308,15 +308,14 @@ impl ConsensusEngine for Tendermint {
308308
header.parent_hash()
309309
}
310310

311-
fn can_change_canon_chain(&self, header: &HeaderView) -> bool {
312-
let (result, receiver) = crossbeam::bounded(1);
313-
self.inner
314-
.send(worker::Event::AllowedHeight {
315-
result,
316-
})
317-
.unwrap();
318-
let allowed_height = receiver.recv().unwrap();
319-
header.number() >= allowed_height
311+
312+
fn can_change_canon_chain(
313+
&self,
314+
new_header: &HeaderView,
315+
prev_best_hash: H256,
316+
prev_best_proposal_hash: H256,
317+
) -> bool {
318+
new_header.parent_hash() == prev_best_hash || new_header.parent_hash() == prev_best_proposal_hash
320319
}
321320

322321
fn action_handlers(&self) -> &[Arc<dyn ActionHandler>] {

core/src/consensus/tendermint/worker.rs

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -133,9 +133,6 @@ pub enum Event {
133133
ap: Arc<AccountProvider>,
134134
address: Address,
135135
},
136-
AllowedHeight {
137-
result: crossbeam::Sender<Height>,
138-
},
139136
Restore(crossbeam::Sender<()>),
140137
ProposalBlock {
141138
signature: SchnorrSignature,
@@ -307,16 +304,6 @@ impl Worker {
307304
}) => {
308305
inner.set_signer(ap, address);
309306
}
310-
Ok(Event::AllowedHeight {
311-
result,
312-
}) => {
313-
let allowed_height = if inner.step.is_commit() {
314-
inner.height + 1
315-
} else {
316-
inner.height
317-
};
318-
result.send(allowed_height).unwrap();
319-
}
320307
Ok(Event::Restore(result)) => {
321308
inner.restore();
322309
result.send(()).unwrap();

0 commit comments

Comments
 (0)