Skip to content

Instantly share code, notes, and snippets.

@malik672
Created January 23, 2025 11:53
Show Gist options
  • Save malik672/6b97eb4927429c376ee70aa79a16b6c6 to your computer and use it in GitHub Desktop.
Save malik672/6b97eb4927429c376ee70aa79a16b6c6 to your computer and use it in GitHub Desktop.
pub fn benchmark_sync_blocks(c: &mut Criterion) {
let rt = Runtime::new().unwrap();
let rpc = RpcClient::new(
TransportBuilder::new(
"https://mainnet.infura.io/v3/f5fa2813a91241dbb0decd8872ee2154".to_string()
).build_http(),
);
let node = Node::new(
Arc::new(ConsensusImpl::new(
ConsensusConfig {
chain_id: 1,
finalized_block_number: 0,
genesis_hash: B256::default(),
finalized_block_hash: B256::default(),
sync_period: 10,
min_sync_comitee: 30,
},
Arc::new(rpc.clone()),
)),
Arc::new(rpc),
);
let mut group = c.benchmark_group("sync_operations");
// Benchmark block range sync with different sizes
let start_block = 17000000;
for size in [1000].iter() {
group.bench_function(format!("sync_{}_blocks", size), |b| {
b.iter(|| {
rt.block_on(async {
black_box(
node.sync_block_range(start_block, start_block + size).await.unwrap()
)
})
})
});
}
group.finish();
}
pub async fn sync_block_range(&self, start: u64, end: u64) -> Result<(), NodeError> {
const BATCH_SIZE: u64 = 10000;
const MAX_RETRIES: u32 = 5;
for batch_start in (start..end).step_by(BATCH_SIZE as usize) {
let batch_end = (batch_start + BATCH_SIZE).min(end);
let futures: Vec<_> = (batch_start..batch_end)
.map(|block_num| async move {
let mut attempt = 0;
loop {
match self.rpc.get_block_by_number(block_num, false).await {
Ok(Some(block)) => return Ok(block),
Ok(None) => return Ok(Block::default()),
Err(e) => {
attempt += 1;
if attempt >= MAX_RETRIES {
return Err(NodeError::Rpc(e.to_string()));
}
let delay = 1000 * 2u64.pow(attempt - 1);
info!(
"Failed to fetch block {}, attempt {}/{}. Retrying in {}ms. Error: {}",
block_num, attempt, MAX_RETRIES, delay, e
);
println!("Failed to fetch block {}, attempt {}/{}. Retrying in {}ms. Error: {}",
block_num, attempt, MAX_RETRIES, delay, e
);
tokio::time::sleep(Duration::from_millis(delay)).await;
continue;
}
}
}
})
.collect();
let _blocks = futures::future::join_all(futures)
.await
.into_iter()
.collect::<Result<Vec<_>, _>>()?;
}
// let mut state = self
// .SyncedState
// .as_ref()
// .ok_or(NodeError::State("SyncedState not initialized".to_string()))?
// .write()
// .await;
// state.current_block = end;
Ok(())
}
pub async fn get_block_by_number(
&self,
number: u64,
full_tx: bool,
) -> Result<Option<Block>, RpcError> {
let request = RpcRequest {
jsonrpc: "2.0",
method: "eth_getBlockByNumber",
params: json!([format!("0x{:x}", number), full_tx]),
id: 1,
};
let response_bytes: Vec<u8> = self.execute_raw(request).await?;
match parse_block(&response_bytes) {
Some(block) => Ok(Some(block)),
None => Ok(None)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment