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:
Svyatoslav Nikolsky
2019-05-13 12:36:52 +03:00
committed by Gavin Wood
parent 258f0835e4
commit 22586113ea
36 changed files with 3320 additions and 803 deletions
@@ -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);
}
+280 -72
View File
@@ -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())
}
}
+32 -33
View File
@@ -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]