// Copyright 2019-2020 Parity Technologies (UK) Ltd.
// This file is part of Polkadot.
// Polkadot 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.
// Polkadot 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 Polkadot. If not, see .
//! Tests and helpers for validation networking.
#![allow(unused)]
use crate::legacy::gossip::GossipMessage;
use sc_network::{Context as NetContext, PeerId};
use sc_network_gossip::TopicNotification;
use sp_core::{NativeOrEncoded, ExecutionContext};
use sp_keyring::Sr25519Keyring;
use crate::legacy::{PolkadotProtocol, NetworkService, GossipService, GossipMessageStream};
use polkadot_validation::{SharedTable, Network};
use polkadot_primitives::{Block, BlockNumber, Hash, Header, BlockId};
use polkadot_primitives::parachain::{
Id as ParaId, Chain, DutyRoster, ParachainHost, ValidatorId, Status,
FeeSchedule, HeadData, Retriable, CollatorId, ErasureChunk, CandidateReceipt,
};
use parking_lot::Mutex;
use sp_blockchain::Result as ClientResult;
use sp_api::{ApiRef, Core, RuntimeVersion, StorageProof, ApiErrorExt, ApiExt, ProvideRuntimeApi};
use sp_runtime::traits::{Block as BlockT, HasherFor, NumberFor};
use sp_state_machine::ChangesTrieState;
use std::collections::HashMap;
use std::sync::Arc;
use std::pin::Pin;
use std::task::{Poll, Context};
use futures::{prelude::*, channel::mpsc, future::{select, Either}, task::Spawn};
use codec::Encode;
use super::{TestContext, TestChainContext};
#[derive(Clone, Copy)]
struct NeverExit;
impl Future for NeverExit {
type Output = ();
fn poll(self: Pin<&mut Self>, _: &mut Context) -> Poll {
Poll::Pending
}
}
fn clone_gossip(n: &TopicNotification) -> TopicNotification {
TopicNotification {
message: n.message.clone(),
sender: n.sender.clone(),
}
}
async fn gossip_router(
mut incoming_messages: mpsc::UnboundedReceiver<(Hash, TopicNotification)>,
mut incoming_streams: mpsc::UnboundedReceiver<(Hash, mpsc::UnboundedSender)>
) {
let mut outgoing: Vec<(Hash, mpsc::UnboundedSender)> = Vec::new();
let mut messages = Vec::new();
loop {
match select(incoming_messages.next(), incoming_streams.next()).await {
Either::Left((Some((topic, message)), _)) => {
outgoing.retain(|&(ref o_topic, ref sender)| {
o_topic != &topic || sender.unbounded_send(clone_gossip(&message)).is_ok()
});
messages.push((topic, message));
},
Either::Right((Some((topic, sender)), _)) => {
for message in messages.iter()
.filter(|&&(ref t, _)| t == &topic)
.map(|&(_, ref msg)| clone_gossip(msg))
{
if let Err(_) = sender.unbounded_send(message) { return }
}
outgoing.push((topic, sender));
},
Either::Left((None, _)) | Either::Right((None, _)) => panic!("ended early.")
}
}
}
#[derive(Clone)]
struct GossipHandle {
send_message: mpsc::UnboundedSender<(Hash, TopicNotification)>,
send_listener: mpsc::UnboundedSender<(Hash, mpsc::UnboundedSender)>,
}
fn make_gossip() -> (impl Future