mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-14 12:11:09 +00:00
Allow syncing to peers with finalized common block (#5408)
* Allow syncing to peers with finalized common block * Added test
This commit is contained in:
@@ -1108,10 +1108,12 @@ impl<B: BlockT> ChainSync<B> {
|
||||
}
|
||||
// If the announced block is the best they have and is not ahead of us, our common number
|
||||
// is either one further ahead or it's the one they just announced, if we know about it.
|
||||
if is_best && self.best_queued_number >= number {
|
||||
if known {
|
||||
if is_best {
|
||||
if known && self.best_queued_number >= number {
|
||||
peer.common_number = number
|
||||
} else if header.parent_hash() == &self.best_queued_hash || known_parent {
|
||||
} else if header.parent_hash() == &self.best_queued_hash
|
||||
|| known_parent && self.best_queued_number >= number
|
||||
{
|
||||
peer.common_number = number - One::one();
|
||||
}
|
||||
}
|
||||
@@ -1320,13 +1322,17 @@ fn peer_block_request<B: BlockT>(
|
||||
finalized: NumberFor<B>,
|
||||
best_num: NumberFor<B>,
|
||||
) -> Option<(Range<NumberFor<B>>, BlockRequest<B>)> {
|
||||
if peer.common_number < finalized {
|
||||
return None;
|
||||
}
|
||||
if best_num >= peer.best_number {
|
||||
// Will be downloaded as alternative fork instead.
|
||||
return None;
|
||||
}
|
||||
if peer.common_number < finalized {
|
||||
trace!(
|
||||
target: "sync",
|
||||
"Requesting pre-finalized chain from {:?}, common={}, finalized={}, peer best={}, our best={}",
|
||||
id, finalized, peer.common_number, peer.best_number, best_num,
|
||||
);
|
||||
}
|
||||
if let Some(range) = blocks.needed_blocks(
|
||||
id.clone(),
|
||||
MAX_BLOCKS_TO_REQUEST,
|
||||
|
||||
@@ -694,3 +694,32 @@ fn imports_stale_once() {
|
||||
assert_eq!(net.peer(1).num_processed_blocks(), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn can_sync_to_peers_with_wrong_common_block() {
|
||||
let _ = ::env_logger::try_init();
|
||||
let mut net = TestNet::new(2);
|
||||
|
||||
net.peer(0).push_blocks(2, true);
|
||||
net.peer(1).push_blocks(2, true);
|
||||
let fork_hash = net.peer(0).push_blocks_at(BlockId::Number(0), 2, false);
|
||||
net.peer(1).push_blocks_at(BlockId::Number(0), 2, false);
|
||||
// wait for connection
|
||||
block_on(futures::future::poll_fn::<(), _>(|cx| {
|
||||
net.poll(cx);
|
||||
if net.peer(0).num_peers() == 0 || net.peer(1).num_peers() == 0 {
|
||||
Poll::Pending
|
||||
} else {
|
||||
Poll::Ready(())
|
||||
}
|
||||
}));
|
||||
|
||||
// both peers re-org to the same fork without notifying each other
|
||||
net.peer(0).client().finalize_block(BlockId::Hash(fork_hash), Some(Vec::new()), true).unwrap();
|
||||
net.peer(1).client().finalize_block(BlockId::Hash(fork_hash), Some(Vec::new()), true).unwrap();
|
||||
let final_hash = net.peer(0).push_blocks(1, false);
|
||||
|
||||
net.block_until_sync();
|
||||
|
||||
assert!(net.peer(1).client().header(&BlockId::Hash(final_hash)).unwrap().is_some());
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user