client/network-gossip: Integrate GossipEngine tasks into Future impl (#4767)

`GossipEngine` spawns two tasks, one for a periodic tick, one to forward
messages from the network to subscribers. These tasks hold an `Arc` to a
`GossipEngineInner`.

To reduce the amount of shared ownership (locking) this patch integrates
the two tasks into a `Future` implementation on the `GossipEngine`
struct. This `Future` implementation can now be called from a single
owner, e.g. the `finality-grandpa` `NetworkBridge`.

As a side effect this removes the requirement on the `network-gossip`
crate to spawn tasks and thereby removes the requirement on the
`finality-grandpa` crate to spawn any tasks.

This is part of a greater effort to reduce the number of owners of
components within `finality-grandpa`, `network` and `network-gossip` as
well as to reduce the amount of unbounded channels. For details see
d9837d7dd, 5f80929dc and 597c0a6c4.
This commit is contained in:
Max Inden
2020-02-12 13:15:26 +01:00
committed by GitHub
parent 13971fe2a7
commit 3f3910ccaf
9 changed files with 121 additions and 155 deletions
+18 -44
View File
@@ -387,7 +387,6 @@ fn block_until_complete(future: impl Future + Unpin, net: &Arc<Mutex<GrandpaTest
// the voters are spawned but before blocking on them.
fn run_to_completion_with<F>(
runtime: &mut current_thread::Runtime,
threads_pool: &futures::executor::ThreadPool,
blocks: u64,
net: Arc<Mutex<GrandpaTestNet>>,
peers: &[Ed25519Keyring],
@@ -454,7 +453,6 @@ fn run_to_completion_with<F>(
on_exit: Exit,
telemetry_on_connect: None,
voting_rule: (),
executor: threads_pool.clone(),
};
let voter = run_grandpa_voter(grandpa_params).expect("all in order with client and network");
@@ -473,12 +471,11 @@ fn run_to_completion_with<F>(
fn run_to_completion(
runtime: &mut current_thread::Runtime,
threads_pool: &futures::executor::ThreadPool,
blocks: u64,
net: Arc<Mutex<GrandpaTestNet>>,
peers: &[Ed25519Keyring]
) -> u64 {
run_to_completion_with(runtime, threads_pool, blocks, net, peers, |_| None)
run_to_completion_with(runtime, blocks, net, peers, |_| None)
}
fn add_scheduled_change(block: &mut Block, change: ScheduledChange<BlockNumber>) {
@@ -499,17 +496,10 @@ fn add_forced_change(
));
}
fn thread_pool() -> futures::executor::ThreadPool {
futures::executor::ThreadPool::builder().pool_size(2)
.create()
.expect("never fails")
}
#[test]
fn finalize_3_voters_no_observers() {
let _ = env_logger::try_init();
let mut runtime = current_thread::Runtime::new().unwrap();
let threads_pool = thread_pool();
let peers = &[Ed25519Keyring::Alice, Ed25519Keyring::Bob, Ed25519Keyring::Charlie];
let voters = make_ids(peers);
@@ -523,7 +513,7 @@ fn finalize_3_voters_no_observers() {
}
let net = Arc::new(Mutex::new(net));
run_to_completion(&mut runtime, &threads_pool, 20, net.clone(), peers);
run_to_completion(&mut runtime, 20, net.clone(), peers);
// normally there's no justification for finalized blocks
assert!(
@@ -535,7 +525,6 @@ fn finalize_3_voters_no_observers() {
#[test]
fn finalize_3_voters_1_full_observer() {
let mut runtime = current_thread::Runtime::new().unwrap();
let threads_pool = thread_pool();
let peers = &[Ed25519Keyring::Alice, Ed25519Keyring::Bob, Ed25519Keyring::Charlie];
let voters = make_ids(peers);
@@ -595,7 +584,6 @@ fn finalize_3_voters_1_full_observer() {
on_exit: Exit,
telemetry_on_connect: None,
voting_rule: (),
executor: threads_pool.clone(),
};
voters.push(run_grandpa_voter(grandpa_params).expect("all in order with client and network"));
@@ -641,7 +629,6 @@ fn transition_3_voters_twice_1_full_observer() {
let net = Arc::new(Mutex::new(GrandpaTestNet::new(api, 8)));
let mut runtime = current_thread::Runtime::new().unwrap();
let threads_pool = thread_pool();
net.lock().peer(0).push_blocks(1, false);
net.lock().block_until_sync(&mut runtime);
@@ -760,7 +747,6 @@ fn transition_3_voters_twice_1_full_observer() {
on_exit: Exit,
telemetry_on_connect: None,
voting_rule: (),
executor: threads_pool.clone(),
};
let voter = run_grandpa_voter(grandpa_params).expect("all in order with client and network");
@@ -776,7 +762,6 @@ fn transition_3_voters_twice_1_full_observer() {
#[test]
fn justification_is_emitted_when_consensus_data_changes() {
let mut runtime = current_thread::Runtime::new().unwrap();
let threads_pool = thread_pool();
let peers = &[Ed25519Keyring::Alice, Ed25519Keyring::Bob, Ed25519Keyring::Charlie];
let mut net = GrandpaTestNet::new(TestApi::new(make_ids(peers)), 3);
@@ -785,7 +770,7 @@ fn justification_is_emitted_when_consensus_data_changes() {
net.peer(0).push_authorities_change_block(new_authorities);
net.block_until_sync(&mut runtime);
let net = Arc::new(Mutex::new(net));
run_to_completion(&mut runtime, &threads_pool, 1, net.clone(), peers);
run_to_completion(&mut runtime, 1, net.clone(), peers);
// ... and check that there's justification for block#1
assert!(net.lock().peer(0).client().justification(&BlockId::Number(1)).unwrap().is_some(),
@@ -795,7 +780,6 @@ fn justification_is_emitted_when_consensus_data_changes() {
#[test]
fn justification_is_generated_periodically() {
let mut runtime = current_thread::Runtime::new().unwrap();
let threads_pool = thread_pool();
let peers = &[Ed25519Keyring::Alice, Ed25519Keyring::Bob, Ed25519Keyring::Charlie];
let voters = make_ids(peers);
@@ -804,7 +788,7 @@ fn justification_is_generated_periodically() {
net.block_until_sync(&mut runtime);
let net = Arc::new(Mutex::new(net));
run_to_completion(&mut runtime, &threads_pool, 32, net.clone(), peers);
run_to_completion(&mut runtime, 32, net.clone(), peers);
// when block#32 (justification_period) is finalized, justification
// is required => generated
@@ -835,7 +819,6 @@ fn consensus_changes_works() {
#[test]
fn sync_justifications_on_change_blocks() {
let mut runtime = current_thread::Runtime::new().unwrap();
let threads_pool = thread_pool();
let peers_a = &[Ed25519Keyring::Alice, Ed25519Keyring::Bob, Ed25519Keyring::Charlie];
let peers_b = &[Ed25519Keyring::Alice, Ed25519Keyring::Bob];
let voters = make_ids(peers_b);
@@ -867,7 +850,7 @@ fn sync_justifications_on_change_blocks() {
}
let net = Arc::new(Mutex::new(net));
run_to_completion(&mut runtime, &threads_pool, 25, net.clone(), peers_a);
run_to_completion(&mut runtime, 25, net.clone(), peers_a);
// the first 3 peers are grandpa voters and therefore have already finalized
// block 21 and stored a justification
@@ -890,7 +873,6 @@ fn sync_justifications_on_change_blocks() {
fn finalizes_multiple_pending_changes_in_order() {
let _ = env_logger::try_init();
let mut runtime = current_thread::Runtime::new().unwrap();
let threads_pool = thread_pool();
let peers_a = &[Ed25519Keyring::Alice, Ed25519Keyring::Bob, Ed25519Keyring::Charlie];
let peers_b = &[Ed25519Keyring::Dave, Ed25519Keyring::Eve, Ed25519Keyring::Ferdie];
@@ -944,14 +926,13 @@ fn finalizes_multiple_pending_changes_in_order() {
}
let net = Arc::new(Mutex::new(net));
run_to_completion(&mut runtime, &threads_pool, 30, net.clone(), all_peers);
run_to_completion(&mut runtime, 30, net.clone(), all_peers);
}
#[test]
fn force_change_to_new_set() {
let _ = env_logger::try_init();
let mut runtime = current_thread::Runtime::new().unwrap();
let threads_pool = thread_pool();
// two of these guys are offline.
let genesis_authorities = &[
Ed25519Keyring::Alice,
@@ -1002,7 +983,7 @@ fn force_change_to_new_set() {
// it will only finalize if the forced transition happens.
// we add_blocks after the voters are spawned because otherwise
// the link-halfs have the wrong AuthoritySet
run_to_completion(&mut runtime, &threads_pool, 25, net, peers_a);
run_to_completion(&mut runtime, 25, net, peers_a);
}
#[test]
@@ -1132,7 +1113,6 @@ fn voter_persists_its_votes() {
let _ = env_logger::try_init();
let mut runtime = current_thread::Runtime::new().unwrap();
let threads_pool = thread_pool();
// we have two authorities but we'll only be running the voter for alice
// we are going to be listening for the prevotes it casts
@@ -1171,7 +1151,6 @@ fn voter_persists_its_votes() {
net: Arc<Mutex<GrandpaTestNet>>,
client: PeersClient,
keystore: KeyStorePtr,
threads_pool: futures::executor::ThreadPool,
}
impl Future for ResettableVoter {
@@ -1210,7 +1189,6 @@ fn voter_persists_its_votes() {
on_exit: Exit,
telemetry_on_connect: None,
voting_rule: VotingRulesBuilder::default().build(),
executor: this.threads_pool.clone(),
};
let voter = run_grandpa_voter(grandpa_params)
@@ -1242,7 +1220,6 @@ fn voter_persists_its_votes() {
net: net.clone(),
client: client.clone(),
keystore,
threads_pool: threads_pool.clone(),
}.unit_error().compat());
}
@@ -1278,7 +1255,6 @@ fn voter_persists_its_votes() {
net.lock().peers[1].network_service().clone(),
config.clone(),
set_state,
&threads_pool,
);
let (round_rx, round_tx) = network.round_communication(
@@ -1289,6 +1265,11 @@ fn voter_persists_its_votes() {
HasVoted::No,
);
runtime.spawn(
network.map_err(|e| panic!("network bridge should not error: {:?}", e))
.compat(),
);
let round_tx = Arc::new(Mutex::new(round_tx));
let exit_tx = Arc::new(Mutex::new(Some(exit_tx)));
@@ -1389,7 +1370,6 @@ fn voter_persists_its_votes() {
fn finalize_3_voters_1_light_observer() {
let _ = env_logger::try_init();
let mut runtime = current_thread::Runtime::new().unwrap();
let threads_pool = thread_pool();
let authorities = &[Ed25519Keyring::Alice, Ed25519Keyring::Bob, Ed25519Keyring::Charlie];
let voters = make_ids(authorities);
@@ -1406,10 +1386,12 @@ fn finalize_3_voters_1_light_observer() {
let link = net.lock().peer(3).data.lock().take().expect("link initialized on startup; qed");
let finality_notifications = net.lock().peer(3).client().finality_notification_stream()
.take_while(|n| future::ready(n.header.number() < &20))
.take_while(|n| {
future::ready(n.header.number() < &20)
})
.collect::<Vec<_>>();
run_to_completion_with(&mut runtime, &threads_pool, 20, net.clone(), authorities, |executor| {
run_to_completion_with(&mut runtime, 20, net.clone(), authorities, |executor| {
executor.spawn(
run_grandpa_observer(
Config {
@@ -1423,7 +1405,6 @@ fn finalize_3_voters_1_light_observer() {
link,
net.lock().peers[3].network_service().clone(),
Exit,
threads_pool.clone(),
).unwrap().unit_error().compat()
).unwrap();
@@ -1435,7 +1416,6 @@ fn finalize_3_voters_1_light_observer() {
fn finality_proof_is_fetched_by_light_client_when_consensus_data_changes() {
let _ = ::env_logger::try_init();
let mut runtime = current_thread::Runtime::new().unwrap();
let threads_pool = thread_pool();
let peers = &[Ed25519Keyring::Alice];
let mut net = GrandpaTestNet::new(TestApi::new(make_ids(peers)), 1);
@@ -1445,7 +1425,7 @@ fn finality_proof_is_fetched_by_light_client_when_consensus_data_changes() {
// && instead fetches finality proof for block #1
net.peer(0).push_authorities_change_block(vec![sp_consensus_babe::AuthorityId::from_slice(&[42; 32])]);
let net = Arc::new(Mutex::new(net));
run_to_completion(&mut runtime, &threads_pool, 1, net.clone(), peers);
run_to_completion(&mut runtime, 1, net.clone(), peers);
net.lock().block_until_sync(&mut runtime);
// check that the block#1 is finalized on light client
@@ -1467,7 +1447,6 @@ fn empty_finality_proof_is_returned_to_light_client_when_authority_set_is_differ
let _ = ::env_logger::try_init();
let mut runtime = current_thread::Runtime::new().unwrap();
let threads_pool = thread_pool();
// two of these guys are offline.
let genesis_authorities = if FORCE_CHANGE {
@@ -1515,7 +1494,7 @@ fn empty_finality_proof_is_returned_to_light_client_when_authority_set_is_differ
net.lock().block_until_sync(&mut runtime);
// finalize block #11 on full clients
run_to_completion(&mut runtime, &threads_pool, 11, net.clone(), peers_a);
run_to_completion(&mut runtime, 11, net.clone(), peers_a);
// request finalization by light client
net.lock().add_light_peer(&GrandpaTestNet::default_config());
@@ -1532,7 +1511,6 @@ fn empty_finality_proof_is_returned_to_light_client_when_authority_set_is_differ
fn voter_catches_up_to_latest_round_when_behind() {
let _ = env_logger::try_init();
let mut runtime = current_thread::Runtime::new().unwrap();
let threads_pool = thread_pool();
let peers = &[Ed25519Keyring::Alice, Ed25519Keyring::Bob];
let voters = make_ids(peers);
@@ -1560,7 +1538,6 @@ fn voter_catches_up_to_latest_round_when_behind() {
on_exit: Exit,
telemetry_on_connect: None,
voting_rule: (),
executor: threads_pool.clone(),
};
Box::pin(run_grandpa_voter(grandpa_params).expect("all in order with client and network"))
@@ -1652,8 +1629,6 @@ fn grandpa_environment_respects_voting_rules() {
use finality_grandpa::Chain;
use sc_network_test::TestClient;
let threads_pool = thread_pool();
let peers = &[Ed25519Keyring::Alice];
let voters = make_ids(peers);
@@ -1684,7 +1659,6 @@ fn grandpa_environment_respects_voting_rules() {
network_service.clone(),
config.clone(),
set_state.clone(),
&threads_pool,
);
Environment {