mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-12 08:51:09 +00:00
Make BlockImport and Verifier async (#8472)
* Make grandpa work * Introduce `SharedData` * Add test and fix bugs * Switch to `SharedData` * Make grandpa tests working * More Babe work * Make it async * Fix fix * Use `async_trait` in sc-consensus-slots This makes the code a little bit easier to read and also expresses that there can always only be one call at a time to `on_slot`. * Make grandpa tests compile * More Babe tests work * Fix network test * Start fixing service test * Finish service-test * Fix sc-consensus-aura * Fix fix fix * More fixes * Make everything compile *yeah* * Fix build when we have Rust 1.51 * Update client/consensus/common/src/shared_data.rs Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com> * Update client/consensus/common/src/shared_data.rs Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com> * Update client/consensus/common/src/shared_data.rs Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com> * Update client/consensus/common/src/shared_data.rs Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com> * Update client/consensus/common/src/shared_data.rs Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com> * Update client/consensus/babe/src/tests.rs Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com> * Update client/consensus/babe/src/tests.rs Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com> * Fix warning Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com>
This commit is contained in:
@@ -26,12 +26,13 @@ use substrate_test_runtime_client::{self, prelude::*};
|
||||
use substrate_test_runtime_client::runtime::{Block, Hash};
|
||||
use sp_runtime::generic::BlockId;
|
||||
use sc_block_builder::BlockBuilderProvider;
|
||||
use futures::executor::block_on;
|
||||
use super::*;
|
||||
|
||||
fn prepare_good_block() -> (TestClient, Hash, u64, PeerId, IncomingBlock<Block>) {
|
||||
let mut client = substrate_test_runtime_client::new();
|
||||
let block = client.new_block(Default::default()).unwrap().build().unwrap().block;
|
||||
client.import(BlockOrigin::File, block).unwrap();
|
||||
block_on(client.import(BlockOrigin::File, block)).unwrap();
|
||||
|
||||
let (hash, number) = (client.block_hash(1).unwrap().unwrap(), 1);
|
||||
let header = client.header(&BlockId::Number(1)).unwrap();
|
||||
@@ -55,12 +56,12 @@ fn import_single_good_block_works() {
|
||||
let mut expected_aux = ImportedAux::default();
|
||||
expected_aux.is_new_best = true;
|
||||
|
||||
match import_single_block(
|
||||
match block_on(import_single_block(
|
||||
&mut substrate_test_runtime_client::new(),
|
||||
BlockOrigin::File,
|
||||
block,
|
||||
&mut PassThroughVerifier::new(true)
|
||||
) {
|
||||
)) {
|
||||
Ok(BlockImportResult::ImportedUnknown(ref num, ref aux, ref org))
|
||||
if *num == number && *aux == expected_aux && *org == Some(peer_id) => {}
|
||||
r @ _ => panic!("{:?}", r)
|
||||
@@ -70,12 +71,12 @@ fn import_single_good_block_works() {
|
||||
#[test]
|
||||
fn import_single_good_known_block_is_ignored() {
|
||||
let (mut client, _hash, number, _, block) = prepare_good_block();
|
||||
match import_single_block(
|
||||
match block_on(import_single_block(
|
||||
&mut client,
|
||||
BlockOrigin::File,
|
||||
block,
|
||||
&mut PassThroughVerifier::new(true)
|
||||
) {
|
||||
)) {
|
||||
Ok(BlockImportResult::ImportedKnown(ref n, _)) if *n == number => {}
|
||||
_ => panic!()
|
||||
}
|
||||
@@ -85,12 +86,12 @@ fn import_single_good_known_block_is_ignored() {
|
||||
fn import_single_good_block_without_header_fails() {
|
||||
let (_, _, _, peer_id, mut block) = prepare_good_block();
|
||||
block.header = None;
|
||||
match import_single_block(
|
||||
match block_on(import_single_block(
|
||||
&mut substrate_test_runtime_client::new(),
|
||||
BlockOrigin::File,
|
||||
block,
|
||||
&mut PassThroughVerifier::new(true)
|
||||
) {
|
||||
)) {
|
||||
Err(BlockImportError::IncompleteHeader(ref org)) if *org == Some(peer_id) => {}
|
||||
_ => panic!()
|
||||
}
|
||||
|
||||
@@ -23,8 +23,7 @@ mod block_import;
|
||||
mod sync;
|
||||
|
||||
use std::{
|
||||
borrow::Cow, collections::HashMap, pin::Pin, sync::Arc, marker::PhantomData,
|
||||
task::{Poll, Context as FutureContext}
|
||||
borrow::Cow, collections::HashMap, pin::Pin, sync::Arc, task::{Poll, Context as FutureContext}
|
||||
};
|
||||
|
||||
use libp2p::build_multiaddr;
|
||||
@@ -64,7 +63,7 @@ use sc_network::config::ProtocolConfig;
|
||||
use sp_runtime::generic::{BlockId, OpaqueDigestItemId};
|
||||
use sp_runtime::traits::{Block as BlockT, Header as HeaderT, NumberFor};
|
||||
use sp_runtime::{Justification, Justifications};
|
||||
use substrate_test_runtime_client::{self, AccountKeyring};
|
||||
use substrate_test_runtime_client::AccountKeyring;
|
||||
use sc_service::client::Client;
|
||||
pub use sc_network::config::EmptyTransactionPool;
|
||||
pub use substrate_test_runtime_client::runtime::{Block, Extrinsic, Hash, Transfer};
|
||||
@@ -104,8 +103,9 @@ impl PassThroughVerifier {
|
||||
}
|
||||
|
||||
/// This `Verifier` accepts all data as valid.
|
||||
#[async_trait::async_trait]
|
||||
impl<B: BlockT> Verifier<B> for PassThroughVerifier {
|
||||
fn verify(
|
||||
async fn verify(
|
||||
&mut self,
|
||||
origin: BlockOrigin,
|
||||
header: B::Header,
|
||||
@@ -154,13 +154,8 @@ impl PeersClient {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_block_import<Transaction>(&self) -> BlockImportAdapter<Transaction> {
|
||||
match *self {
|
||||
PeersClient::Full(ref client, ref _backend) =>
|
||||
BlockImportAdapter::new_full(client.clone()),
|
||||
PeersClient::Light(ref client, ref _backend) =>
|
||||
BlockImportAdapter::Light(Arc::new(Mutex::new(client.clone())), PhantomData),
|
||||
}
|
||||
pub fn as_block_import(&self) -> BlockImportAdapter<Self> {
|
||||
BlockImportAdapter::new(self.clone())
|
||||
}
|
||||
|
||||
pub fn get_aux(&self, key: &[u8]) -> ClientResult<Option<Vec<u8>>> {
|
||||
@@ -218,7 +213,36 @@ impl PeersClient {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Peer<D> {
|
||||
#[async_trait::async_trait]
|
||||
impl BlockImport<Block> for PeersClient {
|
||||
type Error = ConsensusError;
|
||||
type Transaction = ();
|
||||
|
||||
async fn check_block(
|
||||
&mut self,
|
||||
block: BlockCheckParams<Block>,
|
||||
) -> Result<ImportResult, Self::Error> {
|
||||
match self {
|
||||
PeersClient::Full(client, _) => client.check_block(block).await,
|
||||
PeersClient::Light(client, _) => client.check_block(block).await,
|
||||
}
|
||||
}
|
||||
|
||||
async fn import_block(
|
||||
&mut self,
|
||||
block: BlockImportParams<Block, ()>,
|
||||
cache: HashMap<well_known_cache_keys::Id, Vec<u8>>,
|
||||
) -> Result<ImportResult, Self::Error> {
|
||||
match self {
|
||||
PeersClient::Full(client, _) =>
|
||||
client.import_block(block.convert_transaction(), cache).await,
|
||||
PeersClient::Light(client, _) =>
|
||||
client.import_block(block.convert_transaction(), cache).await,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Peer<D, BlockImport> {
|
||||
pub data: D,
|
||||
client: PeersClient,
|
||||
/// We keep a copy of the verifier so that we can invoke it for locally-generated blocks,
|
||||
@@ -226,7 +250,7 @@ pub struct Peer<D> {
|
||||
verifier: VerifierAdapter<Block>,
|
||||
/// We keep a copy of the block_import so that we can invoke it for locally-generated blocks,
|
||||
/// instead of going through the import queue.
|
||||
block_import: BlockImportAdapter<()>,
|
||||
block_import: BlockImportAdapter<BlockImport>,
|
||||
select_chain: Option<LongestChain<substrate_test_runtime_client::Backend, Block>>,
|
||||
backend: Option<Arc<substrate_test_runtime_client::Backend>>,
|
||||
network: NetworkWorker<Block, <Block as BlockT>::Hash>,
|
||||
@@ -235,7 +259,10 @@ pub struct Peer<D> {
|
||||
listen_addr: Multiaddr,
|
||||
}
|
||||
|
||||
impl<D> Peer<D> {
|
||||
impl<D, B> Peer<D, B> where
|
||||
B: BlockImport<Block, Error = ConsensusError> + Send + Sync,
|
||||
B::Transaction: Send,
|
||||
{
|
||||
/// Get this peer ID.
|
||||
pub fn id(&self) -> PeerId {
|
||||
self.network.service().local_peer_id().clone()
|
||||
@@ -277,13 +304,24 @@ impl<D> Peer<D> {
|
||||
}
|
||||
|
||||
/// Request explicit fork sync.
|
||||
pub fn set_sync_fork_request(&self, peers: Vec<PeerId>, hash: <Block as BlockT>::Hash, number: NumberFor<Block>) {
|
||||
pub fn set_sync_fork_request(
|
||||
&self,
|
||||
peers: Vec<PeerId>,
|
||||
hash: <Block as BlockT>::Hash,
|
||||
number: NumberFor<Block>,
|
||||
) {
|
||||
self.network.service().set_sync_fork_request(peers, hash, number);
|
||||
}
|
||||
|
||||
/// Add blocks to the peer -- edit the block before adding
|
||||
pub fn generate_blocks<F>(&mut self, count: usize, origin: BlockOrigin, edit_block: F) -> H256
|
||||
where F: FnMut(BlockBuilder<Block, PeersFullClient, substrate_test_runtime_client::Backend>) -> Block
|
||||
pub fn generate_blocks<F>(
|
||||
&mut self,
|
||||
count: usize,
|
||||
origin: BlockOrigin,
|
||||
edit_block: F,
|
||||
) -> H256
|
||||
where
|
||||
F: FnMut(BlockBuilder<Block, PeersFullClient, substrate_test_runtime_client::Backend>) -> Block
|
||||
{
|
||||
let best_hash = self.client.info().best_hash;
|
||||
self.generate_blocks_at(BlockId::Hash(best_hash), count, origin, edit_block, false, true, true)
|
||||
@@ -320,19 +358,21 @@ impl<D> Peer<D> {
|
||||
block.header.parent_hash,
|
||||
);
|
||||
let header = block.header.clone();
|
||||
let (import_block, cache) = self.verifier.verify(
|
||||
let (import_block, cache) = futures::executor::block_on(self.verifier.verify(
|
||||
origin,
|
||||
header.clone(),
|
||||
None,
|
||||
if headers_only { None } else { Some(block.extrinsics) },
|
||||
).unwrap();
|
||||
)).unwrap();
|
||||
let cache = if let Some(cache) = cache {
|
||||
cache.into_iter().collect()
|
||||
} else {
|
||||
Default::default()
|
||||
};
|
||||
|
||||
self.block_import.import_block(import_block, cache).expect("block_import failed");
|
||||
futures::executor::block_on(
|
||||
self.block_import.import_block(import_block, cache)
|
||||
).expect("block_import failed");
|
||||
if announce_block {
|
||||
self.network.service().announce_block(hash, None);
|
||||
}
|
||||
@@ -478,102 +518,80 @@ impl<D> Peer<D> {
|
||||
}
|
||||
}
|
||||
|
||||
pub trait BlockImportAdapterFull:
|
||||
BlockImport<
|
||||
Block,
|
||||
Transaction = TransactionFor<substrate_test_runtime_client::Backend, Block>,
|
||||
Error = ConsensusError,
|
||||
> +
|
||||
Send +
|
||||
Sync +
|
||||
Clone
|
||||
{}
|
||||
|
||||
impl<T> BlockImportAdapterFull for T where
|
||||
T: BlockImport<
|
||||
Block,
|
||||
Transaction = TransactionFor<substrate_test_runtime_client::Backend, Block>,
|
||||
Error = ConsensusError,
|
||||
> +
|
||||
Send +
|
||||
Sync +
|
||||
Clone
|
||||
{}
|
||||
|
||||
/// Implements `BlockImport` for any `Transaction`. Internally the transaction is
|
||||
/// "converted", aka the field is set to `None`.
|
||||
///
|
||||
/// This is required as the `TestNetFactory` trait does not distinguish between
|
||||
/// full and light nodes.
|
||||
pub enum BlockImportAdapter<Transaction> {
|
||||
Full(
|
||||
Arc<Mutex<dyn BlockImport<
|
||||
Block,
|
||||
Transaction = TransactionFor<substrate_test_runtime_client::Backend, Block>,
|
||||
Error = ConsensusError
|
||||
> + Send>>,
|
||||
PhantomData<Transaction>,
|
||||
),
|
||||
Light(
|
||||
Arc<Mutex<dyn BlockImport<
|
||||
Block,
|
||||
Transaction = TransactionFor<substrate_test_runtime_client::LightBackend, Block>,
|
||||
Error = ConsensusError
|
||||
> + Send>>,
|
||||
PhantomData<Transaction>,
|
||||
),
|
||||
#[derive(Clone)]
|
||||
pub struct BlockImportAdapter<I> {
|
||||
inner: I,
|
||||
}
|
||||
|
||||
impl<Transaction> BlockImportAdapter<Transaction> {
|
||||
impl<I> BlockImportAdapter<I> {
|
||||
/// Create a new instance of `Self::Full`.
|
||||
pub fn new_full(
|
||||
full: impl BlockImport<
|
||||
Block,
|
||||
Transaction = TransactionFor<substrate_test_runtime_client::Backend, Block>,
|
||||
Error = ConsensusError
|
||||
>
|
||||
+ 'static
|
||||
+ Send
|
||||
) -> Self {
|
||||
Self::Full(Arc::new(Mutex::new(full)), PhantomData)
|
||||
}
|
||||
|
||||
/// Create a new instance of `Self::Light`.
|
||||
pub fn new_light(
|
||||
light: impl BlockImport<
|
||||
Block,
|
||||
Transaction = TransactionFor<substrate_test_runtime_client::LightBackend, Block>,
|
||||
Error = ConsensusError
|
||||
>
|
||||
+ 'static
|
||||
+ Send
|
||||
) -> Self {
|
||||
Self::Light(Arc::new(Mutex::new(light)), PhantomData)
|
||||
}
|
||||
}
|
||||
|
||||
impl<Transaction> Clone for BlockImportAdapter<Transaction> {
|
||||
fn clone(&self) -> Self {
|
||||
match self {
|
||||
Self::Full(full, _) => Self::Full(full.clone(), PhantomData),
|
||||
Self::Light(light, _) => Self::Light(light.clone(), PhantomData),
|
||||
pub fn new(inner: I) -> Self {
|
||||
Self {
|
||||
inner,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<Transaction> BlockImport<Block> for BlockImportAdapter<Transaction> {
|
||||
#[async_trait::async_trait]
|
||||
impl<I> BlockImport<Block> for BlockImportAdapter<I> where
|
||||
I: BlockImport<Block, Error = ConsensusError> + Send + Sync,
|
||||
I::Transaction: Send,
|
||||
{
|
||||
type Error = ConsensusError;
|
||||
type Transaction = Transaction;
|
||||
type Transaction = ();
|
||||
|
||||
fn check_block(
|
||||
async fn check_block(
|
||||
&mut self,
|
||||
block: BlockCheckParams<Block>,
|
||||
) -> Result<ImportResult, Self::Error> {
|
||||
match self {
|
||||
Self::Full(full, _) => full.lock().check_block(block),
|
||||
Self::Light(light, _) => light.lock().check_block(block),
|
||||
}
|
||||
self.inner.check_block(block).await
|
||||
}
|
||||
|
||||
fn import_block(
|
||||
async fn import_block(
|
||||
&mut self,
|
||||
block: BlockImportParams<Block, Transaction>,
|
||||
block: BlockImportParams<Block, ()>,
|
||||
cache: HashMap<well_known_cache_keys::Id, Vec<u8>>,
|
||||
) -> Result<ImportResult, Self::Error> {
|
||||
match self {
|
||||
Self::Full(full, _) => full.lock().import_block(block.convert_transaction(), cache),
|
||||
Self::Light(light, _) => light.lock().import_block(block.convert_transaction(), cache),
|
||||
}
|
||||
self.inner.import_block(block.convert_transaction(), cache).await
|
||||
}
|
||||
}
|
||||
|
||||
/// Implements `Verifier` on an `Arc<Mutex<impl Verifier>>`. Used internally.
|
||||
#[derive(Clone)]
|
||||
/// Implements `Verifier` and keeps track of failed verifications.
|
||||
struct VerifierAdapter<B: BlockT> {
|
||||
verifier: Arc<Mutex<Box<dyn Verifier<B>>>>,
|
||||
verifier: Arc<futures::lock::Mutex<Box<dyn Verifier<B>>>>,
|
||||
failed_verifications: Arc<Mutex<HashMap<B::Hash, String>>>,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl<B: BlockT> Verifier<B> for VerifierAdapter<B> {
|
||||
fn verify(
|
||||
async fn verify(
|
||||
&mut self,
|
||||
origin: BlockOrigin,
|
||||
header: B::Header,
|
||||
@@ -581,17 +599,26 @@ impl<B: BlockT> Verifier<B> for VerifierAdapter<B> {
|
||||
body: Option<Vec<B::Extrinsic>>
|
||||
) -> Result<(BlockImportParams<B, ()>, Option<Vec<(CacheKeyId, Vec<u8>)>>), String> {
|
||||
let hash = header.hash();
|
||||
self.verifier.lock().verify(origin, header, justifications, body).map_err(|e| {
|
||||
self.verifier.lock().await.verify(origin, header, justifications, body).await.map_err(|e| {
|
||||
self.failed_verifications.lock().insert(hash, e.clone());
|
||||
e
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<B: BlockT> Clone for VerifierAdapter<B> {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
verifier: self.verifier.clone(),
|
||||
failed_verifications: self.failed_verifications.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<B: BlockT> VerifierAdapter<B> {
|
||||
fn new(verifier: Arc<Mutex<Box<dyn Verifier<B>>>>) -> VerifierAdapter<B> {
|
||||
fn new(verifier: impl Verifier<B> + 'static) -> Self {
|
||||
VerifierAdapter {
|
||||
verifier,
|
||||
verifier: Arc::new(futures::lock::Mutex::new(Box::new(verifier))),
|
||||
failed_verifications: Default::default(),
|
||||
}
|
||||
}
|
||||
@@ -614,8 +641,9 @@ pub struct FullPeerConfig {
|
||||
pub is_authority: bool,
|
||||
}
|
||||
|
||||
pub trait TestNetFactory: Sized {
|
||||
pub trait TestNetFactory: Sized where <Self::BlockImport as BlockImport<Block>>::Transaction: Send {
|
||||
type Verifier: 'static + Verifier<Block>;
|
||||
type BlockImport: BlockImport<Block, Error = ConsensusError> + Clone + Send + Sync + 'static;
|
||||
type PeerData: Default;
|
||||
|
||||
/// These two need to be implemented!
|
||||
@@ -628,23 +656,20 @@ pub trait TestNetFactory: Sized {
|
||||
) -> Self::Verifier;
|
||||
|
||||
/// Get reference to peer.
|
||||
fn peer(&mut self, i: usize) -> &mut Peer<Self::PeerData>;
|
||||
fn peers(&self) -> &Vec<Peer<Self::PeerData>>;
|
||||
fn mut_peers<F: FnOnce(&mut Vec<Peer<Self::PeerData>>)>(
|
||||
fn peer(&mut self, i: usize) -> &mut Peer<Self::PeerData, Self::BlockImport>;
|
||||
fn peers(&self) -> &Vec<Peer<Self::PeerData, Self::BlockImport>>;
|
||||
fn mut_peers<F: FnOnce(&mut Vec<Peer<Self::PeerData, Self::BlockImport>>)>(
|
||||
&mut self,
|
||||
closure: F,
|
||||
);
|
||||
|
||||
/// Get custom block import handle for fresh client, along with peer data.
|
||||
fn make_block_import<Transaction>(&self, client: PeersClient)
|
||||
fn make_block_import(&self, client: PeersClient)
|
||||
-> (
|
||||
BlockImportAdapter<Transaction>,
|
||||
BlockImportAdapter<Self::BlockImport>,
|
||||
Option<BoxJustificationImport<Block>>,
|
||||
Self::PeerData,
|
||||
)
|
||||
{
|
||||
(client.as_block_import(), None, Default::default())
|
||||
}
|
||||
);
|
||||
|
||||
fn default_config() -> ProtocolConfig {
|
||||
ProtocolConfig::default()
|
||||
@@ -688,7 +713,7 @@ pub trait TestNetFactory: Sized {
|
||||
&Default::default(),
|
||||
&data,
|
||||
);
|
||||
let verifier = VerifierAdapter::new(Arc::new(Mutex::new(Box::new(verifier) as Box<_>)));
|
||||
let verifier = VerifierAdapter::new(verifier);
|
||||
|
||||
let import_queue = Box::new(BasicQueue::new(
|
||||
verifier.clone(),
|
||||
@@ -776,7 +801,7 @@ pub trait TestNetFactory: Sized {
|
||||
|
||||
peers.push(Peer {
|
||||
data,
|
||||
client: PeersClient::Full(client, backend.clone()),
|
||||
client: PeersClient::Full(client.clone(), backend.clone()),
|
||||
select_chain: Some(longest_chain),
|
||||
backend: Some(backend),
|
||||
imported_blocks_stream,
|
||||
@@ -804,7 +829,7 @@ pub trait TestNetFactory: Sized {
|
||||
&Default::default(),
|
||||
&data,
|
||||
);
|
||||
let verifier = VerifierAdapter::new(Arc::new(Mutex::new(Box::new(verifier) as Box<_>)));
|
||||
let verifier = VerifierAdapter::new(verifier);
|
||||
|
||||
let import_queue = Box::new(BasicQueue::new(
|
||||
verifier.clone(),
|
||||
@@ -986,7 +1011,7 @@ pub trait TestNetFactory: Sized {
|
||||
}
|
||||
|
||||
pub struct TestNet {
|
||||
peers: Vec<Peer<()>>,
|
||||
peers: Vec<Peer<(), PeersClient>>,
|
||||
fork_choice: ForkChoiceStrategy,
|
||||
}
|
||||
|
||||
@@ -1003,6 +1028,7 @@ impl TestNet {
|
||||
impl TestNetFactory for TestNet {
|
||||
type Verifier = PassThroughVerifier;
|
||||
type PeerData = ();
|
||||
type BlockImport = PeersClient;
|
||||
|
||||
/// Create new test network with peers and given config.
|
||||
fn from_config(_config: &ProtocolConfig) -> Self {
|
||||
@@ -1018,15 +1044,25 @@ impl TestNetFactory for TestNet {
|
||||
PassThroughVerifier::new_with_fork_choice(false, self.fork_choice.clone())
|
||||
}
|
||||
|
||||
fn peer(&mut self, i: usize) -> &mut Peer<()> {
|
||||
fn make_block_import(&self, client: PeersClient)
|
||||
-> (
|
||||
BlockImportAdapter<Self::BlockImport>,
|
||||
Option<BoxJustificationImport<Block>>,
|
||||
Self::PeerData,
|
||||
)
|
||||
{
|
||||
(client.as_block_import(), None, ())
|
||||
}
|
||||
|
||||
fn peer(&mut self, i: usize) -> &mut Peer<(), Self::BlockImport> {
|
||||
&mut self.peers[i]
|
||||
}
|
||||
|
||||
fn peers(&self) -> &Vec<Peer<()>> {
|
||||
fn peers(&self) -> &Vec<Peer<(), Self::BlockImport>> {
|
||||
&self.peers
|
||||
}
|
||||
|
||||
fn mut_peers<F: FnOnce(&mut Vec<Peer<()>>)>(&mut self, closure: F) {
|
||||
fn mut_peers<F: FnOnce(&mut Vec<Peer<(), Self::BlockImport>>)>(&mut self, closure: F) {
|
||||
closure(&mut self.peers);
|
||||
}
|
||||
}
|
||||
@@ -1052,6 +1088,7 @@ pub struct JustificationTestNet(TestNet);
|
||||
impl TestNetFactory for JustificationTestNet {
|
||||
type Verifier = PassThroughVerifier;
|
||||
type PeerData = ();
|
||||
type BlockImport = PeersClient;
|
||||
|
||||
fn from_config(config: &ProtocolConfig) -> Self {
|
||||
JustificationTestNet(TestNet::from_config(config))
|
||||
@@ -1061,23 +1098,23 @@ impl TestNetFactory for JustificationTestNet {
|
||||
self.0.make_verifier(client, config, peer_data)
|
||||
}
|
||||
|
||||
fn peer(&mut self, i: usize) -> &mut Peer<Self::PeerData> {
|
||||
fn peer(&mut self, i: usize) -> &mut Peer<Self::PeerData, Self::BlockImport> {
|
||||
self.0.peer(i)
|
||||
}
|
||||
|
||||
fn peers(&self) -> &Vec<Peer<Self::PeerData>> {
|
||||
fn peers(&self) -> &Vec<Peer<Self::PeerData, Self::BlockImport>> {
|
||||
self.0.peers()
|
||||
}
|
||||
|
||||
fn mut_peers<F: FnOnce(
|
||||
&mut Vec<Peer<Self::PeerData>>,
|
||||
&mut Vec<Peer<Self::PeerData, Self::BlockImport>>,
|
||||
)>(&mut self, closure: F) {
|
||||
self.0.mut_peers(closure)
|
||||
}
|
||||
|
||||
fn make_block_import<Transaction>(&self, client: PeersClient)
|
||||
fn make_block_import(&self, client: PeersClient)
|
||||
-> (
|
||||
BlockImportAdapter<Transaction>,
|
||||
BlockImportAdapter<Self::BlockImport>,
|
||||
Option<BoxJustificationImport<Block>>,
|
||||
Self::PeerData,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user