mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 08:11:03 +00:00
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:
committed by
GitHub
parent
bd8ebbfee5
commit
55c4c830fe
@@ -57,7 +57,7 @@ use primitives::Pair;
|
||||
use polkadot_primitives::{
|
||||
BlockId, Hash, Block,
|
||||
parachain::{
|
||||
self, BlockData, DutyRoster, HeadData, ConsolidatedIngress, Message, Id as ParaId, Extrinsic,
|
||||
self, BlockData, DutyRoster, HeadData, ConsolidatedIngress, Message, Id as ParaId, OutgoingMessages,
|
||||
PoVBlock, Status as ParachainStatus, ValidatorId, CollatorPair,
|
||||
}
|
||||
};
|
||||
@@ -65,8 +65,8 @@ use polkadot_cli::{
|
||||
Worker, IntoExit, ProvideRuntimeApi, TaskExecutor, AbstractService,
|
||||
CustomConfiguration, ParachainHost,
|
||||
};
|
||||
use polkadot_network::validation::{SessionParams, ValidationNetwork};
|
||||
use polkadot_network::{NetworkService, PolkadotProtocol};
|
||||
use polkadot_network::validation::{LeafWorkParams, ValidationNetwork};
|
||||
use polkadot_network::{PolkadotNetworkService, PolkadotProtocol};
|
||||
use tokio::timer::Timeout;
|
||||
|
||||
pub use polkadot_cli::VersionInfo;
|
||||
@@ -91,7 +91,7 @@ pub trait Network: Send + Sync {
|
||||
fn checked_statements(&self, relay_parent: Hash) -> Box<dyn Stream<Item=SignedStatement, Error=()>>;
|
||||
}
|
||||
|
||||
impl<P, E> Network for ValidationNetwork<P, E, NetworkService, TaskExecutor> where
|
||||
impl<P, E> Network for ValidationNetwork<P, E, PolkadotNetworkService, TaskExecutor> where
|
||||
P: 'static + Send + Sync,
|
||||
E: 'static + Send + Sync,
|
||||
{
|
||||
@@ -142,7 +142,7 @@ pub trait BuildParachainContext {
|
||||
/// This can be implemented through an externally attached service or a stub.
|
||||
/// This is expected to be a lightweight, shared type like an Arc.
|
||||
pub trait ParachainContext: Clone {
|
||||
type ProduceCandidate: IntoFuture<Item=(BlockData, HeadData, Extrinsic), Error=InvalidHead>;
|
||||
type ProduceCandidate: IntoFuture<Item=(BlockData, HeadData, OutgoingMessages), Error=InvalidHead>;
|
||||
|
||||
/// Produce a candidate, given the relay parent hash, the latest ingress queue information
|
||||
/// and the last parachain head.
|
||||
@@ -177,7 +177,7 @@ pub fn collate<'a, R, P>(
|
||||
para_context: P,
|
||||
key: Arc<CollatorPair>,
|
||||
)
|
||||
-> impl Future<Item=parachain::Collation, Error=Error<R::Error>> + 'a
|
||||
-> impl Future<Item=(parachain::Collation, OutgoingMessages), Error=Error<R::Error>> + 'a
|
||||
where
|
||||
R: RelayChainContext,
|
||||
R::Error: 'a,
|
||||
@@ -197,11 +197,11 @@ pub fn collate<'a, R, P>(
|
||||
.map(move |x| (ingress, x))
|
||||
.map_err(Error::Collator)
|
||||
})
|
||||
.and_then(move |(ingress, (block_data, head_data, mut extrinsic))| {
|
||||
.and_then(move |(ingress, (block_data, head_data, mut outgoing))| {
|
||||
let block_data_hash = block_data.hash();
|
||||
let signature = key.sign(block_data_hash.as_ref()).into();
|
||||
let egress_queue_roots =
|
||||
polkadot_validation::egress_roots(&mut extrinsic.outgoing_messages);
|
||||
polkadot_validation::egress_roots(&mut outgoing.outgoing_messages);
|
||||
|
||||
let receipt = parachain::CandidateReceipt {
|
||||
parachain_index: local_id,
|
||||
@@ -214,19 +214,21 @@ pub fn collate<'a, R, P>(
|
||||
upward_messages: Vec::new(),
|
||||
};
|
||||
|
||||
Ok(parachain::Collation {
|
||||
let collation = parachain::Collation {
|
||||
receipt,
|
||||
pov: PoVBlock {
|
||||
block_data,
|
||||
ingress,
|
||||
},
|
||||
})
|
||||
};
|
||||
|
||||
Ok((collation, outgoing))
|
||||
})
|
||||
}
|
||||
|
||||
/// Polkadot-api context.
|
||||
struct ApiContext<P, E> {
|
||||
network: Arc<ValidationNetwork<P, E, NetworkService, TaskExecutor>>,
|
||||
network: Arc<ValidationNetwork<P, E, PolkadotNetworkService, TaskExecutor>>,
|
||||
parent_hash: Hash,
|
||||
validators: Vec<ValidatorId>,
|
||||
}
|
||||
@@ -243,7 +245,7 @@ impl<P: 'static, E: 'static> RelayChainContext for ApiContext<P, E> where
|
||||
// TODO: https://github.com/paritytech/polkadot/issues/253
|
||||
//
|
||||
// Fetch ingress and accumulate all unrounted egress
|
||||
let _session = self.network.instantiate_session(SessionParams {
|
||||
let _session = self.network.instantiate_leaf_work(LeafWorkParams {
|
||||
local_session_key: None,
|
||||
parent_hash: self.parent_hash,
|
||||
authorities: self.validators.clone(),
|
||||
@@ -303,26 +305,28 @@ impl<P, E> Worker for CollationNode<P, E> where
|
||||
return Box::new(future::err(()));
|
||||
};
|
||||
|
||||
let is_known = move |block_hash: &Hash| {
|
||||
use client::BlockStatus;
|
||||
use polkadot_network::gossip::Known;
|
||||
|
||||
match known_oracle.block_status(&BlockId::hash(*block_hash)) {
|
||||
Err(_) | Ok(BlockStatus::Unknown) | Ok(BlockStatus::Queued) => None,
|
||||
Ok(BlockStatus::KnownBad) => Some(Known::Bad),
|
||||
Ok(BlockStatus::InChainWithState) | Ok(BlockStatus::InChainPruned) =>
|
||||
match select_chain.leaves() {
|
||||
Err(_) => None,
|
||||
Ok(leaves) => if leaves.contains(block_hash) {
|
||||
Some(Known::Leaf)
|
||||
} else {
|
||||
Some(Known::Old)
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let message_validator = polkadot_network::gossip::register_validator(
|
||||
network.clone(),
|
||||
move |block_hash: &Hash| {
|
||||
use client::BlockStatus;
|
||||
use polkadot_network::gossip::Known;
|
||||
|
||||
match known_oracle.block_status(&BlockId::hash(*block_hash)) {
|
||||
Err(_) | Ok(BlockStatus::Unknown) | Ok(BlockStatus::Queued) => None,
|
||||
Ok(BlockStatus::KnownBad) => Some(Known::Bad),
|
||||
Ok(BlockStatus::InChainWithState) | Ok(BlockStatus::InChainPruned) =>
|
||||
match select_chain.leaves() {
|
||||
Err(_) => None,
|
||||
Ok(leaves) => if leaves.contains(block_hash) {
|
||||
Some(Known::Leaf)
|
||||
} else {
|
||||
Some(Known::Old)
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
(is_known, client.clone()),
|
||||
);
|
||||
|
||||
let validation_network = Arc::new(ValidationNetwork::new(
|
||||
@@ -386,13 +390,20 @@ impl<P, E> Worker for CollationNode<P, E> where
|
||||
context,
|
||||
parachain_context,
|
||||
key,
|
||||
).map(move |collation| {
|
||||
network.with_spec(move |spec, ctx| spec.add_local_collation(
|
||||
ctx,
|
||||
relay_parent,
|
||||
targets,
|
||||
collation,
|
||||
));
|
||||
).map(move |(collation, outgoing)| {
|
||||
network.with_spec(move |spec, ctx| {
|
||||
let res = spec.add_local_collation(
|
||||
ctx,
|
||||
relay_parent,
|
||||
targets,
|
||||
collation,
|
||||
outgoing,
|
||||
);
|
||||
|
||||
if let Err(e) = res {
|
||||
warn!("Unable to broadcast local collation: {:?}", e);
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
future::Either::B(collation_work)
|
||||
@@ -450,7 +461,7 @@ pub fn run_collator<P, E>(
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::collections::HashMap;
|
||||
use polkadot_primitives::parachain::{OutgoingMessage, FeeSchedule};
|
||||
use polkadot_primitives::parachain::{TargetedMessage, FeeSchedule};
|
||||
use keyring::Sr25519Keyring;
|
||||
use super::*;
|
||||
|
||||
@@ -475,20 +486,20 @@ mod tests {
|
||||
struct DummyParachainContext;
|
||||
|
||||
impl ParachainContext for DummyParachainContext {
|
||||
type ProduceCandidate = Result<(BlockData, HeadData, Extrinsic), InvalidHead>;
|
||||
type ProduceCandidate = Result<(BlockData, HeadData, OutgoingMessages), InvalidHead>;
|
||||
|
||||
fn produce_candidate<I: IntoIterator<Item=(ParaId, Message)>>(
|
||||
&self,
|
||||
_relay_parent: Hash,
|
||||
_status: ParachainStatus,
|
||||
ingress: I,
|
||||
) -> Result<(BlockData, HeadData, Extrinsic), InvalidHead> {
|
||||
) -> Result<(BlockData, HeadData, OutgoingMessages), InvalidHead> {
|
||||
// send messages right back.
|
||||
Ok((
|
||||
BlockData(vec![1, 2, 3, 4, 5,]),
|
||||
HeadData(vec![9, 9, 9]),
|
||||
Extrinsic {
|
||||
outgoing_messages: ingress.into_iter().map(|(id, msg)| OutgoingMessage {
|
||||
OutgoingMessages {
|
||||
outgoing_messages: ingress.into_iter().map(|(id, msg)| TargetedMessage {
|
||||
target: id,
|
||||
data: msg.0,
|
||||
}).collect(),
|
||||
@@ -542,7 +553,7 @@ mod tests {
|
||||
context.clone(),
|
||||
DummyParachainContext,
|
||||
Arc::new(Sr25519Keyring::Alice.pair().into()),
|
||||
).wait().unwrap();
|
||||
).wait().unwrap().0;
|
||||
|
||||
// ascending order by root.
|
||||
assert_eq!(collation.receipt.egress_queue_roots, vec![(a, root_a), (b, root_b)]);
|
||||
|
||||
Reference in New Issue
Block a user