Extract syncing protocol from sc-network (#12828)

* Move import queue out of `sc-network`

Add supplementary asynchronous API for the import queue which means
it can be run as an independent task and communicated with through
the `ImportQueueService`.

This commit removes removes block and justification imports from
`sc-network` and provides `ChainSync` with a handle to import queue so
it can import blocks and justifications. Polling of the import queue is
moved complete out of `sc-network` and `sc_consensus::Link` is
implemented for `ChainSyncInterfaceHandled` so the import queue
can still influence the syncing process.

* Move stuff to SyncingEngine

* Move `ChainSync` instanation to `SyncingEngine`

Some of the tests have to be rewritten

* Move peer hashmap to `SyncingEngine`

* Let `SyncingEngine` to implement `ChainSyncInterface`

* Introduce `SyncStatusProvider`

* Move `sync_peer_(connected|disconnected)` to `SyncingEngine`

* Implement `SyncEventStream`

Remove `SyncConnected`/`SyncDisconnected` events from
`NetworkEvenStream` and provide those events through
`ChainSyncInterface` instead.

Modify BEEFY/GRANDPA/transactions protocol and `NetworkGossip` to take
`SyncEventStream` object which they listen to for incoming sync peer
events.

* Introduce `ChainSyncInterface`

This interface provides a set of miscellaneous functions that other
subsystems can use to query, for example, the syncing status.

* Move event stream polling to `SyncingEngine`

Subscribe to `NetworkStreamEvent` and poll the incoming notifications
and substream events from `SyncingEngine`.

The code needs refactoring.

* Make `SyncingEngine` into an asynchronous runner

This commits removes the last hard dependency of syncing from
`sc-network` meaning the protocol now lives completely outside of
`sc-network`, ignoring the hardcoded peerset entry which will be
addressed in the future.

Code needs a lot of refactoring.

* Fix warnings

* Code refactoring

* Use `SyncingService` for BEEFY

* Use `SyncingService` for GRANDPA

* Remove call delegation from `NetworkService`

* Remove `ChainSyncService`

* Remove `ChainSync` service tests

They were written for the sole purpose of verifying that `NetworWorker`
continues to function while the calls are being dispatched to
`ChainSync`.

* Refactor code

* Refactor code

* Update client/finality-grandpa/src/communication/tests.rs

Co-authored-by: Anton <anton.kalyaev@gmail.com>

* Fix warnings

* Apply review comments

* Fix docs

* Fix test

* cargo-fmt

* Update client/network/sync/src/engine.rs

Co-authored-by: Anton <anton.kalyaev@gmail.com>

* Update client/network/sync/src/engine.rs

Co-authored-by: Anton <anton.kalyaev@gmail.com>

* Add missing docs

* Refactor code

---------

Co-authored-by: Anton <anton.kalyaev@gmail.com>
This commit is contained in:
Aaro Altonen
2023-03-06 18:33:38 +02:00
committed by GitHub
parent 8adde84330
commit 1a7f5be07f
57 changed files with 2904 additions and 2877 deletions
+15 -12
View File
@@ -652,12 +652,12 @@ async fn imports_stale_once() {
// check that NEW block is imported from announce message
let new_hash = net.peer(0).push_blocks(1, false).pop().unwrap();
import_with_announce(&mut net, new_hash).await;
assert_eq!(net.peer(1).num_downloaded_blocks(), 1);
assert_eq!(net.peer(1).num_downloaded_blocks().await, 1);
// check that KNOWN STALE block is imported from announce message
let known_stale_hash = net.peer(0).push_blocks_at(BlockId::Number(0), 1, true).pop().unwrap();
import_with_announce(&mut net, known_stale_hash).await;
assert_eq!(net.peer(1).num_downloaded_blocks(), 2);
assert_eq!(net.peer(1).num_downloaded_blocks().await, 2);
}
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
@@ -820,7 +820,7 @@ async fn sync_to_tip_requires_that_sync_protocol_is_informed_about_best_block()
assert!(!net.peer(1).has_block(block_hash));
// Make sync protocol aware of the best block
net.peer(0).network_service().new_best_block_imported(block_hash, 3);
net.peer(0).sync_service().new_best_block_imported(block_hash, 3);
net.run_until_idle().await;
// Connect another node that should now sync to the tip
@@ -865,8 +865,8 @@ async fn sync_to_tip_when_we_sync_together_with_multiple_peers() {
assert!(!net.peer(2).has_block(block_hash));
net.peer(0).network_service().new_best_block_imported(block_hash, 10_000);
net.peer(0).network_service().announce_block(block_hash, None);
net.peer(0).sync_service().new_best_block_imported(block_hash, 10_000);
net.peer(0).sync_service().announce_block(block_hash, None);
while !net.peer(2).has_block(block_hash) && !net.peer(1).has_block(block_hash) {
net.run_until_idle().await;
@@ -1045,14 +1045,17 @@ async fn syncs_all_forks_from_single_peer() {
let branch1 = net.peer(0).push_blocks_at(BlockId::Number(10), 2, true).pop().unwrap();
// Wait till peer 1 starts downloading
futures::future::poll_fn::<(), _>(|cx| {
net.poll(cx);
if net.peer(1).network().best_seen_block() != Some(12) {
return Poll::Pending
loop {
futures::future::poll_fn::<(), _>(|cx| {
net.poll(cx);
Poll::Ready(())
})
.await;
if net.peer(1).sync_service().best_seen_block().await.unwrap() == Some(12) {
break
}
Poll::Ready(())
})
.await;
}
// Peer 0 produces and announces another fork
let branch2 = net.peer(0).push_blocks_at(BlockId::Number(10), 2, false).pop().unwrap();