Skip to content

Commit

Permalink
fix: optimize previous hashes retrieval (#316)
Browse files Browse the repository at this point in the history
* fix: optimize previous hashes retrieval

* fix: comment

* fix: cleanup

* fix: naming

* fix: simplify
  • Loading branch information
atanmarko authored Jun 25, 2024
1 parent 201a67e commit e47a1f4
Showing 1 changed file with 38 additions and 14 deletions.
52 changes: 38 additions & 14 deletions zero_bin/rpc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ pub mod retry;

use compat::Compat;

const PREVIOUS_HASHES_COUNT: usize = 256;

/// The RPC type.
#[derive(ValueEnum, Clone, Debug)]
pub enum RpcType {
Expand Down Expand Up @@ -86,33 +88,55 @@ where
.context("target block is missing field `number`")?;
let chain_id = provider.get_chain_id().await?;

let mut prev_hashes = [alloy::primitives::B256::ZERO; 256];
let concurrency = prev_hashes.len();
futures::stream::iter(
prev_hashes
.iter_mut()
.rev() // fill RTL
.zip(std::iter::successors(Some(target_block_number), |it| {
it.checked_sub(1)
}))
.map(|(dst, n)| {
let previous_block_numbers =
std::iter::successors(Some(target_block_number as i128 - 1), |&it| Some(it - 1))
.take(PREVIOUS_HASHES_COUNT)
.filter(|i| *i >= 0)
.collect::<Vec<_>>();
let concurrency = previous_block_numbers.len();
let collected_hashes = futures::stream::iter(
previous_block_numbers
.chunks(2) // we get hash for previous and current block with one request
.map(|block_numbers| {
let provider = &provider;
let block_num = &block_numbers[0];
let previos_block_num = if block_numbers.len() > 1 {
Some(block_numbers[1])
} else {
// For genesis block
None
};
async move {
let block = provider
.get_block(n.into(), BlockTransactionsKind::Hashes)
.get_block((*block_num as u64).into(), BlockTransactionsKind::Hashes)
.await
.context("couldn't get block")?
.context("no such block")?;
*dst = block.header.parent_hash;
anyhow::Ok(())
anyhow::Ok([
(block.header.hash, Some(*block_num)),
(Some(block.header.parent_hash), previos_block_num),
])
}
}),
)
.buffered(concurrency)
.try_collect::<()>()
.try_collect::<Vec<_>>()
.await
.context("couldn't fill previous hashes")?;

let mut prev_hashes = [B256::ZERO; PREVIOUS_HASHES_COUNT];
collected_hashes
.into_iter()
.flatten()
.for_each(|(hash, block_num)| {
if let (Some(hash), Some(block_num)) = (hash, block_num) {
// Most recent previous block hash is expected at the end of the array
prev_hashes
[PREVIOUS_HASHES_COUNT - (target_block_number - block_num as u64) as usize] =
hash;
}
});

let other_data = OtherBlockData {
b_data: BlockLevelData {
b_meta: BlockMetadata {
Expand Down

0 comments on commit e47a1f4

Please sign in to comment.