Skip to content
This repository has been archived by the owner on Jun 20, 2024. It is now read-only.

Commit

Permalink
Fix fetch_previous_block_hashes going out of bounds (#12)
Browse files Browse the repository at this point in the history
  • Loading branch information
cpubot authored Dec 23, 2023
1 parent 9c86dc3 commit efaf274
Showing 1 changed file with 23 additions and 24 deletions.
47 changes: 23 additions & 24 deletions rpc/src/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,42 +143,41 @@ impl EthGetBlockByNumberResponse {
rpc_url: U,
block_number: u64,
) -> Result<Vec<H256>> {
let mut hashes = vec![H256::default(); 256];
if block_number == 0 {
return Ok(vec![H256::default(); 256]);
}

let mut hashes = Vec::with_capacity(256);

let padding_delta = block_number as i64 - 256;
if padding_delta < 0 {
let default = H256::default();
for _ in 0..padding_delta.abs() {
hashes.push(default);
}
}

// Every block response includes the _parent_ hash along with its hash, so we
// can just fetch half the blocks to acquire all hashes for the range.
let start = block_number.saturating_sub(256);
let futs: FuturesOrdered<_> = (start..=block_number)
.rev()
let mut futs: FuturesOrdered<_> = (start..=block_number)
.step_by(2)
.map(|block_number| Self::fetch(rpc_url, block_number))
.collect();

let responses = futs.try_collect::<Vec<_>>().await?;

// Check first response, which may be the current block
let starting_offset = {
if responses[0].result.number == block_number.into() {
// Ignore hash of the current block.
hashes[255] = responses[0].result.parent_hash;
254
} else {
hashes[255] = responses[0].result.hash;
hashes[254] = responses[0].result.parent_hash;
253
while let Some(response) = futs.try_next().await? {
// Ignore hash of the current block.
if response.result.number == block_number.into() {
hashes.push(response.result.parent_hash);
continue;
}
};

// Iterate over the block responses, skipping the first (possibly current)
// block.
for (idx, response) in responses.iter().skip(1).enumerate() {
if response.result.number == 0.into() {
// Genesis has no parent block, we only write the genesis hash.
hashes[starting_offset - 2 * idx] = response.result.hash;
// Ignore the parent of the start block.
if response.result.number != start.into() {
hashes.push(response.result.parent_hash);
}

hashes[starting_offset - 2 * idx] = response.result.hash;
hashes[starting_offset - 2 * idx - 1] = response.result.parent_hash;
hashes.push(response.result.hash);
}

Ok(hashes)
Expand Down

0 comments on commit efaf274

Please sign in to comment.