Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
b1561e7
primitives/runtime: initial changes on supporting multiple Justificat…
octol Nov 19, 2020
16bfd2c
primitives/runtime: make Justifications strongly typed
octol Nov 30, 2020
d72b5eb
Encode/decode Justifications
octol Nov 30, 2020
88d1e1a
primitives/runtime: add Justification type
octol Dec 1, 2020
12f8f7e
backend: apply_finality and finalize_block takes a single Justification
octol Dec 2, 2020
75dc977
manual-seal: create engine id and let rpc take encoded justification
octol Dec 2, 2020
9920319
backend: skeleton functions for appending justifications
octol Dec 2, 2020
1f7f2d1
backend: initial implementation append_justification
octol Dec 10, 2020
523038a
backend: guard against duplicate consensus engine id
octol Dec 11, 2020
52a0dff
client/db: add check for block finality
octol Dec 14, 2020
a25d33d
client/api: add append_justification to in_mem db
octol Dec 14, 2020
f023cca
client/light: add no-op append_justification
octol Dec 15, 2020
2a6e9cd
Merge remote-tracking branch 'upstream/master' into jon/store-multipl…
octol Dec 15, 2020
46b4584
Merge remote-tracking branch 'upstream/master' into jon/store-multipl…
octol Jan 7, 2021
544c8e2
network: fix decode call for Justification
octol Jan 14, 2021
6aabece
network: only send a single Justification in BlockData
octol Jan 14, 2021
10e9f22
network: minor comment update
octol Jan 14, 2021
3613fdb
protocol: update field names to distinguish single justification
octol Jan 14, 2021
ce5dad9
client: further field renames to plural
octol Jan 14, 2021
b0f9b5c
client: update function names to plural justifications
octol Jan 14, 2021
4dc856e
Merge remote-tracking branch 'upstream/master' into jon/store-multipl…
octol Jan 14, 2021
2e23810
client/db: upgrade existing database for new format
octol Jan 19, 2021
66b2c4e
Merge remote-tracking branch 'upstream/master' into jon/store-multipl…
octol Jan 20, 2021
0b69a39
network: remove dependency on grandpa crate
octol Jan 29, 2021
b91f821
db: fix check for finalized block
octol Jan 29, 2021
9301c86
grandpa: check for multiple grandpa justifications hwne importing
octol Jan 29, 2021
63291b5
backend: update Finalizer trait to take multiple Justifications
octol Feb 1, 2021
206447c
db: remove debugging statements in migration code
octol Feb 1, 2021
4185aa5
manual-seal: update note about engine id
octol Feb 1, 2021
d0adabb
Merge remote-tracking branch 'upstream/master' into jon/store-multipl…
octol Feb 1, 2021
5cae4b1
db: fix check for finalized block
octol Feb 1, 2021
1d7e50b
client: update variable name to reflect it is now plural
octol Feb 10, 2021
4d1ed93
grandpa: fix incorrect empty Justications in test
octol Feb 10, 2021
a0cb5e3
primitives: make Justifications opaque to avoid being empty
octol Feb 11, 2021
c32e538
network: fix detecting empty Justification
octol Feb 11, 2021
2545ed2
runtime: doc strings for Justifications functions
octol Feb 12, 2021
45f9e20
runtime: add into_justifications
octol Feb 12, 2021
47bda20
Merge remote-tracking branch 'upstream/master' into jon/store-multipl…
octol Feb 12, 2021
b65b38a
primitives: check for duplicates in when adding to Justifications
octol Feb 16, 2021
c69833e
network/test: use real grandpa engine id in test
octol Feb 16, 2021
1019de3
Merge remote-tracking branch 'upstream/master' into jon/store-multipl…
octol Feb 16, 2021
8391a9d
client: fix reviewer comments
octol Feb 16, 2021
c9cc2c8
primitives: rename Justifications::push to append
octol Feb 16, 2021
7bbc156
backend: revert changes to Finalizer trait
octol Feb 22, 2021
a42122b
backend: revert mark_finalized
octol Feb 22, 2021
356176f
backend: revert changes to finalize_block
octol Feb 22, 2021
609bbe0
backend: revert finalized_blocks
octol Feb 22, 2021
037e0a4
db: add a quick early return for performance
octol Feb 22, 2021
c5fe8f2
client: minor reviewer comments
octol Feb 22, 2021
5c4a735
service/test: use local ConsensusEngineId
octol Feb 22, 2021
693757f
Merge remote-tracking branch 'upstream/master' into jon/store-multipl…
octol Feb 22, 2021
1667e41
network: add link to issue for sending multiple Justifications
octol Feb 22, 2021
d7ea7bd
Apply suggestions from code review
octol Feb 23, 2021
87cf0d3
Apply suggestions from code review
octol Feb 23, 2021
b266679
network: tweaks to review suggestions
octol Feb 23, 2021
7f8e0b3
network: revert change to BlockData for backwards compatibility
octol Feb 24, 2021
ad05998
Apply suggestion from code review
octol Feb 24, 2021
bcc69ce
Merge remote-tracking branch 'upstream/master' into jon/store-multipl…
octol Feb 24, 2021
3af1962
Apply suggestions from code review
octol Feb 25, 2021
3f5e07c
primitives: update doc comment for Justifications
octol Feb 26, 2021
a829791
client/db/upgrade: avoid grandpa crate dependency
octol Feb 26, 2021
dda0b2d
consensus: revert to single Justification for import_justification
octol Mar 1, 2021
711984f
Merge remote-tracking branch 'upstream/master' into jon/store-multipl…
octol Mar 1, 2021
9a2ba3c
Merge branch 'master' into jon/store-multiple-justifications
andresilva Mar 15, 2021
e405ce9
primitives: improve justifications docs
andresilva Mar 15, 2021
aaac8c5
style cleanups
andresilva Mar 15, 2021
3e4443f
use and_then
andresilva Mar 15, 2021
340e092
client: rename JUSTIFICATIONS db column
andresilva Mar 15, 2021
5c5449e
network: revert to using FRNK in network-test
octol Mar 16, 2021
c338058
Merge remote-tracking branch 'upstream/master' into jon/store-multipl…
octol Mar 16, 2021
ed93ea0
Merge branch 'master' into jon/store-multiple-justifications
andresilva Mar 16, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions client/api/src/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use std::sync::Arc;
use std::collections::{HashMap, HashSet};
use sp_core::ChangesTrieConfigurationRange;
use sp_core::offchain::OffchainStorage;
use sp_runtime::{generic::BlockId, Justification, Storage};
use sp_runtime::{generic::BlockId, Justification, Justifications, Storage};
use sp_runtime::traits::{Block as BlockT, NumberFor, HashFor};
use sp_state_machine::{
ChangesTrieState, ChangesTrieStorage as StateChangesTrieStorage, ChangesTrieTransaction,
Expand Down Expand Up @@ -148,7 +148,7 @@ pub trait BlockImportOperation<Block: BlockT> {
&mut self,
header: Block::Header,
body: Option<Vec<Block::Extrinsic>>,
justification: Option<Justification>,
justifications: Option<Justifications>,
state: NewBlockState,
) -> sp_blockchain::Result<()>;

Expand Down Expand Up @@ -197,6 +197,7 @@ pub trait BlockImportOperation<Block: BlockT> {
id: BlockId<Block>,
justification: Option<Justification>,
) -> sp_blockchain::Result<()>;

/// Mark a block as new head. If both block import and set head are specified, set head
/// overrides block import's best block rule.
fn mark_head(&mut self, id: BlockId<Block>) -> sp_blockchain::Result<()>;
Expand Down Expand Up @@ -230,7 +231,6 @@ pub trait Finalizer<Block: BlockT, B: Backend<Block>> {
notify: bool,
) -> sp_blockchain::Result<()>;


/// Finalize a block.
///
/// This will implicitly finalize all blocks up to it and
Expand All @@ -250,7 +250,6 @@ pub trait Finalizer<Block: BlockT, B: Backend<Block>> {
justification: Option<Justification>,
notify: bool,
) -> sp_blockchain::Result<()>;

}

