Warp sync part II (#9284)

* Gap sync

* Gap epoch test

* Simplified network requests

* Update client/db/src/utils.rs

Co-authored-by: cheme <emericchevalier.pro@gmail.com>

* Fixed v1 migration and added some comments

* Next epoch is always regular

* Removed fork tree change

* Apply suggestions from code review

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>

* Added a comment and converted assert to error

Co-authored-by: cheme <emericchevalier.pro@gmail.com>
Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>
This commit is contained in:
Arkadiy Paronyan
2021-10-07 11:31:39 +02:00
committed by GitHub
parent 9f1c3acb7d
commit e6ff531d0b
29 changed files with 800 additions and 169 deletions
+40 -3
View File
@@ -55,7 +55,7 @@ use sc_network::{
},
light_client_requests::{self, handler::LightClientRequestHandler},
state_request_handler::{self, StateRequestHandler},
Multiaddr, NetworkService, NetworkWorker,
warp_request_handler, Multiaddr, NetworkService, NetworkWorker,
};
use sc_service::client::Client;
use sp_blockchain::{
@@ -68,6 +68,7 @@ use sp_consensus::{
};
use sp_core::H256;
use sp_runtime::{
codec::{Decode, Encode},
generic::{BlockId, OpaqueDigestItemId},
traits::{Block as BlockT, Header as HeaderT, NumberFor},
Justification, Justifications,
@@ -652,6 +653,33 @@ impl<B: BlockT> VerifierAdapter<B> {
}
}
struct TestWarpSyncProvider<B: BlockT>(Arc<dyn HeaderBackend<B>>);
impl<B: BlockT> warp_request_handler::WarpSyncProvider<B> for TestWarpSyncProvider<B> {
fn generate(
&self,
_start: B::Hash,
) -> Result<warp_request_handler::EncodedProof, Box<dyn std::error::Error + Send + Sync>> {
let info = self.0.info();
let best_header = self.0.header(BlockId::hash(info.best_hash)).unwrap().unwrap();
Ok(warp_request_handler::EncodedProof(best_header.encode()))
}
fn verify(
&self,
proof: &warp_request_handler::EncodedProof,
_set_id: warp_request_handler::SetId,
_authorities: warp_request_handler::AuthorityList,
) -> Result<warp_request_handler::VerificationResult<B>, Box<dyn std::error::Error + Send + Sync>>
{
let warp_request_handler::EncodedProof(encoded) = proof;
let header = B::Header::decode(&mut encoded.as_slice()).unwrap();
Ok(warp_request_handler::VerificationResult::Complete(0, Default::default(), header))
}
fn current_authorities(&self) -> warp_request_handler::AuthorityList {
Default::default()
}
}
/// Configuration for a full peer.
#[derive(Default)]
pub struct FullPeerConfig {
@@ -737,7 +765,7 @@ where
(Some(keep_blocks), false) => TestClientBuilder::with_pruning_window(keep_blocks),
(None, false) => TestClientBuilder::with_default_backend(),
};
if matches!(config.sync_mode, SyncMode::Fast { .. }) {
if matches!(config.sync_mode, SyncMode::Fast { .. } | SyncMode::Warp) {
test_client_builder = test_client_builder.set_no_genesis();
}
let backend = test_client_builder.backend();
@@ -816,6 +844,15 @@ where
protocol_config
};
let warp_sync = Arc::new(TestWarpSyncProvider(client.clone()));
let warp_protocol_config = {
let (handler, protocol_config) =
warp_request_handler::RequestHandler::new(protocol_id.clone(), warp_sync.clone());
self.spawn_task(handler.run().boxed());
protocol_config
};
let network = NetworkWorker::new(sc_network::config::Params {
role: if config.is_authority { Role::Authority } else { Role::Full },
executor: None,
@@ -835,7 +872,7 @@ where
block_request_protocol_config,
state_request_protocol_config,
light_client_request_protocol_config,
warp_sync: None,
warp_sync: Some((warp_sync, warp_protocol_config)),
})
.unwrap();
+32
View File
@@ -1202,6 +1202,38 @@ fn syncs_indexed_blocks() {
.is_some());
}
#[test]
fn warp_sync() {
sp_tracing::try_init_simple();
let mut net = TestNet::new(0);
// Create 3 synced peers and 1 peer trying to warp sync.
net.add_full_peer_with_config(Default::default());
net.add_full_peer_with_config(Default::default());
net.add_full_peer_with_config(Default::default());
net.add_full_peer_with_config(FullPeerConfig {
sync_mode: SyncMode::Warp,
..Default::default()
});
let gap_end = net.peer(0).push_blocks(63, false);
net.peer(0).push_blocks(1, false);
net.peer(1).push_blocks(64, false);
net.peer(2).push_blocks(64, false);
// Wait for peer 1 to sync state.
net.block_until_sync();
assert!(!net.peer(3).client().has_state_at(&BlockId::Number(1)));
assert!(net.peer(3).client().has_state_at(&BlockId::Number(64)));
// Wait for peer 1 download block history
block_on(futures::future::poll_fn::<(), _>(|cx| {
net.poll(cx);
if net.peer(3).has_block(&gap_end) {
Poll::Ready(())
} else {
Poll::Pending
}
}));
}
#[test]
fn syncs_huge_blocks() {
use sp_core::storage::well_known_keys::HEAP_PAGES;