// Copyright 2019-2020 Parity Technologies (UK) Ltd.
// This file is part of Substrate.
// Substrate is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Substrate is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Substrate. If not, see .
//! Tests for the communication portion of the GRANDPA crate.
use sp_utils::mpsc::{tracing_unbounded, TracingUnboundedReceiver, TracingUnboundedSender};
use futures::prelude::*;
use sc_network::{Event as NetworkEvent, ObservedRole, PeerId};
use sc_network_test::{Block, Hash};
use sc_network_gossip::Validator;
use std::sync::Arc;
use sp_keyring::Ed25519Keyring;
use parity_scale_codec::Encode;
use sp_runtime::{ConsensusEngineId, traits::NumberFor};
use std::{borrow::Cow, pin::Pin, task::{Context, Poll}};
use crate::environment::SharedVoterSetState;
use sp_finality_grandpa::{AuthorityList, GRANDPA_ENGINE_ID};
use super::gossip::{self, GossipValidator};
use super::{AuthorityId, VoterSet, Round, SetId};
#[derive(Debug)]
pub(crate) enum Event {
EventStream(TracingUnboundedSender),
WriteNotification(sc_network::PeerId, Vec),
Report(sc_network::PeerId, sc_network::ReputationChange),
Announce(Hash),
}
#[derive(Clone)]
pub(crate) struct TestNetwork {
sender: TracingUnboundedSender,
}
impl sc_network_gossip::Network for TestNetwork {
fn event_stream(&self) -> Pin + Send>> {
let (tx, rx) = tracing_unbounded("test");
let _ = self.sender.unbounded_send(Event::EventStream(tx));
Box::pin(rx)
}
fn report_peer(&self, who: sc_network::PeerId, cost_benefit: sc_network::ReputationChange) {
let _ = self.sender.unbounded_send(Event::Report(who, cost_benefit));
}
fn disconnect_peer(&self, _: PeerId) {}
fn write_notification(&self, who: PeerId, _: ConsensusEngineId, message: Vec) {
let _ = self.sender.unbounded_send(Event::WriteNotification(who, message));
}
fn register_notifications_protocol(&self, _: ConsensusEngineId, _: Cow<'static, [u8]>) {}
fn announce(&self, block: Hash, _associated_data: Vec) {
let _ = self.sender.unbounded_send(Event::Announce(block));
}
}
impl super::Network for TestNetwork {
fn set_sync_fork_request(
&self,
_peers: Vec,
_hash: Hash,
_number: NumberFor,
) {}
}
impl sc_network_gossip::ValidatorContext for TestNetwork {
fn broadcast_topic(&mut self, _: Hash, _: bool) { }
fn broadcast_message(&mut self, _: Hash, _: Vec, _: bool) { }
fn send_message(&mut self, who: &sc_network::PeerId, data: Vec) {
>::write_notification(
self,
who.clone(),
GRANDPA_ENGINE_ID,
data,
);
}
fn send_topic(&mut self, _: &sc_network::PeerId, _: Hash, _: bool) { }
}
pub(crate) struct Tester {
pub(crate) net_handle: super::NetworkBridge,
gossip_validator: Arc>,
pub(crate) events: TracingUnboundedReceiver,
}
impl Tester {
fn filter_network_events(self, mut pred: F) -> impl Future