Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

ICMP message-routing gossip #304

Merged
merged 39 commits into from
Aug 29, 2019
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
207e5b6
core logic for ICMP gossip
rphmeier Jun 27, 2019
360c729
refactor gossip to make more extension friendly
rphmeier Jun 27, 2019
9922f02
move files aroun
rphmeier Jun 27, 2019
0125f18
extract attestation-gossip logic to its own module
rphmeier Jun 27, 2019
5e25763
Merge branch 'master' into rh-icmp-gossip-primitives
rphmeier Jul 24, 2019
3a4bd99
message validation and broadcast logic
rphmeier Jul 26, 2019
9e76e36
fix upstream crates' compilation
rphmeier Jul 28, 2019
65bbe33
add a test
rphmeier Jul 28, 2019
e9e6032
another test for overlapping
rphmeier Jul 30, 2019
a192da1
Some grammar and phrasing tweaks
rphmeier Aug 2, 2019
8d4e67b
Merge branch 'master' into rh-icmp-gossip-primitives
rphmeier Aug 8, 2019
63f26b0
add since parameter to ingress runtime API
rphmeier Aug 9, 2019
ec7d9de
broadcast out known unrouted message queues
rphmeier Aug 9, 2019
bdc213e
fix compilation of service and collator
rphmeier Aug 9, 2019
cfa47b8
Merge branch 'rh-icmp-gossip-primitives' of github.com:paritytech/pol…
rphmeier Aug 9, 2019
b38b712
remove useless index_mapping
rphmeier Aug 9, 2019
727b92c
Merge branch 'master' into rh-icmp-gossip-primitives
rphmeier Aug 12, 2019
6a9269d
some tests for icmp propagation
rphmeier Aug 12, 2019
ced6186
fix decoding bug and test icmp queue validation
rphmeier Aug 12, 2019
a2ea950
simplify engine-id definition
rphmeier Aug 14, 2019
158942e
address some grumbles
rphmeier Aug 14, 2019
a5b5591
some cleanup of old circulation code
rphmeier Aug 14, 2019
251cf2f
give network a handle to extrinsic store on startup
rphmeier Aug 14, 2019
14c58fd
an honest collator ensures data available as well
rphmeier Aug 14, 2019
0cec9da
address some grumbles
rphmeier Aug 14, 2019
e427fd9
add docs; rename the attestation session to "leaf work"
rphmeier Aug 14, 2019
3d8df1f
module docs
rphmeier Aug 14, 2019
8e6ef2c
move gossip back to gossip.rs
rphmeier Aug 15, 2019
02ecf76
clean up and document attestation-gossip a bit
rphmeier Aug 15, 2019
5ccf536
some more docs on the availability store
rphmeier Aug 15, 2019
acc36af
store all outgoing message queues in the availability store
rphmeier Aug 15, 2019
d736ea3
filter `Extrinsic` out of validation crate
rphmeier Aug 15, 2019
bded179
expunge Extrinsic from network
rphmeier Aug 15, 2019
ad31039
expunge Extrinsic from erasure-coding
rphmeier Aug 15, 2019
550c4fd
expunge Extrinsic from collator
rphmeier Aug 15, 2019
7a82f33
expunge from adder-collator
rphmeier Aug 15, 2019
e900307
rename ExtrinsicStore to AvailabilityStore everywhere
rphmeier Aug 15, 2019
093a912
annotate and clean up message-routing tests
rphmeier Aug 15, 2019
bba4c5a
Merge branch 'master' into rh-icmp-gossip-primitives
rphmeier Aug 29, 2019
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
79 changes: 71 additions & 8 deletions availability-store/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,16 @@ pub struct Config {
pub path: PathBuf,
}

/// A record containing information about parachain extrinsic data to store.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is "parachain extrinsic data"? a set_heads call? a single extrinsic of a parachain? what about parachains that don't have single extrinsics?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a piece of terminology we had since before Substrate, which essentially refers to the outgoing messages of the parachain, which has to remain available along with the block-data.

After Substrate introduced Extrinsics, this naming became more confusing.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe rename to IntermediateData or even just MessageData?

pub struct StoredExtrinsic {
/// The actual extrinsic data.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Terms highly confusing now; definitely suggest a blanket rename.

pub inner: Extrinsic,
/// The queue root of the `outgoing_messages` member of `inner`.
///
/// The responsibility is on the creator to set this correctly.
pub message_queue_root: Hash,
}

/// Some data to keep available.
pub struct Data {
/// The relay chain parent hash this should be localized to.
Expand All @@ -53,7 +63,7 @@ pub struct Data {
/// Block data.
pub block_data: BlockData,
/// Extrinsic data.
pub extrinsic: Option<Extrinsic>,
pub extrinsic: Option<StoredExtrinsic>,
}

fn block_data_key(relay_parent: &Hash, candidate_hash: &Hash) -> Vec<u8> {
Expand Down Expand Up @@ -119,10 +129,17 @@ impl Store {
);

if let Some(extrinsic) = data.extrinsic {
let encoded = extrinsic.inner.encode();
tx.put_vec(
columns::DATA,
extrinsic_key(&data.relay_parent, &data.candidate_hash).as_slice(),
extrinsic.encode(),
encoded.clone(),
);

tx.put_vec(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this is storing the message data ready for some later recall under some circumstances? If those circumstances are not already documented, maybe put them here. If they are then a pointer to them somewhere near here would be most useful for anyone coming to this code.

columns::DATA,
extrinsic.message_queue_root.as_ref(),
encoded,
);
}

Expand Down Expand Up @@ -168,10 +185,8 @@ impl Store {
}
}

/// Query extrinsic data.
pub fn extrinsic(&self, relay_parent: Hash, candidate_hash: Hash) -> Option<Extrinsic> {
let encoded_key = extrinsic_key(&relay_parent, &candidate_hash);
match self.inner.get(columns::DATA, &encoded_key[..]) {
fn extrinsic_with_key(&self, key: &[u8]) -> Option<Extrinsic> {
match self.inner.get(columns::DATA, key) {
Ok(Some(raw)) => Some(
Extrinsic::decode(&mut &raw[..]).expect("all stored data serialized correctly; qed")
),
Expand All @@ -182,11 +197,23 @@ impl Store {
}
}
}

/// Query extrinsic data by relay parent and candidate hash.
pub fn extrinsic(&self, relay_parent: Hash, candidate_hash: Hash) -> Option<Extrinsic> {
let encoded_key = extrinsic_key(&relay_parent, &candidate_hash);
self.extrinsic_with_key(&encoded_key[..])
}

/// Query extrinsic data by message queue root hash.
pub fn extrinsic_by_queue_root(&self, queue_root: &Hash) -> Option<Extrinsic> {
self.extrinsic_with_key(queue_root.as_ref())
}
}

#[cfg(test)]
mod tests {
use super::*;
use polkadot_primitives::parachain::OutgoingMessage;

#[test]
fn finalization_removes_unneeded() {
Expand All @@ -207,15 +234,21 @@ mod tests {
parachain_id: para_id_1,
candidate_hash: candidate_1,
block_data: block_data_1.clone(),
extrinsic: Some(Extrinsic { outgoing_messages: Vec::new() }),
extrinsic: Some(StoredExtrinsic {
inner: Extrinsic { outgoing_messages: Vec::new() },
message_queue_root: Default::default(),
}),
}).unwrap();

store.make_available(Data {
relay_parent,
parachain_id: para_id_2,
candidate_hash: candidate_2,
block_data: block_data_2.clone(),
extrinsic: Some(Extrinsic { outgoing_messages: Vec::new() }),
extrinsic: Some(StoredExtrinsic {
inner: Extrinsic { outgoing_messages: Vec::new() },
message_queue_root: Default::default(),
}),
}).unwrap();

assert_eq!(store.block_data(relay_parent, candidate_1).unwrap(), block_data_1);
Expand All @@ -232,4 +265,34 @@ mod tests {
assert!(store.extrinsic(relay_parent, candidate_1).is_some());
assert!(store.extrinsic(relay_parent, candidate_2).is_none());
}

#[test]
fn extrinsic_available_by_queue_root() {
let relay_parent = [1; 32].into();
let para_id = 5.into();
let candidate = [2; 32].into();
let block_data = BlockData(vec![1, 2, 3]);

let outgoing_messages = vec![
OutgoingMessage { target: 1.into(), data: vec![1, 2, 3, 4] },
OutgoingMessage { target: 2.into(), data: vec![5, 6, 7, 8] },
];
let ex = Extrinsic { outgoing_messages };

let message_queue_root = [0x42; 32].into();

let store = Store::new_in_memory();
store.make_available(Data {
relay_parent,
parachain_id: para_id,
candidate_hash: candidate,
block_data: block_data.clone(),
extrinsic: Some(StoredExtrinsic {
inner: ex.clone(),
message_queue_root,
}),
}).unwrap();

assert_eq!(store.extrinsic_by_queue_root(&message_queue_root), Some(ex));
}
}
44 changes: 23 additions & 21 deletions collator/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ use polkadot_cli::{
ParachainHost,
};
use polkadot_network::validation::{SessionParams, ValidationNetwork};
use polkadot_network::NetworkService;
use polkadot_network::PolkadotNetworkService;
use tokio::timer::Timeout;
use consensus_common::SelectChain;

Expand All @@ -92,7 +92,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,
{
Expand Down Expand Up @@ -227,7 +227,7 @@ pub fn collate<'a, R, P>(

/// 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>,
}
Expand Down Expand Up @@ -301,26 +301,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(
Expand Down
2 changes: 1 addition & 1 deletion network/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ sr-primitives = { git = "https://github.com/paritytech/substrate", branch = "pol
futures = "0.1"
log = "0.4"
exit-future = "0.1.4"
substrate-client = { git = "https://github.com/paritytech/substrate", branch = "polkadot-master" }

[dev-dependencies]
substrate-client = { git = "https://github.com/paritytech/substrate", branch = "polkadot-master" }
substrate-keyring = { git = "https://github.com/paritytech/substrate", branch = "polkadot-master" }
Loading