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

update substrate reference #249

Merged
merged 2 commits into from
May 8, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
116 changes: 57 additions & 59 deletions Cargo.lock

Large diffs are not rendered by default.

34 changes: 20 additions & 14 deletions network/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ use polkadot_primitives::parachain::{
Id as ParaId, BlockData, CollatorId, CandidateReceipt, Collation, PoVBlock,
ConsolidatedIngressRoots,
};
use substrate_network::{PeerId, RequestId, Context, Severity};
use substrate_network::{PeerId, RequestId, Context};
use substrate_network::{message, generic_message};
use substrate_network::specialization::NetworkSpecialization as Specialization;
use substrate_network::StatusMessage as GenericFullStatus;
Expand All @@ -73,6 +73,15 @@ use std::collections::{HashMap, HashSet};
#[cfg(test)]
mod tests;

mod cost {
Copy link
Contributor

Choose a reason for hiding this comment

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

Shouldn't there also be a positive reputation, when good things happen?

Copy link
Member

Choose a reason for hiding this comment

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

Yes. I added this which should be done ASAP: #251

pub(super) const UNEXPECTED_MESSAGE: i32 = -200;
pub(super) const INVALID_FORMAT: i32 = -200;

pub(super) const UNKNOWN_PEER: i32 = -50;
pub(super) const COLLATOR_ALREADY_KNOWN: i32 = -100;
pub(super) const BAD_COLLATION: i32 = -1000;
}

type FullStatus = GenericFullStatus<Block>;

/// Specialization of the network service for the polkadot protocol.
Expand Down Expand Up @@ -352,7 +361,7 @@ impl PolkadotProtocol {
Message::PovBlock(req_id, data) => self.on_pov_block(ctx, who, req_id, data),
Message::BlockData(_req_id, _data) => {
// current block data is never requested bare by the node.
ctx.report_peer(who, Severity::Bad("Peer sent un-requested block data".to_string()));
ctx.report_peer(who, cost::UNEXPECTED_MESSAGE);
}
Message::Collation(relay_parent, collation) => self.on_collation(ctx, who, relay_parent, collation),
Message::CollatorRole(role) => self.on_new_role(ctx, who, role),
Expand All @@ -370,7 +379,7 @@ impl PolkadotProtocol {
};

if !info.claimed_validator {
ctx.report_peer(who, Severity::Bad("Session key broadcasted without setting authority role".to_string()));
ctx.report_peer(who, cost::UNEXPECTED_MESSAGE);
return;
}

Expand Down Expand Up @@ -419,7 +428,7 @@ impl PolkadotProtocol {
self.pending.push(req);
self.dispatch_pending_requests(ctx);
}
None => ctx.report_peer(who, Severity::Bad("Unexpected block data response".to_string())),
None => ctx.report_peer(who, cost::UNEXPECTED_MESSAGE),
}
}

