mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 22:11:02 +00:00
initial test to ensure auxiliary data is generated correctly
This commit is contained in:
@@ -39,11 +39,7 @@ impl<H, N> SharedAuthoritySet<H, N> {
|
||||
/// The genesis authority set.
|
||||
pub(crate) fn genesis(initial: Vec<(AuthorityId, u64)>) -> Self {
|
||||
SharedAuthoritySet {
|
||||
inner: Arc::new(RwLock::new(AuthoritySet {
|
||||
current_authorities: initial,
|
||||
set_id: 0,
|
||||
pending_changes: Vec::new(),
|
||||
}))
|
||||
inner: Arc::new(RwLock::new(AuthoritySet::genesis(initial)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,6 +87,15 @@ pub(crate) struct AuthoritySet<H, N> {
|
||||
}
|
||||
|
||||
impl<H, N> AuthoritySet<H, N> {
|
||||
/// Get a genesis set with given authorities.
|
||||
pub(crate) fn genesis(initial: Vec<(AuthorityId, u64)>) -> Self {
|
||||
AuthoritySet {
|
||||
current_authorities: initial,
|
||||
set_id: 0,
|
||||
pending_changes: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the current set id and a reference to the current authority set.
|
||||
pub(crate) fn current(&self) -> (u64, &[(AuthorityId, u64)]) {
|
||||
(self.set_id, &self.current_authorities[..])
|
||||
@@ -113,6 +118,12 @@ impl<H: Eq, N> AuthoritySet<H, N>
|
||||
|
||||
self.pending_changes.insert(idx, pending);
|
||||
}
|
||||
|
||||
/// Inspect pending changes.
|
||||
pub(crate) fn pending_changes(&self) -> &[PendingChange<H, N>] {
|
||||
&self.pending_changes
|
||||
}
|
||||
|
||||
/// Get the earliest limit-block number, if any.
|
||||
pub(crate) fn current_limit(&self) -> Option<N> {
|
||||
self.pending_changes.get(0).map(|change| change.effective_number().clone())
|
||||
|
||||
@@ -1,3 +1,21 @@
|
||||
// Copyright 2018 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! Tests and test helpers for GRANDPA.
|
||||
|
||||
use super::*;
|
||||
use network::test::{Block, Hash, TestNetFactory, Peer, PeersClient};
|
||||
use network::import_queue::{PassThroughVerifier};
|
||||
@@ -7,6 +25,10 @@ use tokio::runtime::current_thread;
|
||||
use keyring::Keyring;
|
||||
use client::BlockchainEvents;
|
||||
use test_client::{self, runtime::BlockNumber};
|
||||
use codec::Decode;
|
||||
use consensus_common::BlockOrigin;
|
||||
|
||||
use authorities::AuthoritySet;
|
||||
|
||||
type PeerData = Mutex<Option<LinkHalf<test_client::Backend, test_client::Executor, Block>>>;
|
||||
type GrandpaPeer = Peer<PassThroughVerifier, PeerData>;
|
||||
@@ -135,14 +157,14 @@ impl Network for MessageRouting {
|
||||
#[derive(Default, Clone)]
|
||||
struct TestApi {
|
||||
genesis_authorities: Vec<(AuthorityId, u64)>,
|
||||
scheduled_changes: HashMap<BlockNumber, ScheduledChange<BlockNumber>>,
|
||||
scheduled_changes: Arc<Mutex<HashMap<Hash, ScheduledChange<BlockNumber>>>>,
|
||||
}
|
||||
|
||||
impl TestApi {
|
||||
fn new(genesis_authorities: Vec<(AuthorityId, u64)>) -> Self {
|
||||
TestApi {
|
||||
genesis_authorities,
|
||||
scheduled_changes: HashMap::new(),
|
||||
scheduled_changes: Arc::new(Mutex::new(HashMap::new())),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -157,20 +179,29 @@ impl ApiClient<Block> for TestApi {
|
||||
{
|
||||
// we take only scheduled changes at given block number where there are no
|
||||
// extrinsics.
|
||||
Ok(self.scheduled_changes.get(header.number()).map(|c| c.clone()))
|
||||
let change = self.scheduled_changes.lock().get(&header.hash()).map(|c| c.clone());
|
||||
if change.is_some() {
|
||||
println!("Found transition for {:?}", header.hash());
|
||||
}
|
||||
|
||||
Ok(change)
|
||||
}
|
||||
}
|
||||
|
||||
const TEST_GOSSIP_DURATION: Duration = Duration::from_millis(500);
|
||||
const TEST_ROUTING_INTERVAL: Duration = Duration::from_millis(50);
|
||||
|
||||
fn make_ids(keys: &[Keyring]) -> Vec<(AuthorityId, u64)> {
|
||||
keys.iter()
|
||||
.map(|key| AuthorityId(key.to_raw_public()))
|
||||
.map(|id| (id, 1))
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn finalize_3_voters_no_observers() {
|
||||
let peers = &[Keyring::Alice, Keyring::Bob, Keyring::Charlie];
|
||||
let voters: Vec<_> = peers.iter()
|
||||
.map(|key| AuthorityId(key.to_raw_public()))
|
||||
.map(|id| (id, 1))
|
||||
.collect();
|
||||
let voters = make_ids(peers);
|
||||
|
||||
let mut net = GrandpaTestNet::new(TestApi::new(voters), 3);
|
||||
net.peer(0).push_blocks(20, false);
|
||||
@@ -229,10 +260,7 @@ fn finalize_3_voters_no_observers() {
|
||||
#[test]
|
||||
fn finalize_3_voters_1_observer() {
|
||||
let peers = &[Keyring::Alice, Keyring::Bob, Keyring::Charlie];
|
||||
let voters: Vec<_> = peers.iter()
|
||||
.map(|key| AuthorityId(key.to_raw_public()))
|
||||
.map(|id| (id, 1))
|
||||
.collect();
|
||||
let voters = make_ids(peers);
|
||||
|
||||
let mut net = GrandpaTestNet::new(TestApi::new(voters), 4);
|
||||
net.peer(0).push_blocks(20, false);
|
||||
@@ -285,3 +313,128 @@ fn finalize_3_voters_1_observer() {
|
||||
|
||||
runtime.block_on(wait_for.select(drive_to_completion).map_err(|_| ())).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn transition_3_voters_twice_1_observer() {
|
||||
let peers_a = &[
|
||||
Keyring::Alice,
|
||||
Keyring::Bob,
|
||||
Keyring::Charlie,
|
||||
];
|
||||
|
||||
let peers_b = &[
|
||||
Keyring::Dave,
|
||||
Keyring::Eve,
|
||||
Keyring::Ferdie,
|
||||
];
|
||||
|
||||
let peers_c = &[
|
||||
Keyring::Alice,
|
||||
Keyring::Eve,
|
||||
Keyring::Two,
|
||||
];
|
||||
|
||||
let observer = &[Keyring::One];
|
||||
|
||||
let genesis_voters = make_ids(peers_a);
|
||||
|
||||
let api = TestApi::new(genesis_voters);
|
||||
let transitions = api.scheduled_changes.clone();
|
||||
let add_transition = move |hash, change| {
|
||||
transitions.lock().insert(hash, change);
|
||||
};
|
||||
|
||||
let mut net = GrandpaTestNet::new(api, 8);
|
||||
|
||||
// first 20 blocks: transition at 15, applied at 20.
|
||||
{
|
||||
net.peer(0).push_blocks(14, false);
|
||||
net.peer(0).generate_blocks(1, BlockOrigin::File, |builder| {
|
||||
let block = builder.bake().unwrap();
|
||||
println!("Adding transition for {:?}", block.header.hash());
|
||||
add_transition(block.header.hash(), ScheduledChange {
|
||||
next_authorities: make_ids(peers_b),
|
||||
delay: 4,
|
||||
});
|
||||
|
||||
block
|
||||
});
|
||||
net.peer(0).push_blocks(5, false);
|
||||
}
|
||||
|
||||
// at block 21 we do another transition, but this time instant.
|
||||
// add more until we have 30.
|
||||
{
|
||||
net.peer(0).generate_blocks(1, BlockOrigin::File, |builder| {
|
||||
let block = builder.bake().unwrap();
|
||||
println!("Adding transition for {:?}", block.header.hash());
|
||||
add_transition(block.header.hash(), ScheduledChange {
|
||||
next_authorities: make_ids(peers_c),
|
||||
delay: 0,
|
||||
});
|
||||
|
||||
block
|
||||
});
|
||||
|
||||
net.peer(0).push_blocks(9, false);
|
||||
}
|
||||
net.sync();
|
||||
|
||||
for (i, peer) in net.peers().iter().enumerate() {
|
||||
assert_eq!(peer.client().info().unwrap().chain.best_number, 30,
|
||||
"Peer #{} failed to sync", i);
|
||||
|
||||
let set_raw = peer.client().backend().get_aux(::AUTHORITY_SET_KEY).unwrap().unwrap();
|
||||
let set = AuthoritySet::<Hash, BlockNumber>::decode(&mut &set_raw[..]).unwrap();
|
||||
|
||||
assert_eq!(set.current(), (0, make_ids(peers_a).as_slice()));
|
||||
assert_eq!(set.pending_changes().len(), 2);
|
||||
}
|
||||
|
||||
// let net = Arc::new(Mutex::new(net));
|
||||
// let mut finality_notifications = Vec::new();
|
||||
|
||||
// let mut runtime = current_thread::Runtime::new().unwrap();
|
||||
// let all_peers = peers.iter()
|
||||
// .cloned()
|
||||
// .map(|key| Some(Arc::new(key.into())))
|
||||
// .chain(::std::iter::once(None));
|
||||
|
||||
// for (peer_id, local_key) in all_peers.enumerate() {
|
||||
// let (client, link) = {
|
||||
// let mut net = net.lock();
|
||||
// let link = net.peers[peer_id].data.lock().take().expect("link initialized at startup; qed");
|
||||
// (
|
||||
// net.peers[peer_id].client().clone(),
|
||||
// link,
|
||||
// )
|
||||
// };
|
||||
// finality_notifications.push(
|
||||
// client.finality_notification_stream()
|
||||
// .take_while(|n| Ok(n.header.number() < &20))
|
||||
// .for_each(move |_| Ok(()))
|
||||
// );
|
||||
// let voter = run_grandpa(
|
||||
// Config {
|
||||
// gossip_duration: TEST_GOSSIP_DURATION,
|
||||
// local_key,
|
||||
// },
|
||||
// link,
|
||||
// MessageRouting::new(net.clone(), peer_id),
|
||||
// ).expect("all in order with client and network");
|
||||
|
||||
// runtime.spawn(voter);
|
||||
// }
|
||||
|
||||
// // wait for all finalized on each.
|
||||
// let wait_for = ::futures::future::join_all(finality_notifications)
|
||||
// .map(|_| ())
|
||||
// .map_err(|_| ());
|
||||
|
||||
// let drive_to_completion = ::tokio::timer::Interval::new_interval(TEST_ROUTING_INTERVAL)
|
||||
// .for_each(move |_| { net.lock().route_until_complete(); Ok(()) })
|
||||
// .map(|_| ())
|
||||
// .map_err(|_| ());
|
||||
|
||||
// runtime.block_on(wait_for.select(drive_to_completion).map_err(|_| ())).unwrap();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user