Fast/warp sync fixes (#10562)

* Fast sync fixes

* Fix gap blocks validation

* Updated test

* Formatting

* Networking test
This commit is contained in:
Arkadiy Paronyan
2022-01-13 16:26:06 +01:00
committed by GitHub
parent 3a88215fca
commit 4d477ea9b4
7 changed files with 126 additions and 32 deletions
+50 -6
View File
@@ -1095,15 +1095,17 @@ impl<B: BlockT> ChainSync<B> {
}
self.drain_blocks()
},
PeerSyncState::DownloadingGap(start_block) => {
let start_block = *start_block;
PeerSyncState::DownloadingGap(_) => {
peer.state = PeerSyncState::Available;
if let Some(gap_sync) = &mut self.gap_sync {
gap_sync.blocks.clear_peer_download(who);
validate_blocks::<B>(&blocks, who, Some(request))?;
gap_sync.blocks.insert(start_block, blocks, who.clone());
if let Some(start_block) =
validate_blocks::<B>(&blocks, who, Some(request))?
{
gap_sync.blocks.insert(start_block, blocks, who.clone());
}
gap = true;
gap_sync
let blocks: Vec<_> = gap_sync
.blocks
.drain(gap_sync.best_queued_number + One::one())
.into_iter()
@@ -1126,7 +1128,9 @@ impl<B: BlockT> ChainSync<B> {
state: None,
}
})
.collect()
.collect();
debug!(target: "sync", "Drained {} gap blocks from {}", blocks.len(), gap_sync.best_queued_number);
blocks
} else {
debug!(target: "sync", "Unexpected gap block response from {}", who);
return Err(BadPeer(who.clone(), rep::NO_BLOCK))
@@ -3169,4 +3173,44 @@ mod test {
sync.peer_disconnected(&peer_id1);
assert!(sync.fork_targets.len() == 0);
}
#[test]
fn can_import_response_with_missing_blocks() {
sp_tracing::try_init_simple();
let mut client2 = Arc::new(TestClientBuilder::new().build());
let blocks = (0..4).map(|_| build_block(&mut client2, None, false)).collect::<Vec<_>>();
let empty_client = Arc::new(TestClientBuilder::new().build());
let mut sync = ChainSync::new(
SyncMode::Full,
empty_client.clone(),
Box::new(DefaultBlockAnnounceValidator),
1,
None,
)
.unwrap();
let peer_id1 = PeerId::random();
let best_block = blocks[3].clone();
sync.new_peer(peer_id1.clone(), best_block.hash(), *best_block.header().number())
.unwrap();
sync.peers.get_mut(&peer_id1).unwrap().state = PeerSyncState::Available;
sync.peers.get_mut(&peer_id1).unwrap().common_number = 0;
// Request all missing blocks and respond only with some.
let request =
get_block_request(&mut sync, FromBlock::Hash(best_block.hash()), 4, &peer_id1);
let response =
create_block_response(vec![blocks[3].clone(), blocks[2].clone(), blocks[1].clone()]);
sync.on_block_data(&peer_id1, Some(request.clone()), response).unwrap();
assert_eq!(sync.best_queued_number, 0);
// Request should only contain the missing block.
let request = get_block_request(&mut sync, FromBlock::Number(1), 1, &peer_id1);
let response = create_block_response(vec![blocks[0].clone()]);
sync.on_block_data(&peer_id1, Some(request), response).unwrap();
assert_eq!(sync.best_queued_number, 4);
}
}