Skip to content

Commit

Permalink
fix: full syncing separate block body request in chunks
Browse files Browse the repository at this point in the history
  • Loading branch information
MarcosNicolau committed Feb 14, 2025
1 parent e13e833 commit 9233597
Showing 1 changed file with 28 additions and 7 deletions.
35 changes: 28 additions & 7 deletions crates/networking/p2p/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -269,16 +269,35 @@ async fn download_and_run_blocks(
invalid_ancestors: &mut HashMap<BlockHash, BlockHash>,
) -> Result<(), SyncError> {
let mut last_valid_hash = H256::default();
// ask as much as 128 block bodies per req
// this magic number is not part of the protocol and it is taken from geth, see:
// https://github.com/ethereum/go-ethereum/blob/master/eth/downloader/downloader.go#L42
let max_req_len = 128;

let mut current_chunk_idx = 0;
let chunks: Vec<Vec<BlockHash>> = block_hashes
.chunks(max_req_len)
.map(|chunk| chunk.to_vec())
.collect();

let mut chunk = match chunks.get(current_chunk_idx) {
Some(res) => res.clone(),
None => return Ok(()),
};

let mut current_block_hash_idx = 0;
loop {
debug!("Requesting Block Bodies ");
if let Some(block_bodies) = peers.request_block_bodies(block_hashes.clone()).await {
if let Some(block_bodies) = peers.request_block_bodies(chunk.clone()).await {
let block_bodies_len = block_bodies.len();
debug!("Received {} Block Bodies", block_bodies_len);
// Execute and store blocks
for (hash, body) in block_hashes
for (hash, body) in chunk
.drain(..block_bodies_len)
.zip(block_bodies.into_iter())
{
block_hashes.remove(current_block_hash_idx);
current_block_hash_idx += 1;
let header = store
.get_block_header_by_hash(hash)?
.ok_or(SyncError::CorruptDB)?;
Expand All @@ -293,13 +312,15 @@ async fn download_and_run_blocks(
last_valid_hash = hash;
}
debug!("Executed & stored {} blocks", block_bodies_len);
// Check if we need to ask for another batch
if block_hashes.is_empty() {
break;
}
if chunk.len() == 0 {
current_chunk_idx += 1;
chunk = match chunks.get(current_chunk_idx) {
Some(res) => res.clone(),
None => return Ok(()),
};
};
}
}
Ok(())
}

/// Fetches all block bodies for the given block hashes via p2p and stores them
Expand Down

0 comments on commit 9233597

Please sign in to comment.