mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-08 03:08:06 +00:00
Unify ChainSync actions under one enum (#2180)
All `ChainSync` actions that `SyncingEngine` should perform are unified under one `ChainSyncAction`. Processing of these actions put into a single place after `select!` in `SyncingEngine::run` instead of multiple places where calling `ChainSync` methods.
This commit is contained in:
@@ -53,7 +53,7 @@ fn processes_empty_response_on_justification_request_for_unknown_block() {
|
||||
};
|
||||
|
||||
// add a new peer with the same best block
|
||||
sync.new_peer(peer_id, a1_hash, a1_number).unwrap();
|
||||
sync.new_peer(peer_id, a1_hash, a1_number);
|
||||
|
||||
// and request a justification for the block
|
||||
sync.request_justification(&a1_hash, a1_number);
|
||||
@@ -74,10 +74,8 @@ fn processes_empty_response_on_justification_request_for_unknown_block() {
|
||||
|
||||
// if the peer replies with an empty response (i.e. it doesn't know the block),
|
||||
// the active request should be cleared.
|
||||
assert_eq!(
|
||||
sync.on_block_justification(peer_id, BlockResponse::<Block> { id: 0, blocks: vec![] }),
|
||||
Ok(OnBlockJustification::Nothing),
|
||||
);
|
||||
sync.on_block_justification(peer_id, BlockResponse::<Block> { id: 0, blocks: vec![] })
|
||||
.unwrap();
|
||||
|
||||
// there should be no in-flight requests
|
||||
assert_eq!(sync.extra_justifications.active_requests().count(), 0);
|
||||
@@ -119,8 +117,8 @@ fn restart_doesnt_affect_peers_downloading_finality_data() {
|
||||
let (b1_hash, b1_number) = new_blocks(50);
|
||||
|
||||
// add 2 peers at blocks that we don't have locally
|
||||
sync.new_peer(peer_id1, Hash::random(), 42).unwrap();
|
||||
sync.new_peer(peer_id2, Hash::random(), 10).unwrap();
|
||||
sync.new_peer(peer_id1, Hash::random(), 42);
|
||||
sync.new_peer(peer_id2, Hash::random(), 10);
|
||||
|
||||
// we wil send block requests to these peers
|
||||
// for these blocks we don't know about
|
||||
@@ -130,7 +128,7 @@ fn restart_doesnt_affect_peers_downloading_finality_data() {
|
||||
.all(|(p, _)| { p == peer_id1 || p == peer_id2 }));
|
||||
|
||||
// add a new peer at a known block
|
||||
sync.new_peer(peer_id3, b1_hash, b1_number).unwrap();
|
||||
sync.new_peer(peer_id3, b1_hash, b1_number);
|
||||
|
||||
// we request a justification for a block we have locally
|
||||
sync.request_justification(&b1_hash, b1_number);
|
||||
@@ -148,14 +146,19 @@ fn restart_doesnt_affect_peers_downloading_finality_data() {
|
||||
PeerSyncState::DownloadingJustification(b1_hash),
|
||||
);
|
||||
|
||||
// clear old actions
|
||||
let _ = sync.take_actions();
|
||||
|
||||
// we restart the sync state
|
||||
let block_requests = sync.restart();
|
||||
sync.restart();
|
||||
let actions = sync.take_actions().collect::<Vec<_>>();
|
||||
|
||||
// which should make us send out block requests to the first two peers
|
||||
assert!(block_requests.map(|r| r.unwrap()).all(|event| match event {
|
||||
BlockRequestAction::SendRequest { peer_id, .. } =>
|
||||
peer_id == peer_id1 || peer_id == peer_id2,
|
||||
BlockRequestAction::RemoveStale { .. } => false,
|
||||
assert_eq!(actions.len(), 2);
|
||||
assert!(actions.iter().all(|action| match action {
|
||||
ChainSyncAction::SendBlockRequest { peer_id, .. } =>
|
||||
peer_id == &peer_id1 || peer_id == &peer_id2,
|
||||
_ => false,
|
||||
}));
|
||||
|
||||
// peer 3 should be unaffected it was downloading finality data
|
||||
@@ -166,7 +169,7 @@ fn restart_doesnt_affect_peers_downloading_finality_data() {
|
||||
|
||||
// Set common block to something that we don't have (e.g. failed import)
|
||||
sync.peers.get_mut(&peer_id3).unwrap().common_number = 100;
|
||||
let _ = sync.restart().count();
|
||||
sync.restart();
|
||||
assert_eq!(sync.peers.get(&peer_id3).unwrap().common_number, 50);
|
||||
}
|
||||
|
||||
@@ -280,9 +283,8 @@ fn do_ancestor_search_when_common_block_to_best_qeued_gap_is_to_big() {
|
||||
let best_block = blocks.last().unwrap().clone();
|
||||
let max_blocks_to_request = sync.max_blocks_per_request;
|
||||
// Connect the node we will sync from
|
||||
sync.new_peer(peer_id1, best_block.hash(), *best_block.header().number())
|
||||
.unwrap();
|
||||
sync.new_peer(peer_id2, info.best_hash, 0).unwrap();
|
||||
sync.new_peer(peer_id1, best_block.hash(), *best_block.header().number());
|
||||
sync.new_peer(peer_id2, info.best_hash, 0);
|
||||
|
||||
let mut best_block_num = 0;
|
||||
while best_block_num < MAX_DOWNLOAD_AHEAD {
|
||||
@@ -300,11 +302,17 @@ fn do_ancestor_search_when_common_block_to_best_qeued_gap_is_to_big() {
|
||||
|
||||
let response = create_block_response(resp_blocks.clone());
|
||||
|
||||
let res = sync.on_block_data(&peer_id1, Some(request), response).unwrap();
|
||||
// Clear old actions to not deal with them
|
||||
let _ = sync.take_actions();
|
||||
|
||||
sync.on_block_data(&peer_id1, Some(request), response).unwrap();
|
||||
|
||||
let actions = sync.take_actions().collect::<Vec<_>>();
|
||||
assert_eq!(actions.len(), 1);
|
||||
assert!(matches!(
|
||||
res,
|
||||
OnBlockData::Import(ImportBlocksAction{ origin: _, blocks }) if blocks.len() == max_blocks_to_request as usize
|
||||
),);
|
||||
&actions[0],
|
||||
ChainSyncAction::ImportBlocks{ origin: _, blocks } if blocks.len() == max_blocks_to_request as usize,
|
||||
));
|
||||
|
||||
best_block_num += max_blocks_to_request as u32;
|
||||
|
||||
@@ -356,11 +364,14 @@ fn do_ancestor_search_when_common_block_to_best_qeued_gap_is_to_big() {
|
||||
assert_eq!(FromBlock::Number(best_block_num as u64), peer2_req.from);
|
||||
|
||||
let response = create_block_response(vec![blocks[(best_block_num - 1) as usize].clone()]);
|
||||
let res = sync.on_block_data(&peer_id2, Some(peer2_req), response).unwrap();
|
||||
assert!(matches!(
|
||||
res,
|
||||
OnBlockData::Import(ImportBlocksAction{ origin: _, blocks }) if blocks.is_empty()
|
||||
),);
|
||||
|
||||
// Clear old actions to not deal with them
|
||||
let _ = sync.take_actions();
|
||||
|
||||
sync.on_block_data(&peer_id2, Some(peer2_req), response).unwrap();
|
||||
|
||||
let actions = sync.take_actions().collect::<Vec<_>>();
|
||||
assert!(actions.is_empty());
|
||||
|
||||
let peer1_from = unwrap_from_block_number(peer1_req.unwrap().from);
|
||||
|
||||
@@ -421,25 +432,34 @@ fn can_sync_huge_fork() {
|
||||
|
||||
let common_block = blocks[MAX_BLOCKS_TO_LOOK_BACKWARDS as usize / 2].clone();
|
||||
// Connect the node we will sync from
|
||||
sync.new_peer(peer_id1, common_block.hash(), *common_block.header().number())
|
||||
.unwrap();
|
||||
sync.new_peer(peer_id1, common_block.hash(), *common_block.header().number());
|
||||
|
||||
send_block_announce(fork_blocks.last().unwrap().header().clone(), peer_id1, &mut sync);
|
||||
|
||||
let mut request =
|
||||
get_block_request(&mut sync, FromBlock::Number(info.best_number), 1, &peer_id1);
|
||||
|
||||
// Discard old actions we are not interested in
|
||||
let _ = sync.take_actions();
|
||||
|
||||
// Do the ancestor search
|
||||
loop {
|
||||
let block = &fork_blocks[unwrap_from_block_number(request.from.clone()) as usize - 1];
|
||||
let response = create_block_response(vec![block.clone()]);
|
||||
|
||||
let on_block_data = sync.on_block_data(&peer_id1, Some(request), response).unwrap();
|
||||
request = if let OnBlockData::Request(_peer, request) = on_block_data {
|
||||
request
|
||||
} else {
|
||||
sync.on_block_data(&peer_id1, Some(request), response).unwrap();
|
||||
|
||||
let actions = sync.take_actions().collect::<Vec<_>>();
|
||||
|
||||
request = if actions.is_empty() {
|
||||
// We found the ancenstor
|
||||
break
|
||||
} else {
|
||||
assert_eq!(actions.len(), 1);
|
||||
match &actions[0] {
|
||||
ChainSyncAction::SendBlockRequest { peer_id: _, request } => request.clone(),
|
||||
action @ _ => panic!("Unexpected action: {action:?}"),
|
||||
}
|
||||
};
|
||||
|
||||
log::trace!(target: LOG_TARGET, "Request: {request:?}");
|
||||
@@ -463,15 +483,18 @@ fn can_sync_huge_fork() {
|
||||
|
||||
let response = create_block_response(resp_blocks.clone());
|
||||
|
||||
let res = sync.on_block_data(&peer_id1, Some(request), response).unwrap();
|
||||
sync.on_block_data(&peer_id1, Some(request), response).unwrap();
|
||||
|
||||
let actions = sync.take_actions().collect::<Vec<_>>();
|
||||
assert_eq!(actions.len(), 1);
|
||||
assert!(matches!(
|
||||
res,
|
||||
OnBlockData::Import(ImportBlocksAction{ origin: _, blocks }) if blocks.len() == sync.max_blocks_per_request as usize
|
||||
),);
|
||||
&actions[0],
|
||||
ChainSyncAction::ImportBlocks{ origin: _, blocks } if blocks.len() == sync.max_blocks_per_request as usize
|
||||
));
|
||||
|
||||
best_block_num += sync.max_blocks_per_request as u32;
|
||||
|
||||
let _ = sync.on_blocks_processed(
|
||||
sync.on_blocks_processed(
|
||||
max_blocks_to_request as usize,
|
||||
max_blocks_to_request as usize,
|
||||
resp_blocks
|
||||
@@ -490,6 +513,9 @@ fn can_sync_huge_fork() {
|
||||
.collect(),
|
||||
);
|
||||
|
||||
// Discard pending actions
|
||||
let _ = sync.take_actions();
|
||||
|
||||
resp_blocks
|
||||
.into_iter()
|
||||
.rev()
|
||||
@@ -539,25 +565,34 @@ fn syncs_fork_without_duplicate_requests() {
|
||||
|
||||
let common_block = blocks[MAX_BLOCKS_TO_LOOK_BACKWARDS as usize / 2].clone();
|
||||
// Connect the node we will sync from
|
||||
sync.new_peer(peer_id1, common_block.hash(), *common_block.header().number())
|
||||
.unwrap();
|
||||
sync.new_peer(peer_id1, common_block.hash(), *common_block.header().number());
|
||||
|
||||
send_block_announce(fork_blocks.last().unwrap().header().clone(), peer_id1, &mut sync);
|
||||
|
||||
let mut request =
|
||||
get_block_request(&mut sync, FromBlock::Number(info.best_number), 1, &peer_id1);
|
||||
|
||||
// Discard pending actions
|
||||
let _ = sync.take_actions();
|
||||
|
||||
// Do the ancestor search
|
||||
loop {
|
||||
let block = &fork_blocks[unwrap_from_block_number(request.from.clone()) as usize - 1];
|
||||
let response = create_block_response(vec![block.clone()]);
|
||||
|
||||
let on_block_data = sync.on_block_data(&peer_id1, Some(request), response).unwrap();
|
||||
request = if let OnBlockData::Request(_peer, request) = on_block_data {
|
||||
request
|
||||
} else {
|
||||
sync.on_block_data(&peer_id1, Some(request), response).unwrap();
|
||||
|
||||
let actions = sync.take_actions().collect::<Vec<_>>();
|
||||
|
||||
request = if actions.is_empty() {
|
||||
// We found the ancenstor
|
||||
break
|
||||
} else {
|
||||
assert_eq!(actions.len(), 1);
|
||||
match &actions[0] {
|
||||
ChainSyncAction::SendBlockRequest { peer_id: _, request } => request.clone(),
|
||||
action @ _ => panic!("Unexpected action: {action:?}"),
|
||||
}
|
||||
};
|
||||
|
||||
log::trace!(target: LOG_TARGET, "Request: {request:?}");
|
||||
@@ -582,11 +617,17 @@ fn syncs_fork_without_duplicate_requests() {
|
||||
|
||||
let response = create_block_response(resp_blocks.clone());
|
||||
|
||||
let res = sync.on_block_data(&peer_id1, Some(request.clone()), response).unwrap();
|
||||
// Discard old actions
|
||||
let _ = sync.take_actions();
|
||||
|
||||
sync.on_block_data(&peer_id1, Some(request.clone()), response).unwrap();
|
||||
|
||||
let actions = sync.take_actions().collect::<Vec<_>>();
|
||||
assert_eq!(actions.len(), 1);
|
||||
assert!(matches!(
|
||||
res,
|
||||
OnBlockData::Import(ImportBlocksAction{ origin: _, blocks }) if blocks.len() == max_blocks_to_request as usize
|
||||
),);
|
||||
&actions[0],
|
||||
ChainSyncAction::ImportBlocks{ origin: _, blocks } if blocks.len() == max_blocks_to_request as usize
|
||||
));
|
||||
|
||||
best_block_num += max_blocks_to_request as u32;
|
||||
|
||||
@@ -653,8 +694,7 @@ fn removes_target_fork_on_disconnect() {
|
||||
let peer_id1 = PeerId::random();
|
||||
let common_block = blocks[1].clone();
|
||||
// Connect the node we will sync from
|
||||
sync.new_peer(peer_id1, common_block.hash(), *common_block.header().number())
|
||||
.unwrap();
|
||||
sync.new_peer(peer_id1, common_block.hash(), *common_block.header().number());
|
||||
|
||||
// Create a "new" header and announce it
|
||||
let mut header = blocks[0].header().clone();
|
||||
@@ -678,8 +718,7 @@ fn can_import_response_with_missing_blocks() {
|
||||
|
||||
let peer_id1 = PeerId::random();
|
||||
let best_block = blocks[3].clone();
|
||||
sync.new_peer(peer_id1, best_block.hash(), *best_block.header().number())
|
||||
.unwrap();
|
||||
sync.new_peer(peer_id1, best_block.hash(), *best_block.header().number());
|
||||
|
||||
sync.peers.get_mut(&peer_id1).unwrap().state = PeerSyncState::Available;
|
||||
sync.peers.get_mut(&peer_id1).unwrap().common_number = 0;
|
||||
@@ -730,7 +769,7 @@ fn sync_restart_removes_block_but_not_justification_requests() {
|
||||
let (b1_hash, b1_number) = new_blocks(50);
|
||||
|
||||
// add new peer and request blocks from them
|
||||
sync.new_peer(peers[0], Hash::random(), 42).unwrap();
|
||||
sync.new_peer(peers[0], Hash::random(), 42);
|
||||
|
||||
// we don't actually perform any requests, just keep track of peers waiting for a response
|
||||
let mut pending_responses = HashSet::new();
|
||||
@@ -743,7 +782,7 @@ fn sync_restart_removes_block_but_not_justification_requests() {
|
||||
}
|
||||
|
||||
// add a new peer at a known block
|
||||
sync.new_peer(peers[1], b1_hash, b1_number).unwrap();
|
||||
sync.new_peer(peers[1], b1_hash, b1_number);
|
||||
|
||||
// we request a justification for a block we have locally
|
||||
sync.request_justification(&b1_hash, b1_number);
|
||||
@@ -766,24 +805,29 @@ fn sync_restart_removes_block_but_not_justification_requests() {
|
||||
);
|
||||
assert_eq!(pending_responses.len(), 2);
|
||||
|
||||
// discard old actions
|
||||
let _ = sync.take_actions();
|
||||
|
||||
// restart sync
|
||||
let request_events = sync.restart().collect::<Vec<_>>();
|
||||
for event in request_events.iter() {
|
||||
match event.as_ref().unwrap() {
|
||||
BlockRequestAction::RemoveStale { peer_id } => {
|
||||
sync.restart();
|
||||
let actions = sync.take_actions().collect::<Vec<_>>();
|
||||
for action in actions.iter() {
|
||||
match action {
|
||||
ChainSyncAction::CancelBlockRequest { peer_id } => {
|
||||
pending_responses.remove(&peer_id);
|
||||
},
|
||||
BlockRequestAction::SendRequest { peer_id, .. } => {
|
||||
ChainSyncAction::SendBlockRequest { peer_id, .. } => {
|
||||
// we drop obsolete response, but don't register a new request, it's checked in
|
||||
// the `assert!` below
|
||||
pending_responses.remove(&peer_id);
|
||||
},
|
||||
action @ _ => panic!("Unexpected action: {action:?}"),
|
||||
}
|
||||
}
|
||||
assert!(request_events.iter().any(|event| {
|
||||
match event.as_ref().unwrap() {
|
||||
BlockRequestAction::RemoveStale { .. } => false,
|
||||
BlockRequestAction::SendRequest { peer_id, .. } => peer_id == &peers[0],
|
||||
assert!(actions.iter().any(|action| {
|
||||
match action {
|
||||
ChainSyncAction::SendBlockRequest { peer_id, .. } => peer_id == &peers[0],
|
||||
_ => false,
|
||||
}
|
||||
}));
|
||||
|
||||
@@ -848,11 +892,9 @@ fn request_across_forks() {
|
||||
// Add the peers, all at the common ancestor 100.
|
||||
let common_block = blocks.last().unwrap();
|
||||
let peer_id1 = PeerId::random();
|
||||
sync.new_peer(peer_id1, common_block.hash(), *common_block.header().number())
|
||||
.unwrap();
|
||||
sync.new_peer(peer_id1, common_block.hash(), *common_block.header().number());
|
||||
let peer_id2 = PeerId::random();
|
||||
sync.new_peer(peer_id2, common_block.hash(), *common_block.header().number())
|
||||
.unwrap();
|
||||
sync.new_peer(peer_id2, common_block.hash(), *common_block.header().number());
|
||||
|
||||
// Peer 1 announces 107 from fork 1, 100-107 get downloaded.
|
||||
{
|
||||
@@ -864,11 +906,17 @@ fn request_across_forks() {
|
||||
let mut resp_blocks = fork_a_blocks[100_usize..107_usize].to_vec();
|
||||
resp_blocks.reverse();
|
||||
let response = create_block_response(resp_blocks.clone());
|
||||
let res = sync.on_block_data(&peer, Some(request), response).unwrap();
|
||||
|
||||
// Drop old actions
|
||||
let _ = sync.take_actions();
|
||||
|
||||
sync.on_block_data(&peer, Some(request), response).unwrap();
|
||||
let actions = sync.take_actions().collect::<Vec<_>>();
|
||||
assert_eq!(actions.len(), 1);
|
||||
assert!(matches!(
|
||||
res,
|
||||
OnBlockData::Import(ImportBlocksAction{ origin: _, blocks }) if blocks.len() == 7_usize
|
||||
),);
|
||||
&actions[0],
|
||||
ChainSyncAction::ImportBlocks{ origin: _, blocks } if blocks.len() == 7_usize
|
||||
));
|
||||
assert_eq!(sync.best_queued_number, 107);
|
||||
assert_eq!(sync.best_queued_hash, block.hash());
|
||||
assert!(sync.is_known(&block.header.parent_hash()));
|
||||
@@ -903,11 +951,17 @@ fn request_across_forks() {
|
||||
// block is announced.
|
||||
let request = get_block_request(&mut sync, FromBlock::Hash(block.hash()), 1, &peer);
|
||||
let response = create_block_response(vec![block.clone()]);
|
||||
let res = sync.on_block_data(&peer, Some(request), response).unwrap();
|
||||
|
||||
// Drop old actions we are not going to check
|
||||
let _ = sync.take_actions();
|
||||
|
||||
sync.on_block_data(&peer, Some(request), response).unwrap();
|
||||
let actions = sync.take_actions().collect::<Vec<_>>();
|
||||
assert_eq!(actions.len(), 1);
|
||||
assert!(matches!(
|
||||
res,
|
||||
OnBlockData::Import(ImportBlocksAction{ origin: _, blocks }) if blocks.len() == 1_usize
|
||||
),);
|
||||
&actions[0],
|
||||
ChainSyncAction::ImportBlocks{ origin: _, blocks } if blocks.len() == 1_usize
|
||||
));
|
||||
assert!(sync.is_known(&block.header.parent_hash()));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user