mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-28 06:17:56 +00:00
Light GRANDPA import handler (#1669)
* GrandpaLightBlockImport * extract authorities in AuraVerifier * post-merge fix * restore authorities cache * license * new finality proof draft * generalized PendingJustifications * finality proof messages * fixed compilation * pass verifier to import_finality_proof * do not fetch remote proof from light import directly * FinalityProofProvider * fixed authorities cache test * restored finality proof tests * finality_proof docs * use DB backend in test client * justification_is_fetched_by_light_client_when_consensus_data_changes * restore justification_is_fetched_by_light_client_when_consensus_data_changes * some more tests * added authorities-related TODO * removed unneeded clear_finality_proof_requests field * truncated some long lines * more granular light import tests * only provide finality proof if it is generated by the requested set * post-merge fix * finality_proof_is_none_if_first_justification_is_generated_by_unknown_set * make light+grandpa test rely on finality proofs (instead of simple justifications) * empty_finality_proof_is_returned_to_light_client_when_authority_set_is_different * missing trait method impl * fixed proof-of-finality docs * one more doc fix * fix docs * initialize authorities cache (post-merge fix) * fixed cache initialization (post-merge fix) * post-fix merge: fix light + GRANDPA tests (bad way) * proper fix of empty_finality_proof_is_returned_to_light_client_when_authority_set_is_different * fixed easy grumbles * import finality proofs in BlockImportWorker thread * allow import of finality proofs for non-requested blocks * limit number of fragments in finality proof * GRANDPA post-merge fix * BABE: pos-merge fix
This commit is contained in:
committed by
Gavin Wood
parent
258f0835e4
commit
22586113ea
@@ -77,7 +77,7 @@ fn async_import_queue_drops() {
|
||||
// Perform this test multiple times since it exhibits non-deterministic behavior.
|
||||
for _ in 0..100 {
|
||||
let verifier = Arc::new(PassThroughVerifier(true));
|
||||
let queue = BasicQueue::new(verifier, Arc::new(test_client::new()), None);
|
||||
let queue = BasicQueue::new(verifier, Arc::new(test_client::new()), None, None, None);
|
||||
queue.start(Box::new(TestLink{})).unwrap();
|
||||
drop(queue);
|
||||
}
|
||||
|
||||
@@ -26,11 +26,16 @@ use std::sync::Arc;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
|
||||
use log::trace;
|
||||
use client;
|
||||
use crate::chain::FinalityProofProvider;
|
||||
use client::{self, ClientInfo, BlockchainEvents, FinalityNotifications, in_mem::Backend as InMemoryBackend, error::Result as ClientResult};
|
||||
use client::block_builder::BlockBuilder;
|
||||
use crate::config::ProtocolConfig;
|
||||
use client::backend::AuxStore;
|
||||
use crate::config::{ProtocolConfig, Roles};
|
||||
use consensus::import_queue::{BasicQueue, ImportQueue, IncomingBlock};
|
||||
use consensus::import_queue::{Link, SharedBlockImport, SharedJustificationImport, Verifier};
|
||||
use consensus::import_queue::{
|
||||
Link, SharedBlockImport, SharedJustificationImport, Verifier, SharedFinalityProofImport,
|
||||
SharedFinalityProofRequestBuilder,
|
||||
};
|
||||
use consensus::{Error as ConsensusError, ErrorKind as ConsensusErrorKind};
|
||||
use consensus::{BlockOrigin, ForkChoiceStrategy, ImportBlock, JustificationImport};
|
||||
use crate::consensus_gossip::{ConsensusGossip, MessageRecipient as GossipMessageRecipient, TopicNotification};
|
||||
@@ -39,7 +44,7 @@ use futures::{prelude::*, sync::{mpsc, oneshot}};
|
||||
use crate::message::Message;
|
||||
use network_libp2p::PeerId;
|
||||
use parking_lot::{Mutex, RwLock};
|
||||
use primitives::{H256, sr25519::Public as AuthorityId};
|
||||
use primitives::{H256, sr25519::Public as AuthorityId, Blake2Hasher};
|
||||
use crate::protocol::{ConnectedPeer, Context, Protocol, ProtocolMsg, CustomMessageOutcome};
|
||||
use runtime_primitives::generic::BlockId;
|
||||
use runtime_primitives::traits::{AuthorityIdFor, Block as BlockT, Digest, DigestItem, Header, NumberFor};
|
||||
@@ -111,7 +116,79 @@ impl NetworkSpecialization<Block> for DummySpecialization {
|
||||
}
|
||||
}
|
||||
|
||||
pub type PeersClient = client::Client<test_client::Backend, test_client::Executor, Block, test_client::runtime::RuntimeApi>;
|
||||
pub type PeersFullClient = client::Client<test_client::Backend, test_client::Executor, Block, test_client::runtime::RuntimeApi>;
|
||||
pub type PeersLightClient = client::Client<test_client::LightBackend, test_client::LightExecutor, Block, test_client::runtime::RuntimeApi>;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum PeersClient {
|
||||
Full(Arc<PeersFullClient>),
|
||||
Light(Arc<PeersLightClient>),
|
||||
}
|
||||
|
||||
impl PeersClient {
|
||||
pub fn as_full(&self) -> Option<Arc<PeersFullClient>> {
|
||||
match *self {
|
||||
PeersClient::Full(ref client) => Some(client.clone()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_block_import(&self) -> SharedBlockImport<Block> {
|
||||
match *self {
|
||||
PeersClient::Full(ref client) => client.clone() as _,
|
||||
PeersClient::Light(ref client) => client.clone() as _,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_in_memory_backend(&self) -> InMemoryBackend<Block, Blake2Hasher> {
|
||||
match *self {
|
||||
PeersClient::Full(ref client) => client.backend().as_in_memory(),
|
||||
PeersClient::Light(_) => unimplemented!("TODO"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_aux(&self, key: &[u8]) -> ClientResult<Option<Vec<u8>>> {
|
||||
match *self {
|
||||
PeersClient::Full(ref client) => client.backend().get_aux(key),
|
||||
PeersClient::Light(ref client) => client.backend().get_aux(key),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn info(&self) -> ClientResult<ClientInfo<Block>> {
|
||||
match *self {
|
||||
PeersClient::Full(ref client) => client.info(),
|
||||
PeersClient::Light(ref client) => client.info(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn header(&self, block: &BlockId<Block>) -> ClientResult<Option<<Block as BlockT>::Header>> {
|
||||
match *self {
|
||||
PeersClient::Full(ref client) => client.header(block),
|
||||
PeersClient::Light(ref client) => client.header(block),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn justification(&self, block: &BlockId<Block>) -> ClientResult<Option<Justification>> {
|
||||
match *self {
|
||||
PeersClient::Full(ref client) => client.justification(block),
|
||||
PeersClient::Light(ref client) => client.justification(block),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn finality_notification_stream(&self) -> FinalityNotifications<Block> {
|
||||
match *self {
|
||||
PeersClient::Full(ref client) => client.finality_notification_stream(),
|
||||
PeersClient::Light(ref client) => client.finality_notification_stream(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn finalize_block(&self, id: BlockId<Block>, justification: Option<Justification>, notify: bool) -> ClientResult<()> {
|
||||
match *self {
|
||||
PeersClient::Full(ref client) => client.finalize_block(id, justification, notify),
|
||||
PeersClient::Light(ref client) => client.finalize_block(id, justification, notify),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A Link that can wait for a block to have been imported.
|
||||
pub struct TestLink<S: NetworkSpecialization<Block>> {
|
||||
@@ -155,6 +232,23 @@ impl<S: NetworkSpecialization<Block>> Link<Block> for TestLink<S> {
|
||||
self.link.request_justification(hash, number);
|
||||
}
|
||||
|
||||
fn finality_proof_imported(
|
||||
&self,
|
||||
who: PeerId,
|
||||
request_block: (Hash, NumberFor<Block>),
|
||||
finalization_result: Result<(Hash, NumberFor<Block>), ()>,
|
||||
) {
|
||||
self.link.finality_proof_imported(who, request_block, finalization_result);
|
||||
}
|
||||
|
||||
fn request_finality_proof(&self, hash: &Hash, number: NumberFor<Block>) {
|
||||
self.link.request_finality_proof(hash, number);
|
||||
}
|
||||
|
||||
fn set_finality_proof_request_builder(&self, request_builder: SharedFinalityProofRequestBuilder<Block>) {
|
||||
self.link.set_finality_proof_request_builder(request_builder);
|
||||
}
|
||||
|
||||
fn report_peer(&self, who: PeerId, reputation_change: i32) {
|
||||
self.link.report_peer(who, reputation_change);
|
||||
}
|
||||
@@ -178,7 +272,7 @@ pub struct Peer<D, S: NetworkSpecialization<Block>> {
|
||||
pub is_major_syncing: Arc<AtomicBool>,
|
||||
pub peers: Arc<RwLock<HashMap<PeerId, ConnectedPeer<Block>>>>,
|
||||
pub peer_id: PeerId,
|
||||
client: Arc<PeersClient>,
|
||||
client: PeersClient,
|
||||
net_proto_channel: ProtocolChannel<S>,
|
||||
pub import_queue: Box<BasicQueue<Block>>,
|
||||
pub data: D,
|
||||
@@ -188,7 +282,7 @@ pub struct Peer<D, S: NetworkSpecialization<Block>> {
|
||||
|
||||
type MessageFilter = Fn(&NetworkMsg<Block>) -> bool;
|
||||
|
||||
enum FromNetworkMsg<B: BlockT> {
|
||||
pub enum FromNetworkMsg<B: BlockT> {
|
||||
/// A peer connected, with debug info.
|
||||
PeerConnected(PeerId, String),
|
||||
/// A peer disconnected, with debug info.
|
||||
@@ -294,7 +388,7 @@ impl<D, S: NetworkSpecialization<Block>> Peer<D, S> {
|
||||
is_offline: Arc<AtomicBool>,
|
||||
is_major_syncing: Arc<AtomicBool>,
|
||||
peers: Arc<RwLock<HashMap<PeerId, ConnectedPeer<Block>>>>,
|
||||
client: Arc<PeersClient>,
|
||||
client: PeersClient,
|
||||
import_queue: Box<BasicQueue<Block>>,
|
||||
network_to_protocol_sender: mpsc::UnboundedSender<FromNetworkMsg<Block>>,
|
||||
protocol_sender: mpsc::UnboundedSender<ProtocolMsg<Block, S>>,
|
||||
@@ -327,7 +421,7 @@ impl<D, S: NetworkSpecialization<Block>> Peer<D, S> {
|
||||
}
|
||||
}
|
||||
/// Called after blockchain has been populated to updated current state.
|
||||
fn start(&self) {
|
||||
pub fn start(&self) {
|
||||
// Update the sync state to the latest chain state.
|
||||
let info = self.client.info().expect("In-mem client does not fail");
|
||||
let header = self
|
||||
@@ -484,7 +578,7 @@ impl<D, S: NetworkSpecialization<Block>> Peer<D, S> {
|
||||
|
||||
/// Add blocks to the peer -- edit the block before adding
|
||||
pub fn generate_blocks<F>(&self, count: usize, origin: BlockOrigin, edit_block: F) -> H256
|
||||
where F: FnMut(BlockBuilder<Block, PeersClient>) -> Block
|
||||
where F: FnMut(BlockBuilder<Block, PeersFullClient>) -> Block
|
||||
{
|
||||
let best_hash = self.client.info().unwrap().chain.best_hash;
|
||||
self.generate_blocks_at(BlockId::Hash(best_hash), count, origin, edit_block)
|
||||
@@ -493,11 +587,12 @@ impl<D, S: NetworkSpecialization<Block>> Peer<D, S> {
|
||||
/// Add blocks to the peer -- edit the block before adding. The chain will
|
||||
/// start at the given block iD.
|
||||
pub fn generate_blocks_at<F>(&self, at: BlockId<Block>, count: usize, origin: BlockOrigin, mut edit_block: F) -> H256
|
||||
where F: FnMut(BlockBuilder<Block, PeersClient>) -> Block
|
||||
where F: FnMut(BlockBuilder<Block, PeersFullClient>) -> Block
|
||||
{
|
||||
let mut at = self.client.header(&at).unwrap().unwrap().hash();
|
||||
let full_client = self.client.as_full().expect("blocks could only be generated by full clients");
|
||||
let mut at = full_client.header(&at).unwrap().unwrap().hash();
|
||||
for _ in 0..count {
|
||||
let builder = self.client.new_block_at(&BlockId::Hash(at)).unwrap();
|
||||
let builder = full_client.new_block_at(&BlockId::Hash(at)).unwrap();
|
||||
let block = edit_block(builder);
|
||||
let hash = block.header.hash();
|
||||
trace!(
|
||||
@@ -562,7 +657,7 @@ impl<D, S: NetworkSpecialization<Block>> Peer<D, S> {
|
||||
}
|
||||
|
||||
/// Get a reference to the client.
|
||||
pub fn client(&self) -> &Arc<PeersClient> {
|
||||
pub fn client(&self) -> &PeersClient {
|
||||
&self.client
|
||||
}
|
||||
}
|
||||
@@ -598,7 +693,7 @@ pub trait TestNetFactory: Sized {
|
||||
|
||||
/// These two need to be implemented!
|
||||
fn from_config(config: &ProtocolConfig) -> Self;
|
||||
fn make_verifier(&self, client: Arc<PeersClient>, config: &ProtocolConfig) -> Arc<Self::Verifier>;
|
||||
fn make_verifier(&self, client: PeersClient, config: &ProtocolConfig) -> Arc<Self::Verifier>;
|
||||
|
||||
/// Get reference to peer.
|
||||
fn peer(&self, i: usize) -> &Peer<Self::PeerData, Self::Specialization>;
|
||||
@@ -609,10 +704,21 @@ pub trait TestNetFactory: Sized {
|
||||
fn set_started(&mut self, now: bool);
|
||||
|
||||
/// Get custom block import handle for fresh client, along with peer data.
|
||||
fn make_block_import(&self, client: Arc<PeersClient>)
|
||||
-> (SharedBlockImport<Block>, Option<SharedJustificationImport<Block>>, Self::PeerData)
|
||||
fn make_block_import(&self, client: PeersClient)
|
||||
-> (
|
||||
SharedBlockImport<Block>,
|
||||
Option<SharedJustificationImport<Block>>,
|
||||
Option<SharedFinalityProofImport<Block>>,
|
||||
Option<SharedFinalityProofRequestBuilder<Block>>,
|
||||
Self::PeerData,
|
||||
)
|
||||
{
|
||||
(client, None, Default::default())
|
||||
(client.as_block_import(), None, None, None, Default::default())
|
||||
}
|
||||
|
||||
/// Get finality proof provider (if supported).
|
||||
fn make_finality_proof_provider(&self, _client: PeersClient) -> Option<Arc<FinalityProofProvider<Block>>> {
|
||||
None
|
||||
}
|
||||
|
||||
fn default_config() -> ProtocolConfig {
|
||||
@@ -627,41 +733,21 @@ pub trait TestNetFactory: Sized {
|
||||
|
||||
for i in 0..n {
|
||||
trace!(target: "test_network", "Adding peer {}", i);
|
||||
net.add_peer(&config);
|
||||
net.add_full_peer(&config);
|
||||
}
|
||||
net
|
||||
}
|
||||
|
||||
/// Add a peer.
|
||||
fn add_peer(&mut self, config: &ProtocolConfig) {
|
||||
let client = Arc::new(test_client::new());
|
||||
let tx_pool = Arc::new(EmptyTransactionPool);
|
||||
let verifier = self.make_verifier(client.clone(), config);
|
||||
let (block_import, justification_import, data) = self.make_block_import(client.clone());
|
||||
let (network_sender, network_port) = network_channel();
|
||||
|
||||
let import_queue = Box::new(BasicQueue::new(verifier, block_import, justification_import));
|
||||
let is_offline = Arc::new(AtomicBool::new(true));
|
||||
let is_major_syncing = Arc::new(AtomicBool::new(false));
|
||||
let specialization = self::SpecializationFactory::create();
|
||||
let peers: Arc<RwLock<HashMap<PeerId, ConnectedPeer<Block>>>> = Arc::new(Default::default());
|
||||
|
||||
let (network_to_protocol_sender, mut network_to_protocol_rx) = mpsc::unbounded();
|
||||
|
||||
let (mut protocol, protocol_sender) = Protocol::new(
|
||||
peers.clone(),
|
||||
network_sender.clone(),
|
||||
config.clone(),
|
||||
client.clone(),
|
||||
None,
|
||||
tx_pool,
|
||||
specialization,
|
||||
).unwrap();
|
||||
|
||||
let is_offline2 = is_offline.clone();
|
||||
let is_major_syncing2 = is_major_syncing.clone();
|
||||
let import_queue2 = import_queue.clone();
|
||||
|
||||
/// Add created peer.
|
||||
fn add_peer(
|
||||
&mut self,
|
||||
is_offline: Arc<AtomicBool>,
|
||||
is_major_syncing: Arc<AtomicBool>,
|
||||
import_queue: Box<BasicQueue<Block>>,
|
||||
mut protocol: Protocol<Block, Self::Specialization, Hash>,
|
||||
mut network_to_protocol_rx: mpsc::UnboundedReceiver<FromNetworkMsg<Block>>,
|
||||
peer: Arc<Peer<Self::PeerData, Self::Specialization>>,
|
||||
) {
|
||||
std::thread::spawn(move || {
|
||||
tokio::runtime::current_thread::run(futures::future::poll_fn(move || {
|
||||
while let Async::Ready(msg) = network_to_protocol_rx.poll().unwrap() {
|
||||
@@ -680,14 +766,16 @@ pub trait TestNetFactory: Sized {
|
||||
protocol.synchronize();
|
||||
CustomMessageOutcome::None
|
||||
},
|
||||
None => return Ok(Async::Ready(()))
|
||||
None => return Ok(Async::Ready(())),
|
||||
};
|
||||
|
||||
match outcome {
|
||||
CustomMessageOutcome::BlockImport(origin, blocks) =>
|
||||
import_queue2.import_blocks(origin, blocks),
|
||||
import_queue.import_blocks(origin, blocks),
|
||||
CustomMessageOutcome::JustificationImport(origin, hash, nb, justification) =>
|
||||
import_queue2.import_justification(origin, hash, nb, justification),
|
||||
import_queue.import_justification(origin, hash, nb, justification),
|
||||
CustomMessageOutcome::FinalityProofImport(origin, hash, nb, proof) =>
|
||||
import_queue.import_finality_proof(origin, hash, nb, proof),
|
||||
CustomMessageOutcome::None => {}
|
||||
}
|
||||
}
|
||||
@@ -696,31 +784,140 @@ pub trait TestNetFactory: Sized {
|
||||
return Ok(Async::Ready(()))
|
||||
}
|
||||
|
||||
is_offline2.store(protocol.is_offline(), Ordering::Relaxed);
|
||||
is_major_syncing2.store(protocol.is_major_syncing(), Ordering::Relaxed);
|
||||
|
||||
is_offline.store(protocol.is_offline(), Ordering::Relaxed);
|
||||
is_major_syncing.store(protocol.is_major_syncing(), Ordering::Relaxed);
|
||||
|
||||
Ok(Async::NotReady)
|
||||
}));
|
||||
});
|
||||
|
||||
let peer = Arc::new(Peer::new(
|
||||
is_offline,
|
||||
is_major_syncing,
|
||||
peers,
|
||||
client,
|
||||
import_queue,
|
||||
network_to_protocol_sender,
|
||||
protocol_sender,
|
||||
network_sender,
|
||||
network_port,
|
||||
data,
|
||||
));
|
||||
if self.started() {
|
||||
peer.start();
|
||||
self.peers().iter().for_each(|other| {
|
||||
other.on_connect(&*peer);
|
||||
peer.on_connect(other);
|
||||
});
|
||||
}
|
||||
|
||||
self.mut_peers(|peers| {
|
||||
peers.push(peer)
|
||||
});
|
||||
}
|
||||
|
||||
/// Add a full peer.
|
||||
fn add_full_peer(&mut self, config: &ProtocolConfig) {
|
||||
let client = Arc::new(test_client::new());
|
||||
let tx_pool = Arc::new(EmptyTransactionPool);
|
||||
let verifier = self.make_verifier(PeersClient::Full(client.clone()), config);
|
||||
let (block_import, justification_import, finality_proof_import, finality_proof_request_builder, data)
|
||||
= self.make_block_import(PeersClient::Full(client.clone()));
|
||||
let (network_sender, network_port) = network_channel();
|
||||
|
||||
let import_queue = Box::new(BasicQueue::new(
|
||||
verifier,
|
||||
block_import,
|
||||
justification_import,
|
||||
finality_proof_import,
|
||||
finality_proof_request_builder,
|
||||
));
|
||||
let is_offline = Arc::new(AtomicBool::new(true));
|
||||
let is_major_syncing = Arc::new(AtomicBool::new(false));
|
||||
let specialization = self::SpecializationFactory::create();
|
||||
let peers: Arc<RwLock<HashMap<PeerId, ConnectedPeer<Block>>>> = Arc::new(Default::default());
|
||||
|
||||
let (network_to_protocol_sender, network_to_protocol_rx) = mpsc::unbounded();
|
||||
|
||||
let (protocol, protocol_sender) = Protocol::new(
|
||||
peers.clone(),
|
||||
network_sender.clone(),
|
||||
config.clone(),
|
||||
client.clone(),
|
||||
self.make_finality_proof_provider(PeersClient::Full(client.clone())),
|
||||
None,
|
||||
tx_pool,
|
||||
specialization,
|
||||
).unwrap();
|
||||
|
||||
self.add_peer(
|
||||
is_offline.clone(),
|
||||
is_major_syncing.clone(),
|
||||
import_queue.clone(),
|
||||
protocol,
|
||||
network_to_protocol_rx,
|
||||
Arc::new(Peer::new(
|
||||
is_offline,
|
||||
is_major_syncing,
|
||||
peers,
|
||||
PeersClient::Full(client),
|
||||
import_queue,
|
||||
network_to_protocol_sender,
|
||||
protocol_sender,
|
||||
network_sender,
|
||||
network_port,
|
||||
data,
|
||||
)),
|
||||
);
|
||||
}
|
||||
|
||||
/// Add a light peer.
|
||||
fn add_light_peer(&mut self, config: &ProtocolConfig) {
|
||||
let mut config = config.clone();
|
||||
config.roles = Roles::LIGHT;
|
||||
|
||||
let client = Arc::new(test_client::new_light());
|
||||
let tx_pool = Arc::new(EmptyTransactionPool);
|
||||
let verifier = self.make_verifier(PeersClient::Light(client.clone()), &config);
|
||||
let (block_import, justification_import, finality_proof_import, finality_proof_request_builder, data)
|
||||
= self.make_block_import(PeersClient::Light(client.clone()));
|
||||
let (network_sender, network_port) = network_channel();
|
||||
|
||||
let import_queue = Box::new(BasicQueue::new(
|
||||
verifier,
|
||||
block_import,
|
||||
justification_import,
|
||||
finality_proof_import,
|
||||
finality_proof_request_builder,
|
||||
));
|
||||
let is_offline = Arc::new(AtomicBool::new(true));
|
||||
let is_major_syncing = Arc::new(AtomicBool::new(false));
|
||||
let specialization = self::SpecializationFactory::create();
|
||||
let peers: Arc<RwLock<HashMap<PeerId, ConnectedPeer<Block>>>> = Arc::new(Default::default());
|
||||
|
||||
let (network_to_protocol_sender, network_to_protocol_rx) = mpsc::unbounded();
|
||||
|
||||
let (protocol, protocol_sender) = Protocol::new(
|
||||
peers.clone(),
|
||||
network_sender.clone(),
|
||||
config,
|
||||
client.clone(),
|
||||
self.make_finality_proof_provider(PeersClient::Light(client.clone())),
|
||||
None,
|
||||
tx_pool,
|
||||
specialization,
|
||||
).unwrap();
|
||||
|
||||
self.add_peer(
|
||||
is_offline.clone(),
|
||||
is_major_syncing.clone(),
|
||||
import_queue.clone(),
|
||||
protocol,
|
||||
network_to_protocol_rx,
|
||||
Arc::new(Peer::new(
|
||||
is_offline,
|
||||
is_major_syncing,
|
||||
peers,
|
||||
PeersClient::Light(client),
|
||||
import_queue,
|
||||
network_to_protocol_sender,
|
||||
protocol_sender,
|
||||
network_sender,
|
||||
network_port,
|
||||
data,
|
||||
)),
|
||||
);
|
||||
}
|
||||
|
||||
/// Start network.
|
||||
fn start(&mut self) {
|
||||
if self.started() {
|
||||
@@ -832,6 +1029,11 @@ pub trait TestNetFactory: Sized {
|
||||
self.route_single(true, None, &|_| true);
|
||||
}
|
||||
|
||||
/// Maintain sync for a peer.
|
||||
fn tick_peer(&mut self, i: usize) {
|
||||
self.peers()[i].sync_step();
|
||||
}
|
||||
|
||||
/// Deliver pending messages until there are no more.
|
||||
fn sync(&mut self) {
|
||||
self.sync_with(true, None)
|
||||
@@ -866,7 +1068,7 @@ impl TestNetFactory for TestNet {
|
||||
}
|
||||
}
|
||||
|
||||
fn make_verifier(&self, _client: Arc<PeersClient>, _config: &ProtocolConfig)
|
||||
fn make_verifier(&self, _client: PeersClient, _config: &ProtocolConfig)
|
||||
-> Arc<Self::Verifier>
|
||||
{
|
||||
Arc::new(PassThroughVerifier(false))
|
||||
@@ -893,7 +1095,7 @@ impl TestNetFactory for TestNet {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ForceFinalized(Arc<PeersClient>);
|
||||
pub struct ForceFinalized(PeersClient);
|
||||
|
||||
impl JustificationImport<Block> for ForceFinalized {
|
||||
type Error = ConsensusError;
|
||||
@@ -920,7 +1122,7 @@ impl TestNetFactory for JustificationTestNet {
|
||||
JustificationTestNet(TestNet::from_config(config))
|
||||
}
|
||||
|
||||
fn make_verifier(&self, client: Arc<PeersClient>, config: &ProtocolConfig)
|
||||
fn make_verifier(&self, client: PeersClient, config: &ProtocolConfig)
|
||||
-> Arc<Self::Verifier>
|
||||
{
|
||||
self.0.make_verifier(client, config)
|
||||
@@ -946,9 +1148,15 @@ impl TestNetFactory for JustificationTestNet {
|
||||
self.0.set_started(new)
|
||||
}
|
||||
|
||||
fn make_block_import(&self, client: Arc<PeersClient>)
|
||||
-> (SharedBlockImport<Block>, Option<SharedJustificationImport<Block>>, Self::PeerData)
|
||||
fn make_block_import(&self, client: PeersClient)
|
||||
-> (
|
||||
SharedBlockImport<Block>,
|
||||
Option<SharedJustificationImport<Block>>,
|
||||
Option<SharedFinalityProofImport<Block>>,
|
||||
Option<SharedFinalityProofRequestBuilder<Block>>,
|
||||
Self::PeerData,
|
||||
)
|
||||
{
|
||||
(client.clone(), Some(Arc::new(ForceFinalized(client))), Default::default())
|
||||
(client.as_block_import(), Some(Arc::new(ForceFinalized(client))), None, None, Default::default())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,8 +14,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use client::backend::Backend;
|
||||
use client::blockchain::HeaderBackend as BlockchainHeaderBackend;
|
||||
use client::{backend::Backend, blockchain::HeaderBackend};
|
||||
use crate::config::Roles;
|
||||
use consensus::BlockOrigin;
|
||||
use std::collections::HashSet;
|
||||
@@ -34,8 +33,8 @@ fn test_ancestor_search_when_common_is(n: usize) {
|
||||
net.peer(2).push_blocks(100, false);
|
||||
|
||||
net.sync();
|
||||
assert!(net.peer(0).client.backend().as_in_memory().blockchain()
|
||||
.canon_equals_to(net.peer(1).client.backend().as_in_memory().blockchain()));
|
||||
assert!(net.peer(0).client.as_in_memory_backend().blockchain()
|
||||
.canon_equals_to(net.peer(1).client.as_in_memory_backend().blockchain()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -130,8 +129,8 @@ fn sync_from_two_peers_works() {
|
||||
net.peer(1).push_blocks(100, false);
|
||||
net.peer(2).push_blocks(100, false);
|
||||
net.sync();
|
||||
assert!(net.peer(0).client.backend().as_in_memory().blockchain()
|
||||
.equals_to(net.peer(1).client.backend().as_in_memory().blockchain()));
|
||||
assert!(net.peer(0).client.as_in_memory_backend().blockchain()
|
||||
.equals_to(net.peer(1).client.as_in_memory_backend().blockchain()));
|
||||
assert!(!net.peer(0).is_major_syncing());
|
||||
}
|
||||
|
||||
@@ -143,8 +142,8 @@ fn sync_from_two_peers_with_ancestry_search_works() {
|
||||
net.peer(1).push_blocks(100, false);
|
||||
net.peer(2).push_blocks(100, false);
|
||||
net.sync();
|
||||
assert!(net.peer(0).client.backend().as_in_memory().blockchain()
|
||||
.canon_equals_to(net.peer(1).client.backend().as_in_memory().blockchain()));
|
||||
assert!(net.peer(0).client.as_in_memory_backend().blockchain()
|
||||
.canon_equals_to(net.peer(1).client.as_in_memory_backend().blockchain()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -157,8 +156,8 @@ fn ancestry_search_works_when_backoff_is_one() {
|
||||
net.peer(2).push_blocks(2, false);
|
||||
|
||||
net.sync();
|
||||
assert!(net.peer(0).client.backend().as_in_memory().blockchain()
|
||||
.canon_equals_to(net.peer(1).client.backend().as_in_memory().blockchain()));
|
||||
assert!(net.peer(0).client.as_in_memory_backend().blockchain()
|
||||
.canon_equals_to(net.peer(1).client.as_in_memory_backend().blockchain()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -171,8 +170,8 @@ fn ancestry_search_works_when_ancestor_is_genesis() {
|
||||
net.peer(2).push_blocks(100, false);
|
||||
|
||||
net.sync();
|
||||
assert!(net.peer(0).client.backend().as_in_memory().blockchain()
|
||||
.canon_equals_to(net.peer(1).client.backend().as_in_memory().blockchain()));
|
||||
assert!(net.peer(0).client.as_in_memory_backend().blockchain()
|
||||
.canon_equals_to(net.peer(1).client.as_in_memory_backend().blockchain()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -195,8 +194,8 @@ fn sync_long_chain_works() {
|
||||
let mut net = TestNet::new(2);
|
||||
net.peer(1).push_blocks(500, false);
|
||||
net.sync();
|
||||
assert!(net.peer(0).client.backend().as_in_memory().blockchain()
|
||||
.equals_to(net.peer(1).client.backend().as_in_memory().blockchain()));
|
||||
assert!(net.peer(0).client.as_in_memory_backend().blockchain()
|
||||
.equals_to(net.peer(1).client.as_in_memory_backend().blockchain()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -206,8 +205,8 @@ fn sync_no_common_longer_chain_fails() {
|
||||
net.peer(0).push_blocks(20, true);
|
||||
net.peer(1).push_blocks(20, false);
|
||||
net.sync();
|
||||
assert!(!net.peer(0).client.backend().as_in_memory().blockchain()
|
||||
.canon_equals_to(net.peer(1).client.backend().as_in_memory().blockchain()));
|
||||
assert!(!net.peer(0).client.as_in_memory_backend().blockchain()
|
||||
.canon_equals_to(net.peer(1).client.as_in_memory_backend().blockchain()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -285,11 +284,11 @@ fn sync_after_fork_works() {
|
||||
net.peer(2).push_blocks(1, false);
|
||||
|
||||
// peer 1 has the best chain
|
||||
let peer1_chain = net.peer(1).client.backend().as_in_memory().blockchain().clone();
|
||||
let peer1_chain = net.peer(1).client.as_in_memory_backend().blockchain().clone();
|
||||
net.sync();
|
||||
assert!(net.peer(0).client.backend().as_in_memory().blockchain().canon_equals_to(&peer1_chain));
|
||||
assert!(net.peer(1).client.backend().as_in_memory().blockchain().canon_equals_to(&peer1_chain));
|
||||
assert!(net.peer(2).client.backend().as_in_memory().blockchain().canon_equals_to(&peer1_chain));
|
||||
assert!(net.peer(0).client.as_in_memory_backend().blockchain().canon_equals_to(&peer1_chain));
|
||||
assert!(net.peer(1).client.as_in_memory_backend().blockchain().canon_equals_to(&peer1_chain));
|
||||
assert!(net.peer(2).client.as_in_memory_backend().blockchain().canon_equals_to(&peer1_chain));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -305,8 +304,8 @@ fn syncs_all_forks() {
|
||||
|
||||
net.sync();
|
||||
// Check that all peers have all of the blocks.
|
||||
assert_eq!(9, net.peer(0).client.backend().as_in_memory().blockchain().blocks_count());
|
||||
assert_eq!(9, net.peer(1).client.backend().as_in_memory().blockchain().blocks_count());
|
||||
assert_eq!(9, net.peer(0).client.as_in_memory_backend().blockchain().blocks_count());
|
||||
assert_eq!(9, net.peer(1).client.as_in_memory_backend().blockchain().blocks_count());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -320,11 +319,11 @@ fn own_blocks_are_announced() {
|
||||
net.peer(0).on_block_imported(header.hash(), &header);
|
||||
net.sync();
|
||||
|
||||
assert_eq!(net.peer(0).client.backend().blockchain().info().unwrap().best_number, 1);
|
||||
assert_eq!(net.peer(1).client.backend().blockchain().info().unwrap().best_number, 1);
|
||||
let peer0_chain = net.peer(0).client.backend().as_in_memory().blockchain().clone();
|
||||
assert!(net.peer(1).client.backend().as_in_memory().blockchain().canon_equals_to(&peer0_chain));
|
||||
assert!(net.peer(2).client.backend().as_in_memory().blockchain().canon_equals_to(&peer0_chain));
|
||||
assert_eq!(net.peer(0).client.as_in_memory_backend().blockchain().info().unwrap().best_number, 1);
|
||||
assert_eq!(net.peer(1).client.as_in_memory_backend().blockchain().info().unwrap().best_number, 1);
|
||||
let peer0_chain = net.peer(0).client.as_in_memory_backend().blockchain().clone();
|
||||
assert!(net.peer(1).client.as_in_memory_backend().blockchain().canon_equals_to(&peer0_chain));
|
||||
assert!(net.peer(2).client.as_in_memory_backend().blockchain().canon_equals_to(&peer0_chain));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -336,9 +335,9 @@ fn blocks_are_not_announced_by_light_nodes() {
|
||||
// light peer1 is connected to full peer2
|
||||
let mut light_config = ProtocolConfig::default();
|
||||
light_config.roles = Roles::LIGHT;
|
||||
net.add_peer(&ProtocolConfig::default());
|
||||
net.add_peer(&light_config);
|
||||
net.add_peer(&ProtocolConfig::default());
|
||||
net.add_full_peer(&ProtocolConfig::default());
|
||||
net.add_full_peer(&light_config);
|
||||
net.add_full_peer(&ProtocolConfig::default());
|
||||
|
||||
net.peer(0).push_blocks(1, false);
|
||||
net.peer(0).start();
|
||||
@@ -356,9 +355,9 @@ fn blocks_are_not_announced_by_light_nodes() {
|
||||
// peer 0 has the best chain
|
||||
// peer 1 has the best chain
|
||||
// peer 2 has genesis-chain only
|
||||
assert_eq!(net.peer(0).client.backend().blockchain().info().unwrap().best_number, 1);
|
||||
assert_eq!(net.peer(1).client.backend().blockchain().info().unwrap().best_number, 1);
|
||||
assert_eq!(net.peer(2).client.backend().blockchain().info().unwrap().best_number, 0);
|
||||
assert_eq!(net.peer(0).client.info().unwrap().chain.best_number, 1);
|
||||
assert_eq!(net.peer(1).client.info().unwrap().chain.best_number, 1);
|
||||
assert_eq!(net.peer(2).client.info().unwrap().chain.best_number, 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user