Storing multiple Justifications per block (#7640)

* primitives/runtime: initial changes on supporting multiple Justifications

* primitives/runtime: make Justifications strongly typed

* Encode/decode Justifications

* primitives/runtime: add Justification type

* backend: apply_finality and finalize_block takes a single Justification

* manual-seal: create engine id and let rpc take encoded justification

* backend: skeleton functions for appending justifications

* backend: initial implementation append_justification

Initial implementation of append_justification on the Backend trait, and also remove unused skeleton
functions for append_justificaton on Finaziler trait.
k

* backend: guard against duplicate consensus engine id

* client/db: add check for block finality

* client/api: add append_justification to in_mem db

* client/light: add no-op append_justification

* network: fix decode call for Justification

* network: only send a single Justification in BlockData

* network: minor comment update

* protocol: update field names to distinguish single justification

* client: further field renames to plural

* client: update function names to plural justifications

* client/db: upgrade existing database for new format

* network: remove dependency on grandpa crate

* db: fix check for finalized block

* grandpa: check for multiple grandpa justifications hwne importing

* backend: update Finalizer trait to take multiple Justifications

* db: remove debugging statements in migration code

* manual-seal: update note about engine id

* db: fix check for finalized block

* client: update variable name to reflect it is now plural

* grandpa: fix incorrect empty Justications in test

* primitives: make Justifications opaque to avoid being empty

* network: fix detecting empty Justification

* runtime: doc strings for Justifications functions

* runtime: add into_justifications

* primitives: check for duplicates in when adding to Justifications

* network/test: use real grandpa engine id in test

* client: fix reviewer comments

* primitives: rename Justifications::push to append

* backend: revert changes to Finalizer trait

* backend: revert mark_finalized

* backend: revert changes to finalize_block

* backend: revert finalized_blocks

* db: add a quick early return for performance

* client: minor reviewer comments

* service/test: use local ConsensusEngineId

* network: add link to issue for sending multiple Justifications

* Apply suggestions from code review

Co-authored-by: Pierre Krieger <pierre.krieger1708@gmail.com>

* Apply suggestions from code review

Co-authored-by: Pierre Krieger <pierre.krieger1708@gmail.com>

* network: tweaks to review suggestions

* network: revert change to BlockData for backwards compatibility

* Apply suggestion from code review

Co-authored-by: Pierre Krieger <pierre.krieger1708@gmail.com>

* Apply suggestions from code review

Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com>

* primitives: update doc comment for Justifications

* client/db/upgrade: avoid grandpa crate dependency

* consensus: revert to single Justification for import_justification

* primitives: improve justifications docs

* style cleanups

* use and_then

* client: rename JUSTIFICATIONS db column

* network: revert to using FRNK in network-test

Co-authored-by: Pierre Krieger <pierre.krieger1708@gmail.com>
Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com>
Co-authored-by: André Silva <andrerfosilva@gmail.com>
This commit is contained in:
Jon Häggblad
2021-03-17 22:18:16 +01:00
committed by GitHub
parent c7d32ba9a6
commit 0d6884b919
43 changed files with 635 additions and 270 deletions
@@ -148,7 +148,7 @@ pub struct RemoteReadResponse {
pub mod generic {
use bitflags::bitflags;
use codec::{Encode, Decode, Input, Output};
use sp_runtime::Justification;
use sp_runtime::EncodedJustification;
use super::{
RemoteReadResponse, Transactions, Direction,
RequestId, BlockAttributes, RemoteCallResponse, ConsensusEngineId,
@@ -233,7 +233,7 @@ pub mod generic {
/// Block message queue if requested.
pub message_queue: Option<Vec<u8>>,
/// Justification if requested.
pub justification: Option<Justification>,
pub justification: Option<EncodedJustification>,
}
/// Identifies starting point of a block sequence.
+22 -8
View File
@@ -44,7 +44,7 @@ use extra_requests::ExtraRequests;
use libp2p::PeerId;
use log::{debug, trace, warn, info, error};
use sp_runtime::{
Justification,
EncodedJustification, Justifications,
generic::BlockId,
traits::{
Block as BlockT, Header as HeaderT, NumberFor, Zero, One, CheckedSub, SaturatedConversion,
@@ -425,7 +425,7 @@ pub enum OnBlockJustification<B: BlockT> {
peer: PeerId,
hash: B::Hash,
number: NumberFor<B>,
justification: Justification
justifications: Justifications
}
}
@@ -823,11 +823,13 @@ impl<B: BlockT> ChainSync<B> {
.drain(self.best_queued_number + One::one())
.into_iter()
.map(|block_data| {
let justifications =
legacy_justification_mapping(block_data.block.justification);
IncomingBlock {
hash: block_data.block.hash,
header: block_data.block.header,
body: block_data.block.body,
justification: block_data.block.justification,
justifications,
origin: block_data.origin,
allow_missing_state: true,
import_existing: false,
@@ -846,7 +848,7 @@ impl<B: BlockT> ChainSync<B> {
hash: b.hash,
header: b.header,
body: b.body,
justification: b.justification,
justifications: legacy_justification_mapping(b.justification),
origin: Some(who.clone()),
allow_missing_state: true,
import_existing: false,
@@ -955,7 +957,7 @@ impl<B: BlockT> ChainSync<B> {
hash: b.hash,
header: b.header,
body: b.body,
justification: b.justification,
justifications: legacy_justification_mapping(b.justification),
origin: Some(who.clone()),
allow_missing_state: true,
import_existing: false,
@@ -1039,8 +1041,11 @@ impl<B: BlockT> ChainSync<B> {
None
};
if let Some((peer, hash, number, j)) = self.extra_justifications.on_response(who, justification) {
return Ok(OnBlockJustification::Import { peer, hash, number, justification: j })
if let Some((peer, hash, number, j)) = self
.extra_justifications
.on_response(who, legacy_justification_mapping(justification))
{
return Ok(OnBlockJustification::Import { peer, hash, number, justifications: j })
}
}
@@ -1597,6 +1602,14 @@ impl<B: BlockT> ChainSync<B> {
}
}
// This is purely during a backwards compatible transitionary period and should be removed
// once we can assume all nodes can send and receive multiple Justifications
// The ID tag is hardcoded here to avoid depending on the GRANDPA crate.
// TODO: https://github.com/paritytech/substrate/issues/8172
fn legacy_justification_mapping(justification: Option<EncodedJustification>) -> Option<Justifications> {
justification.map(|just| (*b"FRNK", just).into())
}
#[derive(Debug)]
pub(crate) struct Metrics {
pub(crate) queued_blocks: u32,
@@ -2396,7 +2409,8 @@ mod test {
);
let finalized_block = blocks[MAX_BLOCKS_TO_LOOK_BACKWARDS as usize * 2 - 1].clone();
client.finalize_block(BlockId::Hash(finalized_block.hash()), Some(Vec::new())).unwrap();
let just = (*b"TEST", Vec::new());
client.finalize_block(BlockId::Hash(finalized_block.hash()), Some(just)).unwrap();
sync.update_chain_info(&info.best_hash, info.best_number);
let peer_id1 = PeerId::random();