aura: finalize blocks (#9692)

* aura: emit ancestry actions for finalizing blocks

* aura: refactor is_epoch_end to get finalized blocks as argument

* ethcore: add is_epoch_end_light method to Engine

The full client now tracks finality by querying the engine on each block import,
and it also persists the finalization state to the DB. For the light client
current it doesn't persist finality information and only keeps track of finality
for epoch signals, by calling `is_epoch_end_light`. This method implements the
previously existing logic of building finality for all the blocks in the current
epoch and then checking the finalized blocks against the transition store.

* ethcore: allow finalizing current block

* aura: fix construction of finality proof

* aura: fix warnings

- missing docs for is_epoch_end_light
- unused method unfinalized_hashes in RollingFinality

* aura: fix clone on copy types
This commit is contained in:
André Silva
2018-10-25 16:33:41 +01:00
committed by Andrew Jones
parent 9a2c4a34ee
commit e7f1204fa4
7 changed files with 220 additions and 121 deletions

View File

@@ -474,7 +474,7 @@ impl Importer {
let number = header.number();
let parent = header.parent_hash();
let chain = client.chain.read();
let is_finalized = false;
let mut is_finalized = false;
// Commit results
let block = block.drain();
@@ -536,10 +536,18 @@ impl Importer {
state.journal_under(&mut batch, number, hash).expect("DB commit failed");
for ancestry_action in ancestry_actions {
let AncestryAction::MarkFinalized(ancestry) = ancestry_action;
chain.mark_finalized(&mut batch, ancestry).expect("Engine's ancestry action must be known blocks; qed");
}
let finalized: Vec<_> = ancestry_actions.into_iter().map(|ancestry_action| {
let AncestryAction::MarkFinalized(a) = ancestry_action;
if a != header.hash() {
chain.mark_finalized(&mut batch, a).expect("Engine's ancestry action must be known blocks; qed");
} else {
// we're finalizing the current block
is_finalized = true;
}
a
}).collect();
let route = chain.insert_block(&mut batch, block_data, receipts.clone(), ExtrasInsert {
fork_choice: fork_choice,
@@ -560,7 +568,7 @@ impl Importer {
client.db.read().key_value().write_buffered(batch);
chain.commit();
self.check_epoch_end(&header, &chain, client);
self.check_epoch_end(&header, &finalized, &chain, client);
client.update_last_hashes(&parent, hash);
@@ -667,9 +675,10 @@ impl Importer {
}
// check for ending of epoch and write transition if it occurs.
fn check_epoch_end<'a>(&self, header: &'a Header, chain: &BlockChain, client: &Client) {
fn check_epoch_end<'a>(&self, header: &'a Header, finalized: &'a [H256], chain: &BlockChain, client: &Client) {
let is_epoch_end = self.engine.is_epoch_end(
header,
finalized,
&(|hash| client.block_header_decoded(BlockId::Hash(hash))),
&(|hash| chain.get_pending_transition(hash)), // TODO: limit to current epoch.
);