Commit 4cb0346c authored by Arkadiy Paronyan's avatar Arkadiy Paronyan Committed by Gavin Wood
Browse files

Update for new peerset API (#644)

* Reputation changes require reason

* Fixes

* Bump version
parent e0a7e280
This diff is collapsed.
......@@ -4,7 +4,7 @@ path = "src/main.rs"
[package]
name = "polkadot"
version = "0.7.3"
version = "0.7.4"
authors = ["Parity Technologies <admin@parity.io>"]
build = "build.rs"
edition = "2018"
......
[package]
name = "polkadot-availability-store"
description = "Persistent database for parachain data"
version = "0.7.3"
version = "0.7.4"
authors = ["Parity Technologies <admin@parity.io>"]
edition = "2018"
......
[package]
name = "polkadot-cli"
version = "0.7.3"
version = "0.7.4"
authors = ["Parity Technologies <admin@parity.io>"]
description = "Polkadot node implementation in Rust."
edition = "2018"
......
[package]
name = "polkadot-collator"
version = "0.7.3"
version = "0.7.4"
authors = ["Parity Technologies <admin@parity.io>"]
description = "Collator node implementation"
edition = "2018"
......
[package]
name = "polkadot-erasure-coding"
version = "0.7.3"
version = "0.7.4"
authors = ["Parity Technologies <admin@parity.io>"]
edition = "2018"
......
[package]
name = "polkadot-executor"
version = "0.7.3"
version = "0.7.4"
authors = ["Parity Technologies <admin@parity.io>"]
description = "Polkadot node implementation in Rust."
edition = "2018"
......
[package]
name = "polkadot-network"
version = "0.7.3"
version = "0.7.4"
authors = ["Parity Technologies <admin@parity.io>"]
description = "Polkadot-specific networking protocol"
edition = "2018"
......
......@@ -51,7 +51,7 @@
use sp_runtime::{generic::BlockId, traits::ProvideRuntimeApi};
use sp_blockchain::Error as ClientError;
use sc_network::{config::Roles, PeerId};
use sc_network::{config::Roles, PeerId, ReputationChange};
use sc_network::consensus_gossip::{
self as network_gossip, ValidationResult as GossipValidationResult,
ValidatorContext, MessageIntent, ConsensusMessage,
......@@ -87,35 +87,39 @@ pub(crate) const MAX_CHAIN_HEADS: usize = 5;
pub type LeavesVec = ArrayVec<[Hash; MAX_CHAIN_HEADS]>;
mod benefit {
use sc_network::ReputationChange as Rep;
/// When a peer sends us a previously-unknown candidate statement.
pub const NEW_CANDIDATE: i32 = 100;
pub const NEW_CANDIDATE: Rep = Rep::new(100, "Polkadot: New candidate");
/// When a peer sends us a previously-unknown attestation.
pub const NEW_ATTESTATION: i32 = 50;
pub const NEW_ATTESTATION: Rep = Rep::new(50, "Polkadot: New attestation");
/// When a peer sends us a previously-unknown message packet.
pub const NEW_ICMP_MESSAGES: i32 = 50;
pub const NEW_ICMP_MESSAGES: Rep = Rep::new(50, "Polkadot: New ICMP messages");
}
mod cost {
use sc_network::ReputationChange as Rep;
/// No cost. This will not be reported.
pub const NONE: Rep = Rep::new(0, "");
/// A peer sent us an attestation and we don't know the candidate.
pub const ATTESTATION_NO_CANDIDATE: i32 = -100;
pub const ATTESTATION_NO_CANDIDATE: Rep = Rep::new(-100, "Polkadot: No candidate");
/// A peer sent us a statement we consider in the future.
pub const FUTURE_MESSAGE: i32 = -100;
pub const FUTURE_MESSAGE: Rep = Rep::new(-100, "Polkadot: Future message");
/// A peer sent us a statement from the past.
pub const PAST_MESSAGE: i32 = -30;
pub const PAST_MESSAGE: Rep = Rep::new(-30, "Polkadot: Past message");
/// A peer sent us a malformed message.
pub const MALFORMED_MESSAGE: i32 = -500;
pub const MALFORMED_MESSAGE: Rep = Rep::new(-500, "Polkadot: Malformed message");
/// A peer sent us a wrongly signed message.
pub const BAD_SIGNATURE: i32 = -500;
pub const BAD_SIGNATURE: Rep = Rep::new(-500, "Polkadot: Bad signature");
/// A peer sent us a bad neighbor packet.
pub const BAD_NEIGHBOR_PACKET: i32 = -300;
pub const BAD_NEIGHBOR_PACKET: Rep = Rep::new(-300, "Polkadot: Bad neighbor");
/// A peer sent us an ICMP queue we haven't advertised a need for.
pub const UNNEEDED_ICMP_MESSAGES: i32 = -100;
pub const UNNEEDED_ICMP_MESSAGES: Rep = Rep::new(-100, "Polkadot: Unexpected ICMP message");
/// A peer sent us an ICMP queue with a bad root.
pub fn icmp_messages_root_mismatch(n_messages: usize) -> i32 {
pub fn icmp_messages_root_mismatch(n_messages: usize) -> Rep {
const PER_MESSAGE: i32 = -150;
(0..n_messages).map(|_| PER_MESSAGE).sum()
Rep::new((0..n_messages).map(|_| PER_MESSAGE).sum(), "Polkadot: ICMP root mismatch")
}
}
......@@ -288,8 +292,10 @@ pub fn register_validator<C: ChainContext + 'static>(
) -> RegisteredMessageValidator
{
let s = service.clone();
let report_handle = Box::new(move |peer: &PeerId, cost_benefit| {
s.report_peer(peer.clone(), cost_benefit);
let report_handle = Box::new(move |peer: &PeerId, cost_benefit: ReputationChange| {
if cost_benefit.value != 0 {
s.report_peer(peer.clone(), cost_benefit);
}
});
let validator = Arc::new(MessageValidator {
report_handle,
......@@ -355,7 +361,7 @@ impl RegisteredMessageValidator {
#[cfg(test)]
pub(crate) fn new_test<C: ChainContext + 'static>(
chain: C,
report_handle: Box<dyn Fn(&PeerId, i32) + Send + Sync>,
report_handle: Box<dyn Fn(&PeerId, ReputationChange) + Send + Sync>,
) -> Self {
let validator = Arc::new(MessageValidator::new_test(chain, report_handle));
......@@ -474,7 +480,7 @@ struct Inner<C: ?Sized> {
impl<C: ?Sized + ChainContext> Inner<C> {
fn validate_neighbor_packet(&mut self, sender: &PeerId, packet: NeighborPacket)
-> (GossipValidationResult<Hash>, i32, Vec<Hash>)
-> (GossipValidationResult<Hash>, ReputationChange, Vec<Hash>)
{
let chain_heads = packet.chain_heads;
if chain_heads.len() > MAX_CHAIN_HEADS {
......@@ -494,7 +500,7 @@ impl<C: ?Sized + ChainContext> Inner<C> {
Vec::new()
};
(GossipValidationResult::Discard, 0, new_topics)
(GossipValidationResult::Discard, cost::NONE, new_topics)
}
}
......@@ -514,7 +520,7 @@ impl<C: ?Sized + ChainContext> Inner<C> {
/// An unregistered message validator. Register this with `register_validator`.
pub struct MessageValidator<C: ?Sized> {
report_handle: Box<dyn Fn(&PeerId, i32) + Send + Sync>,
report_handle: Box<dyn Fn(&PeerId, ReputationChange) + Send + Sync>,
inner: RwLock<Inner<C>>,
}
......@@ -522,7 +528,7 @@ impl<C: ChainContext + ?Sized> MessageValidator<C> {
#[cfg(test)]
fn new_test(
chain: C,
report_handle: Box<dyn Fn(&PeerId, i32) + Send + Sync>,
report_handle: Box<dyn Fn(&PeerId, ReputationChange) + Send + Sync>,
) -> Self where C: Sized {
MessageValidator {
report_handle,
......@@ -535,7 +541,7 @@ impl<C: ChainContext + ?Sized> MessageValidator<C> {
}
}
fn report(&self, who: &PeerId, cost_benefit: i32) {
fn report(&self, who: &PeerId, cost_benefit: ReputationChange) {
(self.report_handle)(who, cost_benefit)
}
}
......@@ -720,7 +726,7 @@ mod tests {
fn message_allowed() {
let (tx, _rx) = mpsc::channel();
let tx = Mutex::new(tx);
let report_handle = Box::new(move |peer: &PeerId, cb: i32| tx.lock().send((peer.clone(), cb)).unwrap());
let report_handle = Box::new(move |peer: &PeerId, cb: ReputationChange| tx.lock().send((peer.clone(), cb)).unwrap());
let validator = MessageValidator::new_test(
TestChainContext::default(),
report_handle,
......@@ -803,7 +809,7 @@ mod tests {
fn too_many_chain_heads_is_report() {
let (tx, rx) = mpsc::channel();
let tx = Mutex::new(tx);
let report_handle = Box::new(move |peer: &PeerId, cb: i32| tx.lock().send((peer.clone(), cb)).unwrap());
let report_handle = Box::new(move |peer: &PeerId, cb: ReputationChange| tx.lock().send((peer.clone(), cb)).unwrap());
let validator = MessageValidator::new_test(
TestChainContext::default(),
report_handle,
......@@ -845,7 +851,7 @@ mod tests {
fn statement_only_sent_when_candidate_known() {
let (tx, _rx) = mpsc::channel();
let tx = Mutex::new(tx);
let report_handle = Box::new(move |peer: &PeerId, cb: i32| tx.lock().send((peer.clone(), cb)).unwrap());
let report_handle = Box::new(move |peer: &PeerId, cb: ReputationChange| tx.lock().send((peer.clone(), cb)).unwrap());
let validator = MessageValidator::new_test(
TestChainContext::default(),
report_handle,
......@@ -922,7 +928,7 @@ mod tests {
fn multicasts_icmp_queues_when_building_on_new_leaf() {
let (tx, _rx) = mpsc::channel();
let tx = Mutex::new(tx);
let report_handle = Box::new(move |peer: &PeerId, cb: i32| tx.lock().send((peer.clone(), cb)).unwrap());
let report_handle = Box::new(move |peer: &PeerId, cb: ReputationChange| tx.lock().send((peer.clone(), cb)).unwrap());
let hash_a = [1u8; 32].into();
let root_a = [11u8; 32].into();
......@@ -1017,7 +1023,7 @@ mod tests {
fn multicasts_icmp_queues_on_neighbor_update() {
let (tx, _rx) = mpsc::channel();
let tx = Mutex::new(tx);
let report_handle = Box::new(move |peer: &PeerId, cb: i32| tx.lock().send((peer.clone(), cb)).unwrap());
let report_handle = Box::new(move |peer: &PeerId, cb: ReputationChange| tx.lock().send((peer.clone(), cb)).unwrap());
let hash_a = [1u8; 32].into();
let root_a = [11u8; 32].into();
......@@ -1128,7 +1134,7 @@ mod tests {
fn accepts_needed_unknown_icmp_message_queue() {
let (tx, _rx) = mpsc::channel();
let tx = Mutex::new(tx);
let report_handle = Box::new(move |peer: &PeerId, cb: i32| tx.lock().send((peer.clone(), cb)).unwrap());
let report_handle = Box::new(move |peer: &PeerId, cb: ReputationChange| tx.lock().send((peer.clone(), cb)).unwrap());
let hash_a = [1u8; 32].into();
let root_a_messages = vec![
......
......@@ -31,6 +31,7 @@
//! consider an infinite amount of attestations produced by a misbehaving validator.
use sc_network::consensus_gossip::{ValidationResult as GossipValidationResult};
use sc_network::ReputationChange;
use polkadot_validation::GenericStatement;
use polkadot_primitives::Hash;
......@@ -39,7 +40,9 @@ use std::collections::{HashMap, HashSet};
use log::warn;
use crate::router::attestation_topic;
use super::{cost, benefit, MAX_CHAIN_HEADS, LeavesVec, ChainContext, Known, MessageValidationData, GossipStatement};
use super::{cost, benefit, MAX_CHAIN_HEADS, LeavesVec,
ChainContext, Known, MessageValidationData, GossipStatement
};
// knowledge about attestations on a single parent-hash.
#[derive(Default)]
......@@ -170,7 +173,7 @@ impl View {
message: GossipStatement,
chain: &C,
)
-> (GossipValidationResult<Hash>, i32)
-> (GossipValidationResult<Hash>, ReputationChange)
{
// message must reference one of our chain heads and
// if message is not a `Candidate` we should have the candidate available
......@@ -184,8 +187,7 @@ impl View {
"Leaf block {} not considered live for attestation",
message.relay_chain_leaf,
);
0
cost::NONE
}
Some(Known::Old) => cost::PAST_MESSAGE,
_ => cost::FUTURE_MESSAGE,
......
......@@ -133,7 +133,7 @@ impl View {
/// Validate an incoming message queue against this view. If it is accepted
/// by our view of un-routed message queues, we will keep and re-propagate.
pub fn validate_queue_and_note_known(&mut self, messages: &super::GossipParachainMessages)
-> (GossipValidationResult<Hash>, i32)
-> (GossipValidationResult<Hash>, sc_network::ReputationChange)
{
let ostensible_topic = queue_topic(messages.queue_root);
match self.expected_queues.get_mut(&ostensible_topic) {
......
......@@ -54,23 +54,26 @@ use crate::gossip::{POLKADOT_ENGINE_ID, GossipMessage};
mod tests;
mod cost {
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;
pub(super) const BAD_POV_BLOCK: i32 = -1000;
use sc_network::ReputationChange as Rep;
pub(super) const UNEXPECTED_MESSAGE: Rep = Rep::new(-200, "Polkadot: Unexpected message");
pub(super) const UNEXPECTED_ROLE: Rep = Rep::new(-200, "Polkadot: Unexpected role");
pub(super) const INVALID_FORMAT: Rep = Rep::new(-200, "Polkadot: Bad message");
pub(super) const UNKNOWN_PEER: Rep = Rep::new(-50, "Polkadot: Unknown peer");
pub(super) const COLLATOR_ALREADY_KNOWN: Rep = Rep::new( -100, "Polkadot: Known collator");
pub(super) const BAD_COLLATION: Rep = Rep::new(-1000, "Polkadot: Bad collation");
pub(super) const BAD_POV_BLOCK: Rep = Rep::new(-1000, "Polkadot: Bad POV block");
}
mod benefit {
pub(super) const EXPECTED_MESSAGE: i32 = 20;
pub(super) const VALID_FORMAT: i32 = 20;
pub(super) const KNOWN_PEER: i32 = 5;
pub(super) const NEW_COLLATOR: i32 = 10;
pub(super) const GOOD_COLLATION: i32 = 100;
pub(super) const GOOD_POV_BLOCK: i32 = 100;
use sc_network::ReputationChange as Rep;
pub(super) const EXPECTED_MESSAGE: Rep = Rep::new(20, "Polkadot: Expected message");
pub(super) const VALID_FORMAT: Rep = Rep::new(20, "Polkadot: Valid message format");
pub(super) const KNOWN_PEER: Rep = Rep::new(5, "Polkadot: Known peer");
pub(super) const NEW_COLLATOR: Rep = Rep::new(10, "Polkadot: New collator");
pub(super) const GOOD_COLLATION: Rep = Rep::new(100, "Polkadot: Good collation");
pub(super) const GOOD_POV_BLOCK: Rep = Rep::new(100, "Polkadot: Good POV block");
}
type FullStatus = GenericFullStatus<Block>;
......@@ -553,7 +556,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, cost::UNEXPECTED_MESSAGE);
ctx.report_peer(who, cost::UNEXPECTED_ROLE)
} else {
// update role for all saved session keys for this validator.
let local_collations = &mut self.local_collations;
......
......@@ -29,7 +29,7 @@ use polkadot_primitives::parachain::{
use sp_core::crypto::UncheckedInto;
use codec::Encode;
use sc_network::{
PeerId, Context, config::Roles, message::generic::ConsensusMessage,
PeerId, Context, ReputationChange, config::Roles, message::generic::ConsensusMessage,
specialization::NetworkSpecialization,
};
......@@ -46,8 +46,8 @@ struct TestContext {
}
impl Context<Block> for TestContext {
fn report_peer(&mut self, peer: PeerId, reputation: i32) {
let reputation = self.reputations.get(&peer).map_or(reputation, |v| v + reputation);
fn report_peer(&mut self, peer: PeerId, reputation: ReputationChange) {
let reputation = self.reputations.get(&peer).map_or(reputation.value, |v| v + reputation.value);
self.reputations.insert(peer.clone(), reputation);
match reputation {
......
[package]
name = "polkadot-parachain"
version = "0.7.3"
version = "0.7.4"
authors = ["Parity Technologies <admin@parity.io>"]
description = "Types and utilities for creating and working with parachains"
edition = "2018"
......
[package]
name = "polkadot-primitives"
version = "0.7.3"
version = "0.7.4"
authors = ["Parity Technologies <admin@parity.io>"]
edition = "2018"
......
[package]
name = "polkadot-rpc"
version = "0.7.3"
version = "0.7.4"
authors = ["Parity Technologies <admin@parity.io>"]
edition = "2018"
......
[package]
name = "polkadot-runtime"
version = "0.7.3"
version = "0.7.4"
authors = ["Parity Technologies <admin@parity.io>"]
edition = "2018"
build = "build.rs"
......
......@@ -97,7 +97,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
spec_name: create_runtime_str!("kusama"),
impl_name: create_runtime_str!("parity-kusama"),
authoring_version: 2,
spec_version: 1024,
spec_version: 1025,
impl_version: 0,
apis: RUNTIME_API_VERSIONS,
};
......
[package]
name = "polkadot-service"
version = "0.7.3"
version = "0.7.4"
authors = ["Parity Technologies <admin@parity.io>"]
edition = "2018"
......
[package]
name = "polkadot-statement-table"
version = "0.7.3"
version = "0.7.4"
authors = ["Parity Technologies <admin@parity.io>"]
edition = "2018"
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment