Skip to content

Commit 5224e74

Browse files
authored
feat(operator): reduce number of rpc requests (#46)
1 parent 2aecf55 commit 5224e74

File tree

2 files changed

+45
-26
lines changed

2 files changed

+45
-26
lines changed

script/bin/operator.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,9 +113,11 @@ impl SP1BlobstreamOperator {
113113
let rpc_client = TendermintRPCClient::default();
114114
let mut stdin = SP1Stdin::new();
115115

116+
info!("Fetching inputs for proof.");
116117
let inputs = rpc_client
117118
.fetch_input_for_blobstream_proof(trusted_block, target_block)
118119
.await;
120+
info!("Inputs fetched for proof.");
119121

120122
// Simulate the step from the trusted block to the target block.
121123
let verdict =

script/src/util.rs

Lines changed: 43 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
#![allow(dead_code)]
22
use crate::types::*;
33
use alloy::primitives::B256;
4+
use futures::{stream, StreamExt};
45
use log::debug;
56
use reqwest::Client;
67
use sp1_blobstream_primitives::types::ProofInputs;
78
use std::sync::Arc;
89
use std::{collections::HashMap, env, error::Error};
910
use subtle_encoding::hex;
10-
use tendermint::block::Commit;
11+
use tendermint::block::{Commit, Header};
1112
use tendermint::validator::Set as TendermintValidatorSet;
13+
use tendermint::Block;
1214
use tendermint::{
1315
block::signed_header::SignedHeader,
1416
node::Id,
@@ -31,6 +33,9 @@ impl Default for TendermintRPCClient {
3133
/// The default timeout for Tendermint RPC requests in seconds.
3234
const DEFAULT_TENDERMINT_RPC_TIMEOUT_SECS: u64 = 20;
3335

36+
/// The default concurrency for Tendermint RPC requests.
37+
const DEFAULT_TENDERMINT_RPC_CONCURRENCY: usize = 100;
38+
3439
impl TendermintRPCClient {
3540
pub fn new(url: String) -> Self {
3641
let client = Client::builder()
@@ -50,18 +55,16 @@ impl TendermintRPCClient {
5055
trusted_block_height: u64,
5156
target_block_height: u64,
5257
) -> ProofInputs {
53-
let light_blocks = self
54-
.fetch_light_blocks_in_range(trusted_block_height, target_block_height)
58+
let (trusted_light_block, target_light_block) = self
59+
.get_light_blocks(trusted_block_height, target_block_height)
60+
.await;
61+
let headers = self
62+
.get_headers_in_range(trusted_block_height + 1, target_block_height - 1)
5563
.await;
56-
57-
let mut headers = Vec::new();
58-
for light_block in &light_blocks[1..light_blocks.len() - 1] {
59-
headers.push(light_block.signed_header.header.clone());
60-
}
6164

6265
ProofInputs {
63-
trusted_light_block: light_blocks[0].clone(),
64-
target_light_block: light_blocks[light_blocks.len() - 1].clone(),
66+
trusted_light_block,
67+
target_light_block,
6568
headers,
6669
}
6770
}
@@ -97,27 +100,16 @@ impl TendermintRPCClient {
97100
end_height: u64,
98101
) -> Vec<LightBlock> {
99102
let peer_id = self.fetch_peer_id().await.unwrap();
100-
let batch_size = 25;
101-
let mut blocks = Vec::new();
102103
debug!(
103104
"Fetching light blocks in range: {} to {}",
104105
start_height, end_height
105106
);
106107

107-
for batch_start in (start_height..=end_height).step_by(batch_size) {
108-
let batch_end = std::cmp::min(batch_start + (batch_size as u64) - 1, end_height);
109-
let mut handles = Vec::new();
110-
111-
for height in batch_start..=batch_end {
112-
let fetch_light_block =
113-
async move { self.fetch_light_block(height, peer_id).await.unwrap() };
114-
handles.push(fetch_light_block);
115-
}
116-
117-
// Join all the futures in the current batch
118-
let batch_blocks = futures::future::join_all(handles).await;
119-
blocks.extend(batch_blocks);
120-
}
108+
let blocks = stream::iter(start_height..=end_height)
109+
.map(|height| async move { self.fetch_light_block(height, peer_id).await.unwrap() })
110+
.buffered(DEFAULT_TENDERMINT_RPC_CONCURRENCY)
111+
.collect::<Vec<_>>()
112+
.await;
121113

122114
debug!("Finished fetching light blocks!");
123115
blocks
@@ -142,6 +134,24 @@ impl TendermintRPCClient {
142134
(trusted_light_block, target_light_block)
143135
}
144136

137+
/// Retrieves the block from the Tendermint node.
138+
pub async fn get_block(&self, height: u64) -> Block {
139+
let block = self.fetch_block_by_height(height).await.unwrap();
140+
block.result.block
141+
}
142+
143+
/// Retrieves the headers for the given range of block heights. Inclusive of start and end.
144+
pub async fn get_headers_in_range(&self, start_height: u64, end_height: u64) -> Vec<Header> {
145+
let mut headers = Vec::new();
146+
let headers_stream = stream::iter(start_height..=end_height)
147+
.map(|height| async move { self.get_block(height).await.header })
148+
.buffered(DEFAULT_TENDERMINT_RPC_CONCURRENCY)
149+
.collect::<Vec<_>>()
150+
.await;
151+
headers.extend(headers_stream);
152+
headers
153+
}
154+
145155
/// Retrieves the latest block height from the Tendermint node.
146156
pub async fn get_latest_block_height(&self) -> u64 {
147157
let latest_commit = self.fetch_latest_commit().await.unwrap();
@@ -226,6 +236,13 @@ impl TendermintRPCClient {
226236
.unwrap()
227237
}
228238

239+
/// Fetches the block by its height.
240+
async fn fetch_block_by_height(&self, height: u64) -> Result<BlockResponse, Box<dyn Error>> {
241+
let url = format!("{}/block?height={}", self.url, height);
242+
let response: BlockResponse = self.client.get(url).send().await?.json().await?;
243+
Ok(response)
244+
}
245+
229246
/// Fetches the latest commit from the Tendermint node.
230247
async fn fetch_latest_commit(&self) -> Result<CommitResponse, Box<dyn Error>> {
231248
let url = format!("{}/commit", self.url);

0 commit comments

Comments
 (0)