fixed sync issue
This commit is contained in:
parent
c24af2daed
commit
e589c25581
|
@ -307,13 +307,18 @@ impl Chain {
|
||||||
|
|
||||||
/// Forget in-memory block by hash if it is currently in given state
|
/// Forget in-memory block by hash if it is currently in given state
|
||||||
pub fn forget_with_state(&mut self, hash: &H256, state: BlockState) -> HashPosition {
|
pub fn forget_with_state(&mut self, hash: &H256, state: BlockState) -> HashPosition {
|
||||||
let position = self.hash_chain.remove_at(state.to_queue_index(), hash);
|
let position = self.forget_with_state_leave_header(hash, state);
|
||||||
if position != HashPosition::Missing {
|
if position != HashPosition::Missing {
|
||||||
self.headers_chain.remove(hash);
|
self.headers_chain.remove(hash);
|
||||||
}
|
}
|
||||||
position
|
position
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Forget in-memory block by hash if it is currently in given state
|
||||||
|
pub fn forget_with_state_leave_header(&mut self, hash: &H256, state: BlockState) -> HashPosition {
|
||||||
|
self.hash_chain.remove_at(state.to_queue_index(), hash)
|
||||||
|
}
|
||||||
|
|
||||||
/// Forget in-memory block by hash.
|
/// Forget in-memory block by hash.
|
||||||
/// Also forget all its known children.
|
/// Also forget all its known children.
|
||||||
pub fn forget_with_children(&mut self, hash: &H256) {
|
pub fn forget_with_children(&mut self, hash: &H256) {
|
||||||
|
|
|
@ -298,9 +298,16 @@ impl<T> Client for SynchronizationClient<T> where T: TaskExecutor {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// else => request blocks
|
// else => request all unknown blocks
|
||||||
|
let unknown_blocks_hashes: Vec<_> = {
|
||||||
|
let chain = self.chain.read();
|
||||||
|
blocks_hashes.into_iter()
|
||||||
|
.filter(|h| chain.block_state(&h) == BlockState::Unknown)
|
||||||
|
.collect()
|
||||||
|
};
|
||||||
|
|
||||||
let mut executor = self.executor.lock();
|
let mut executor = self.executor.lock();
|
||||||
executor.execute(Task::RequestBlocks(peer_index, blocks_hashes))
|
executor.execute(Task::RequestBlocks(peer_index, unknown_blocks_hashes))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Try to queue synchronization of unknown blocks when blocks headers are received.
|
/// Try to queue synchronization of unknown blocks when blocks headers are received.
|
||||||
|
@ -386,7 +393,9 @@ impl<T> Client for SynchronizationClient<T> where T: TaskExecutor {
|
||||||
let mut chain = self.chain.write();
|
let mut chain = self.chain.write();
|
||||||
|
|
||||||
// remove block from verification queue
|
// remove block from verification queue
|
||||||
if chain.forget_with_state(&hash, BlockState::Verifying) != HashPosition::Missing {
|
// header is removed in `insert_best_block` call
|
||||||
|
// or it is removed earlier, when block was removed from the verifying queue
|
||||||
|
if chain.forget_with_state_leave_header(&hash, BlockState::Verifying) != HashPosition::Missing {
|
||||||
// block was in verification queue => insert to storage
|
// block was in verification queue => insert to storage
|
||||||
chain.insert_best_block(hash.clone(), block)
|
chain.insert_best_block(hash.clone(), block)
|
||||||
.expect("Error inserting to db.");
|
.expect("Error inserting to db.");
|
||||||
|
@ -408,6 +417,7 @@ impl<T> Client for SynchronizationClient<T> where T: TaskExecutor {
|
||||||
let mut chain = self.chain.write();
|
let mut chain = self.chain.write();
|
||||||
|
|
||||||
// forget for this block and all its children
|
// forget for this block and all its children
|
||||||
|
// headers are also removed as they all are invalid
|
||||||
chain.forget_with_children(&hash);
|
chain.forget_with_children(&hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -561,6 +571,7 @@ impl<T> SynchronizationClient<T> where T: TaskExecutor {
|
||||||
blocks.push_back((block_hash, block));
|
blocks.push_back((block_hash, block));
|
||||||
while let Some((block_hash, block)) = blocks.pop_front() {
|
while let Some((block_hash, block)) = blocks.pop_front() {
|
||||||
// remove block from current queue
|
// remove block from current queue
|
||||||
|
// header is removed in insert_best_block or in one of on_verification_* methods
|
||||||
chain.forget_leave_header(&block_hash);
|
chain.forget_leave_header(&block_hash);
|
||||||
match self.verification_work_sender {
|
match self.verification_work_sender {
|
||||||
Some(ref verification_work_sender) => {
|
Some(ref verification_work_sender) => {
|
||||||
|
@ -598,8 +609,6 @@ impl<T> SynchronizationClient<T> where T: TaskExecutor {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
BlockState::Requested | BlockState::Scheduled => {
|
BlockState::Requested | BlockState::Scheduled => {
|
||||||
// remove block from current queue
|
|
||||||
chain.forget_leave_header(&block_hash);
|
|
||||||
// remember peer as useful
|
// remember peer as useful
|
||||||
self.peers.insert(peer_index);
|
self.peers.insert(peer_index);
|
||||||
// remember as orphan block
|
// remember as orphan block
|
||||||
|
@ -864,7 +873,6 @@ pub mod tests {
|
||||||
|
|
||||||
// push requested block => should be moved to the test storage && orphan should be moved
|
// push requested block => should be moved to the test storage && orphan should be moved
|
||||||
sync.on_peer_block(5, block1);
|
sync.on_peer_block(5, block1);
|
||||||
println!("{:?}", sync.information());
|
|
||||||
assert!(sync.information().state.is_saturated());
|
assert!(sync.information().state.is_saturated());
|
||||||
assert_eq!(sync.information().orphaned, 0);
|
assert_eq!(sync.information().orphaned, 0);
|
||||||
assert_eq!(sync.information().chain.scheduled, 0);
|
assert_eq!(sync.information().chain.scheduled, 0);
|
||||||
|
|
Loading…
Reference in New Issue