Expand All @@ -436,10 +445,7 @@ impl PolkadotProtocol {
debug!(target: "p_net", "New collator role {:?} from {}", role, who);

if info.validator_keys.as_slice().is_empty() {
ctx.report_peer(
who,
Severity::Bad("Sent collator role without registering first as validator".to_string()),
);
ctx.report_peer(who, cost::UNEXPECTED_MESSAGE);
} else {
// update role for all saved session keys for this validator.
let local_collations = &mut self.local_collations;
Expand Down Expand Up @@ -484,7 +490,7 @@ impl Specialization<Block> for PolkadotProtocol {

if let Some((ref acc_id, ref para_id)) = local_status.collating_for {
if self.collator_peer(acc_id.clone()).is_some() {
ctx.report_peer(who, Severity::Useless("Unknown Polkadot-specific reason".to_string()));
ctx.report_peer(who, cost::COLLATOR_ALREADY_KNOWN);
return
}

Expand Down Expand Up @@ -563,7 +569,7 @@ impl Specialization<Block> for PolkadotProtocol {
Some(msg) => self.on_polkadot_message(ctx, who, msg),
None => {
trace!(target: "p_net", "Bad message from {}", who);
ctx.report_peer(who, Severity::Bad("Invalid polkadot protocol message format".to_string()));
ctx.report_peer(who, cost::INVALID_FORMAT);
*message = Some(generic_message::Message::ChainSpecific(raw));
}
}
Expand Down Expand Up @@ -607,16 +613,16 @@ impl PolkadotProtocol {
let collated_acc = collation.receipt.collator.clone();

match self.peers.get(&from) {
None => ctx.report_peer(from, Severity::Useless("Unknown Polkadot specific reason".to_string())),
None => ctx.report_peer(from, cost::UNKNOWN_PEER),
Some(peer_info) => match peer_info.collating_for {
None => ctx.report_peer(from, Severity::Bad("Sent collation without registering collator intent".to_string())),
None => ctx.report_peer(from, cost::UNEXPECTED_MESSAGE),
Some((ref acc_id, ref para_id)) => {
let structurally_valid = para_id == &collation_para && acc_id == &collated_acc;
if structurally_valid && collation.receipt.check_signature().is_ok() {
debug!(target: "p_net", "Received collation for parachain {:?} from peer {}", para_id, from);
self.collators.on_collation(acc_id.clone(), relay_parent, collation)
} else {
ctx.report_peer(from, Severity::Bad("Sent malformed collation".to_string()))
ctx.report_peer(from, cost::INVALID_FORMAT)
};
}
},
Expand Down Expand Up @@ -647,7 +653,7 @@ impl PolkadotProtocol {
// disconnect a collator by account-id.
fn disconnect_bad_collator(&mut self, ctx: &mut Context<Block>, collator_id: CollatorId) {
if let Some((who, _)) = self.collator_peer(collator_id) {
ctx.report_peer(who, Severity::Bad("Consensus layer determined the given collator misbehaved".to_string()))
ctx.report_peer(who, cost::BAD_COLLATION)
}
}
}
Expand Down
15 changes: 9 additions & 6 deletions network/src/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use polkadot_primitives::parachain::{
use substrate_primitives::crypto::UncheckedInto;
use codec::Encode;
use substrate_network::{
Severity, PeerId, PeerInfo, ClientHandle, Context, config::Roles,
PeerId, PeerInfo, ClientHandle, Context, config::Roles,
message::{BlockRequest, generic::ConsensusMessage},
specialization::NetworkSpecialization, generic_message::Message as GenericMessage
};
Expand All @@ -49,10 +49,11 @@ impl Context<Block> for TestContext {
unimplemented!()
}

fn report_peer(&mut self, peer: PeerId, reason: Severity) {
match reason {
Severity::Bad(_) => self.disabled.push(peer),
_ => self.disconnected.push(peer),
fn report_peer(&mut self, peer: PeerId, reputation: i32) {
match reputation {
i if i < -100 => self.disabled.push(peer),
i if i < 0 => self.disconnected.push(peer),
_ => {}
}
}

Expand All @@ -68,9 +69,11 @@ impl Context<Block> for TestContext {
unimplemented!()
}

fn send_chain_specific(&mut self, who: PeerId, message: Vec<u8>){
fn send_chain_specific(&mut self, who: PeerId, message: Vec<u8>) {
self.messages.push((who, message))
}

fn disconnect_peer(&mut self, _who: PeerId) { }
}

impl TestContext {
Expand Down
22 changes: 18 additions & 4 deletions runtime/src/curated_grandpa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,29 @@ decl_module! {
if shuffle_period == 0 { return }

if block_number.as_() % shuffle_period == 0 {
let mut seed = system::Module::<T>::random_seed().as_ref().to_vec();
seed.extend(b"grandpa_shuffling");
let mut seed = BlakeTwo256::hash(&seed);

let mut voters = grandpa::Module::<T>::grandpa_authorities();
let voter_count = voters.len();

if voter_count == 0 { return }

let mut seed = {
let phrase = b"grandpa_shuffling";
let seed = system::Module::<T>::random(&phrase[..]);
let seed_len = seed.as_ref().len();
let needed_bytes = voter_count * 4;

// hash only the needed bits of the random seed.
// if earlier bits are influencable, they will not factor into
// the seed used here.
let seed_off = if needed_bytes >= seed_len {
0
} else {
seed_len - needed_bytes
};

BlakeTwo256::hash(&seed.as_ref()[seed_off..])
};

for i in 0..(voter_count - 1) {
// 4 bytes of entropy used per cycle, 32 bytes entropy per hash
let offset = (i * 4 % 32) as usize;
Expand Down
35 changes: 21 additions & 14 deletions runtime/src/parachains.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,9 +208,24 @@ impl<T: Trait> Module<T> {
_ => Chain::Relay,
}).collect::<Vec<_>>();

let mut random_seed = system::Module::<T>::random_seed().as_ref().to_vec();
random_seed.extend(b"validator_role_pairs");
let mut seed = BlakeTwo256::hash(&random_seed);

let mut seed = {
let phrase = b"validator_role_pairs";
let seed = system::Module::<T>::random(&phrase[..]);
let seed_len = seed.as_ref().len();
let needed_bytes = validator_count * 4;

// hash only the needed bits of the random seed.
// if earlier bits are influencable, they will not factor into
// the seed used here.
let seed_off = if needed_bytes >= seed_len {
0
} else {
seed_len - needed_bytes
};

BlakeTwo256::hash(&seed.as_ref()[seed_off..])
};

// shuffle
for i in 0..(validator_count - 1) {
Expand Down Expand Up @@ -504,6 +519,7 @@ mod tests {
impl Trait for Test {}

type Parachains = Module<Test>;
type System = system::Module<Test>;

fn new_test_ext(parachains: Vec<(ParaId, Vec<u8>, Vec<u8>)>) -> TestExternalities<Blake2Hasher> {
let mut t = system::GenesisConfig::<Test>::default().build_storage().unwrap().0;
Expand Down Expand Up @@ -653,17 +669,16 @@ mod tests {
assert_eq!(duty_roster.validator_duty.iter().filter(|&&j| j == Chain::Relay).count(), 2);
};

system::Module::<Test>::set_random_seed([0u8; 32].into());
let duty_roster_0 = Parachains::calculate_duty_roster();
check_roster(&duty_roster_0);

system::Module::<Test>::set_random_seed([1u8; 32].into());
System::initialize(&1, &H256::from([1; 32]), &Default::default());
let duty_roster_1 = Parachains::calculate_duty_roster();
check_roster(&duty_roster_1);
assert!(duty_roster_0 != duty_roster_1);


system::Module::<Test>::set_random_seed([2u8; 32].into());
System::initialize(&2, &H256::from([2; 32]), &Default::default());
let duty_roster_2 = Parachains::calculate_duty_roster();
check_roster(&duty_roster_2);
assert!(duty_roster_0 != duty_roster_2);
Expand All @@ -679,7 +694,6 @@ mod tests {
];

with_externalities(&mut new_test_ext(parachains), || {
system::Module::<Test>::set_random_seed([0u8; 32].into());
let candidate = AttestedCandidate {
validity_votes: vec![],
candidate: CandidateReceipt {
Expand Down Expand Up @@ -707,7 +721,6 @@ mod tests {
];

with_externalities(&mut new_test_ext(parachains), || {
system::Module::<Test>::set_random_seed([0u8; 32].into());
let mut candidate_a = AttestedCandidate {
validity_votes: vec![],
candidate: CandidateReceipt {
Expand Down Expand Up @@ -759,7 +772,6 @@ mod tests {
];

with_externalities(&mut new_test_ext(parachains), || {
system::Module::<Test>::set_random_seed([0u8; 32].into());
let mut candidate = AttestedCandidate {
validity_votes: vec![],
candidate: CandidateReceipt {
Expand Down Expand Up @@ -795,7 +807,6 @@ mod tests {
];

with_externalities(&mut new_test_ext(parachains), || {
system::Module::<Test>::set_random_seed([0u8; 32].into());
let from_a = vec![(1.into(), [1; 32].into())];
let mut candidate_a = AttestedCandidate {
validity_votes: vec![],
Expand Down Expand Up @@ -865,7 +876,6 @@ mod tests {
];

with_externalities(&mut new_test_ext(parachains), || {
system::Module::<Test>::set_random_seed([0u8; 32].into());
// parachain 99 does not exist
let non_existent = vec![(99.into(), [1; 32].into())];
let mut candidate = new_candidate_with_egress_roots(non_existent);
Expand All @@ -890,7 +900,6 @@ mod tests {
];

with_externalities(&mut new_test_ext(parachains), || {
system::Module::<Test>::set_random_seed([0u8; 32].into());
// parachain 0 is self
let to_self = vec![(0.into(), [1; 32].into())];
let mut candidate = new_candidate_with_egress_roots(to_self);
Expand All @@ -915,7 +924,6 @@ mod tests {
];

with_externalities(&mut new_test_ext(parachains), || {
system::Module::<Test>::set_random_seed([0u8; 32].into());
// parachain 0 is self
let out_of_order = vec![(1.into(), [1; 32].into()), ((0.into(), [1; 32].into()))];
let mut candidate = new_candidate_with_egress_roots(out_of_order);
Expand All @@ -940,7 +948,6 @@ mod tests {
];

with_externalities(&mut new_test_ext(parachains), || {
system::Module::<Test>::set_random_seed([0u8; 32].into());
// parachain 0 is self
let contains_empty_trie_root = vec![(1.into(), [1; 32].into()), ((2.into(), EMPTY_TRIE_ROOT.into()))];
let mut candidate = new_candidate_with_egress_roots(contains_empty_trie_root);
Expand Down
Loading