Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: download matched blocks even previous download are not finished #202

Conversation

chaoticlonghair
Copy link
Contributor

Issue

If the matched blocks in memory are not empty, but the matched blocks in storage are not empty, the download process will hang.

This logic is existed since 2022 without changes.

if let Some((db_start_number, blocks_count, db_blocks)) =
self.storage.get_earliest_matched_blocks()
{
if matched_blocks.is_empty() {
debug!(
"recover matched blocks from storage, start_number={}, blocks_count={}, matched_count: {}",
db_start_number, blocks_count,
matched_blocks.len(),
);
// recover matched blocks from storage
self.peers
.add_matched_blocks(&mut matched_blocks, db_blocks);
let tip_header = self.storage.get_tip_header();
prove_or_download_matched_blocks(
Arc::clone(&self.peers),
&tip_header,
&matched_blocks,
nc.as_ref(),
INIT_BLOCKS_IN_TRANSIT_PER_PEER,
);
if prove_state_number >= start_number {
debug!(
"send get block filters to {}, start_number={}",
peer, start_number
);
self.send_get_block_filters(Arc::clone(&nc), *peer, start_number);
}
}
} else if self.should_ask() && prove_state_number >= start_number {

Ref: #77

Solution

After reading the code, in my understanding:

  • When a set of new possible matched blocks is found, it will be added into storage.
  • If the set of matched blocks in memory is empty, load the earliest set of possible matched blocks from storage.
  • If all matched blocks in memory are downloaded, then clear the memory.

So, prove_or_download_matched_blocks(..) should be executed when memory are not empty.

@chaoticlonghair chaoticlonghair requested a review from quake October 31, 2024 08:34
@chaoticlonghair
Copy link
Contributor Author

After I pushed this PR, I notice that: with get_idle_blocks(..), it should not be stuck.

constant::GET_IDLE_BLOCKS_TOKEN => {
self.get_idle_blocks(nc.as_ref());
}

fn get_idle_blocks(&mut self, nc: &dyn CKBProtocolContext) {
let tip_header = self.storage.get_tip_header();
let matched_blocks = self.peers.matched_blocks().read().expect("poisoned");
prove_or_download_matched_blocks(
Arc::clone(&self.peers),
&tip_header,
&matched_blocks,
nc,
self.init_blocks_in_transit_per_peer(),
);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant