ICMP message-routing gossip (#304)

* core logic for ICMP gossip

* refactor gossip to make more extension friendly

* move files aroun

* extract attestation-gossip logic to its own module

* message validation and broadcast logic

* fix upstream crates' compilation

* add a test

* another test for overlapping

* Some grammar and phrasing tweaks

Co-Authored-By: Luke Schoen <ltfschoen@users.noreply.github.com>

* add since parameter to ingress runtime API

* broadcast out known unrouted message queues

* fix compilation of service and collator

* remove useless index_mapping

* some tests for icmp propagation

* fix decoding bug and test icmp queue validation

* simplify engine-id definition

Co-Authored-By: Sergei Pepyakin <sergei@parity.io>

* address some grumbles

* some cleanup of old circulation code

* give network a handle to extrinsic store on startup

* an honest collator ensures data available as well

* address some grumbles

* add docs; rename the attestation session to "leaf work"

* module docs

* move gossip back to gossip.rs

* clean up and document attestation-gossip a bit

* some more docs on the availability store

* store all outgoing message queues in the availability store

* filter `Extrinsic` out of validation crate

* expunge Extrinsic from network

* expunge Extrinsic from erasure-coding

* expunge Extrinsic from collator

* expunge from adder-collator

* rename ExtrinsicStore to AvailabilityStore everywhere

* annotate and clean up message-routing tests
This commit is contained in:
Robert Habermeier
2019-08-29 11:49:59 +02:00
committed by GitHub
parent bd8ebbfee5
commit 55c4c830fe
22 changed files with 1981 additions and 818 deletions
+35 -13
View File
@@ -18,7 +18,7 @@
use std::collections::HashMap;
use super::{PolkadotProtocol, Status, Message, FullStatus};
use crate::validation::SessionParams;
use crate::validation::LeafWorkParams;
use polkadot_validation::GenericStatement;
use polkadot_primitives::{Block, Hash};
@@ -77,6 +77,28 @@ impl TestContext {
}
}
#[derive(Default)]
pub struct TestChainContext {
pub known_map: HashMap<Hash, crate::gossip::Known>,
pub ingress_roots: HashMap<Hash, Vec<Hash>>,
}
impl crate::gossip::ChainContext for TestChainContext {
fn is_known(&self, block_hash: &Hash) -> Option<crate::gossip::Known> {
self.known_map.get(block_hash).map(|x| x.clone())
}
fn leaf_unrouted_roots(&self, leaf: &Hash, with_queue_root: &mut dyn FnMut(&Hash))
-> Result<(), substrate_client::error::Error>
{
for root in self.ingress_roots.get(leaf).into_iter().flat_map(|roots| roots) {
with_queue_root(root)
}
Ok(())
}
}
fn make_pov(block_data: Vec<u8>) -> PoVBlock {
PoVBlock {
block_data: BlockData(block_data),
@@ -96,8 +118,8 @@ fn make_status(status: &Status, roles: Roles) -> FullStatus {
}
}
fn make_validation_session(parent_hash: Hash, local_key: ValidatorId) -> SessionParams {
SessionParams {
fn make_validation_leaf_work(parent_hash: Hash, local_key: ValidatorId) -> LeafWorkParams {
LeafWorkParams {
local_session_key: Some(local_key),
parent_hash,
authorities: Vec::new(),
@@ -129,8 +151,8 @@ fn sends_session_key() {
{
let mut ctx = TestContext::default();
let params = make_validation_session(parent_hash, local_key.clone());
protocol.new_validation_session(&mut ctx, params);
let params = make_validation_leaf_work(parent_hash, local_key.clone());
protocol.new_validation_leaf_work(&mut ctx, params);
assert!(ctx.has_message(peer_a, Message::ValidatorId(local_key.clone())));
}
@@ -169,8 +191,8 @@ fn fetches_from_those_with_knowledge() {
let status = Status { collating_for: None };
let params = make_validation_session(parent_hash, local_key.clone());
let session = protocol.new_validation_session(&mut TestContext::default(), params);
let params = make_validation_leaf_work(parent_hash, local_key.clone());
let session = protocol.new_validation_leaf_work(&mut TestContext::default(), params);
let knowledge = session.knowledge();
knowledge.lock().note_statement(a_key.clone(), &GenericStatement::Valid(candidate_hash));
@@ -259,7 +281,7 @@ fn fetches_available_block_data() {
parachain_id: para_id,
candidate_hash,
block_data: block_data.clone(),
extrinsic: None,
outgoing_queues: None,
}).unwrap();
// connect peer A
@@ -323,13 +345,13 @@ fn many_session_keys() {
let local_key_a: ValidatorId = [3; 32].unchecked_into();
let local_key_b: ValidatorId = [4; 32].unchecked_into();
let params_a = make_validation_session(parent_a, local_key_a.clone());
let params_b = make_validation_session(parent_b, local_key_b.clone());
let params_a = make_validation_leaf_work(parent_a, local_key_a.clone());
let params_b = make_validation_leaf_work(parent_b, local_key_b.clone());
protocol.new_validation_session(&mut TestContext::default(), params_a);
protocol.new_validation_session(&mut TestContext::default(), params_b);
protocol.new_validation_leaf_work(&mut TestContext::default(), params_a);
protocol.new_validation_leaf_work(&mut TestContext::default(), params_b);
assert_eq!(protocol.live_validation_sessions.recent_keys(), &[local_key_a.clone(), local_key_b.clone()]);
assert_eq!(protocol.live_validation_leaves.recent_keys(), &[local_key_a.clone(), local_key_b.clone()]);
let peer_a = PeerId::random();
+9 -10
View File
@@ -18,18 +18,17 @@
#![allow(unused)]
use crate::validation::{NetworkService, GossipService, GossipMessageStream};
use crate::gossip::GossipMessage;
use substrate_network::Context as NetContext;
use substrate_network::consensus_gossip::TopicNotification;
use substrate_primitives::{NativeOrEncoded, ExecutionContext};
use substrate_keyring::Sr25519Keyring;
use crate::PolkadotProtocol;
use crate::{GossipService, PolkadotProtocol, NetworkService, GossipMessageStream};
use polkadot_validation::{SharedTable, MessagesFrom, Network};
use polkadot_primitives::{Block, Hash, Header, BlockId};
use polkadot_validation::{SharedTable, Network};
use polkadot_primitives::{Block, BlockNumber, Hash, Header, BlockId};
use polkadot_primitives::parachain::{
Id as ParaId, Chain, DutyRoster, ParachainHost, OutgoingMessage,
Id as ParaId, Chain, DutyRoster, ParachainHost, TargetedMessage,
ValidatorId, StructuredUnroutedIngress, BlockIngressRoots, Status,
FeeSchedule, HeadData,
};
@@ -43,7 +42,7 @@ use std::sync::Arc;
use futures::{prelude::*, sync::mpsc};
use codec::Encode;
use super::TestContext;
use super::{TestContext, TestChainContext};
type TaskExecutor = Arc<dyn futures::future::Executor<Box<dyn Future<Item = (), Error = ()> + Send>> + Send + Sync>;
@@ -315,10 +314,10 @@ impl ParachainHost<Block> for RuntimeApi {
&self,
_at: &BlockId,
_: ExecutionContext,
id: Option<ParaId>,
id: Option<(ParaId, Option<BlockNumber>)>,
_: Vec<u8>,
) -> ClientResult<NativeOrEncoded<Option<StructuredUnroutedIngress>>> {
let id = id.unwrap();
let (id, _) = id.unwrap();
Ok(NativeOrEncoded::Native(self.data.lock().ingress.get(&id).cloned()))
}
}
@@ -348,7 +347,7 @@ fn build_network(n: usize, executor: TaskExecutor) -> Built {
});
let message_val = crate::gossip::RegisteredMessageValidator::new_test(
|_hash: &_| Some(crate::gossip::Known::Leaf),
TestChainContext::default(),
Box::new(|_, _| {}),
);
@@ -376,7 +375,7 @@ struct IngressBuilder {
}
impl IngressBuilder {
fn add_messages(&mut self, source: ParaId, messages: &[OutgoingMessage]) {
fn add_messages(&mut self, source: ParaId, messages: &[TargetedMessage]) {
for message in messages {
let target = message.target;
self.egress.entry((source, target)).or_insert_with(Vec::new).push(message.data.clone());