/// Provides access to an auxiliary database.
Expand Down Expand Up @@ -432,6 +431,15 @@ pub trait Backend<Block: BlockT>: AuxStore + Send + Sync {
justification: Option<Justification>,
) -> sp_blockchain::Result<()>;

/// Append justification to the block with the given Id.
///
/// This should only be called for blocks that are already finalized.
fn append_justification(
&self,
block: BlockId<Block>,
justification: Justification,
) -> sp_blockchain::Result<()>;

/// Returns reference to blockchain backend.
fn blockchain(&self) -> &Self::Blockchain;

Expand Down
6 changes: 3 additions & 3 deletions client/api/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use sp_core::storage::StorageKey;
use sp_runtime::{
traits::{Block as BlockT, NumberFor},
generic::{BlockId, SignedBlock},
Justification,
Justifications,
};
use sp_consensus::BlockOrigin;

Expand Down Expand Up @@ -90,8 +90,8 @@ pub trait BlockBackend<Block: BlockT> {
/// Get block status.
fn block_status(&self, id: &BlockId<Block>) -> sp_blockchain::Result<sp_consensus::BlockStatus>;

/// Get block justification set by id.
fn justification(&self, id: &BlockId<Block>) -> sp_blockchain::Result<Option<Justification>>;
/// Get block justifications for the block with the given id.
fn justifications(&self, id: &BlockId<Block>) -> sp_blockchain::Result<Option<Justifications>>;

/// Get block hash by number.
fn block_hash(&self, number: NumberFor<Block>) -> sp_blockchain::Result<Option<Block::Hash>>;
Expand Down
125 changes: 111 additions & 14 deletions client/api/src/in_mem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use sp_core::{
};
use sp_runtime::generic::BlockId;
use sp_runtime::traits::{Block as BlockT, Header as HeaderT, Zero, NumberFor, HashFor};
use sp_runtime::{Justification, Storage};
use sp_runtime::{Justification, Justifications, Storage};
use sp_state_machine::{
ChangesTrieTransaction, InMemoryBackend, Backend as StateBackend, StorageCollection,
ChildStorageCollection,
Expand All @@ -51,12 +51,12 @@ struct PendingBlock<B: BlockT> {

#[derive(PartialEq, Eq, Clone)]
enum StoredBlock<B: BlockT> {
Header(B::Header, Option<Justification>),
Full(B, Option<Justification>),
Header(B::Header, Option<Justifications>),
Full(B, Option<Justifications>),
}

impl<B: BlockT> StoredBlock<B> {
fn new(header: B::Header, body: Option<Vec<B::Extrinsic>>, just: Option<Justification>) -> Self {
fn new(header: B::Header, body: Option<Vec<B::Extrinsic>>, just: Option<Justifications>) -> Self {
match body {
Some(body) => StoredBlock::Full(B::new(header, body), just),
None => StoredBlock::Header(header, just),
Expand All @@ -70,7 +70,7 @@ impl<B: BlockT> StoredBlock<B> {
}
}

fn justification(&self) -> Option<&Justification> {
fn justifications(&self) -> Option<&Justifications> {
match *self {
StoredBlock::Header(_, ref j) | StoredBlock::Full(_, ref j) => j.as_ref()
}
Expand All @@ -83,7 +83,7 @@ impl<B: BlockT> StoredBlock<B> {
}
}

fn into_inner(self) -> (B::Header, Option<Vec<B::Extrinsic>>, Option<Justification>) {
fn into_inner(self) -> (B::Header, Option<Vec<B::Extrinsic>>, Option<Justifications>) {
match self {
StoredBlock::Header(header, just) => (header, None, just),
StoredBlock::Full(block, just) => {
Expand Down Expand Up @@ -164,7 +164,7 @@ impl<Block: BlockT> Blockchain<Block> {
&self,
hash: Block::Hash,
header: <Block as BlockT>::Header,
justification: Option<Justification>,
justifications: Option<Justifications>,
body: Option<Vec<<Block as BlockT>::Extrinsic>>,
new_state: NewBlockState,
) -> sp_blockchain::Result<()> {
Expand All @@ -176,7 +176,7 @@ impl<Block: BlockT> Blockchain<Block> {
{
let mut storage = self.storage.write();
storage.leaves.import(hash.clone(), number.clone(), header.parent_hash().clone());
storage.blocks.insert(hash.clone(), StoredBlock::new(header, body, justification));
storage.blocks.insert(hash.clone(), StoredBlock::new(header, body, justifications));

if let NewBlockState::Final = new_state {
storage.finalized_hash = hash;
Expand Down Expand Up @@ -285,16 +285,44 @@ impl<Block: BlockT> Blockchain<Block> {
let block = storage.blocks.get_mut(&hash)
.expect("hash was fetched from a block in the db; qed");

let block_justification = match block {
let block_justifications = match block {
StoredBlock::Header(_, ref mut j) | StoredBlock::Full(_, ref mut j) => j
};

*block_justification = justification;
*block_justifications = justification.map(Justifications::from);
}

Ok(())
}

fn append_justification(&self, id: BlockId<Block>, justification: Justification)
-> sp_blockchain::Result<()>
{
let hash = self.expect_block_hash_from_id(&id)?;
let mut storage = self.storage.write();

let block = storage
.blocks
.get_mut(&hash)
.expect("hash was fetched from a block in the db; qed");

let block_justifications = match block {
StoredBlock::Header(_, ref mut j) | StoredBlock::Full(_, ref mut j) => j
};

if let Some(stored_justifications) = block_justifications {
if !stored_justifications.append(justification) {
return Err(sp_blockchain::Error::BadJustification(
"Duplicate consensus engine ID".into()
));
}
} else {
*block_justifications = Some(Justifications::from(justification));
};

Ok(())
}

fn write_aux(&self, ops: Vec<(Vec<u8>, Option<Vec<u8>>)>) {
let mut storage = self.storage.write();
for (k, v) in ops {
Expand Down Expand Up @@ -365,9 +393,9 @@ impl<Block: BlockT> blockchain::Backend<Block> for Blockchain<Block> {
}))
}

fn justification(&self, id: BlockId<Block>) -> sp_blockchain::Result<Option<Justification>> {
fn justifications(&self, id: BlockId<Block>) -> sp_blockchain::Result<Option<Justifications>> {
Ok(self.id(id).and_then(|hash| self.storage.read().blocks.get(&hash).and_then(|b|
b.justification().map(|x| x.clone()))
b.justifications().map(|x| x.clone()))
))
}

Expand Down Expand Up @@ -508,12 +536,12 @@ impl<Block: BlockT> backend::BlockImportOperation<Block> for BlockImportOperatio
&mut self,
header: <Block as BlockT>::Header,
body: Option<Vec<<Block as BlockT>::Extrinsic>>,
justification: Option<Justification>,
justifications: Option<Justifications>,
state: NewBlockState,
) -> sp_blockchain::Result<()> {
assert!(self.pending_block.is_none(), "Only one block per operation is allowed");
self.pending_block = Some(PendingBlock {
block: StoredBlock::new(header, body, justification),
block: StoredBlock::new(header, body, justifications),
state,
});
Ok(())
Expand Down Expand Up @@ -696,6 +724,14 @@ impl<Block: BlockT> backend::Backend<Block> for Backend<Block> where Block::Hash
self.blockchain.finalize_header(block, justification)
}

fn append_justification(
&self,
block: BlockId<Block>,
justification: Justification,
) -> sp_blockchain::Result<()> {
self.blockchain.append_justification(block, justification)
}

fn blockchain(&self) -> &Self::Blockchain {
&self.blockchain
}
Expand Down Expand Up @@ -766,3 +802,64 @@ pub fn check_genesis_storage(storage: &Storage) -> sp_blockchain::Result<()> {

Ok(())
}

#[cfg(test)]
mod tests {
use crate::{NewBlockState, in_mem::Blockchain};
use sp_api::{BlockId, HeaderT};
use sp_runtime::{ConsensusEngineId, Justifications};
use sp_blockchain::Backend;
use substrate_test_runtime::{Block, Header, H256};

pub const ID1: ConsensusEngineId = *b"TST1";
pub const ID2: ConsensusEngineId = *b"TST2";

fn header(number: u64) -> Header {
let parent_hash = match number {
0 => Default::default(),
_ => header(number - 1).hash(),
};
Header::new(number, H256::from_low_u64_be(0), H256::from_low_u64_be(0), parent_hash, Default::default())
}

fn test_blockchain() -> Blockchain<Block> {
let blockchain = Blockchain::<Block>::new();
let just0 = Some(Justifications::from((ID1, vec![0])));
let just1 = Some(Justifications::from((ID1, vec![1])));
let just2 = None;
let just3 = Some(Justifications::from((ID1, vec![3])));
blockchain.insert(header(0).hash(), header(0), just0, None, NewBlockState::Final).unwrap();
blockchain.insert(header(1).hash(), header(1), just1, None, NewBlockState::Final).unwrap();
blockchain.insert(header(2).hash(), header(2), just2, None, NewBlockState::Best).unwrap();
blockchain.insert(header(3).hash(), header(3), just3, None, NewBlockState::Final).unwrap();
blockchain
}

#[test]
fn append_and_retrieve_justifications() {
let blockchain = test_blockchain();
let last_finalized = blockchain.last_finalized().unwrap();
let block = BlockId::Hash(last_finalized);

blockchain.append_justification(block, (ID2, vec![4])).unwrap();
let justifications = {
let mut just = Justifications::from((ID1, vec![3]));
just.append((ID2, vec![4]));
just
};
assert_eq!(blockchain.justifications(block).unwrap(), Some(justifications));
}

#[test]
fn store_duplicate_justifications_is_forbidden() {
let blockchain = test_blockchain();
let last_finalized = blockchain.last_finalized().unwrap();
let block = BlockId::Hash(last_finalized);

blockchain.append_justification(block, (ID2, vec![0])).unwrap();
assert!(matches!(
blockchain.append_justification(block, (ID2, vec![1])),
Err(sp_blockchain::Error::BadJustification(_)),
));
}
}
6 changes: 3 additions & 3 deletions client/consensus/aura/src/import_queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ use sp_consensus::{
use sc_client_api::{backend::AuxStore, BlockOf};
use sp_blockchain::{well_known_cache_keys::{self, Id as CacheKeyId}, ProvideCache, HeaderBackend};
use sp_block_builder::BlockBuilder as BlockBuilderApi;
use sp_runtime::{generic::{BlockId, OpaqueDigestItemId}, Justification};
use sp_runtime::{generic::{BlockId, OpaqueDigestItemId}, Justifications};
use sp_runtime::traits::{Block as BlockT, Header, DigestItemFor, Zero};
use sp_api::ProvideRuntimeApi;
use sp_core::crypto::Pair;
Expand Down Expand Up @@ -238,7 +238,7 @@ impl<B: BlockT, C, P, CAW> Verifier<B> for AuraVerifier<C, P, CAW> where
&mut self,
origin: BlockOrigin,
header: B::Header,
justification: Option<Justification>,
justifications: Option<Justifications>,
mut body: Option<Vec<B::Extrinsic>>,
) -> Result<(BlockImportParams<B, ()>, Option<Vec<(CacheKeyId, Vec<u8>)>>), String> {
let mut inherent_data = self.inherent_data_providers
Expand Down Expand Up @@ -317,7 +317,7 @@ impl<B: BlockT, C, P, CAW> Verifier<B> for AuraVerifier<C, P, CAW> where
let mut import_block = BlockImportParams::new(origin, pre_header);
import_block.post_digests.push(seal);
import_block.body = body;
import_block.justification = justification;
import_block.justifications = justifications;
import_block.fork_choice = Some(ForkChoiceStrategy::LongestChain);
import_block.post_hash = Some(hash);

Expand Down
10 changes: 5 additions & 5 deletions client/consensus/babe/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ use sp_core::crypto::Public;
use sp_application_crypto::AppKey;
use sp_keystore::{SyncCryptoStorePtr, SyncCryptoStore};
use sp_runtime::{
generic::{BlockId, OpaqueDigestItemId}, Justification,
generic::{BlockId, OpaqueDigestItemId}, Justifications,
traits::{Block as BlockT, Header, DigestItemFor, Zero},
};
use sp_api::{ProvideRuntimeApi, NumberFor};
Expand Down Expand Up @@ -1097,15 +1097,15 @@ where
&mut self,
origin: BlockOrigin,
header: Block::Header,
justification: Option<Justification>,
justifications: Option<Justifications>,
mut body: Option<Vec<Block::Extrinsic>>,
) -> Result<(BlockImportParams<Block, ()>, Option<Vec<(CacheKeyId, Vec<u8>)>>), String> {
trace!(
target: "babe",
"Verifying origin: {:?} header: {:?} justification: {:?} body: {:?}",
"Verifying origin: {:?} header: {:?} justification(s): {:?} body: {:?}",
origin,
header,
justification,
justifications,
body,
);

Expand Down Expand Up @@ -1194,7 +1194,7 @@ where
let mut import_block = BlockImportParams::new(origin, pre_header);
import_block.post_digests.push(verified_info.seal);
import_block.body = body;
import_block.justification = justification;
import_block.justifications = justifications;
import_block.intermediates.insert(
Cow::from(INTERMEDIATE_KEY),
Box::new(BabeIntermediate::<Block> { epoch_descriptor }) as Box<dyn Any>,
Expand Down
4 changes: 2 additions & 2 deletions client/consensus/babe/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,12 +235,12 @@ impl Verifier<TestBlock> for TestVerifier {
&mut self,
origin: BlockOrigin,
mut header: TestHeader,
justification: Option<Justification>,
justifications: Option<Justifications>,
body: Option<Vec<TestExtrinsic>>,
) -> Result<(BlockImportParams<TestBlock, ()>, Option<Vec<(CacheKeyId, Vec<u8>)>>), String> {
// apply post-sealing mutations (i.e. stripping seal, if desired).
(self.mutator)(&mut header, Stage::PostSeal);
self.inner.verify(origin, header, justification, body)
self.inner.verify(origin, header, justifications, body)
}
}

Expand Down
Loading