11#![ allow( dead_code) ]
22use crate :: types:: * ;
33use alloy:: primitives:: B256 ;
4+ use futures:: { stream, StreamExt } ;
45use log:: debug;
56use reqwest:: Client ;
67use sp1_blobstream_primitives:: types:: ProofInputs ;
78use std:: sync:: Arc ;
89use std:: { collections:: HashMap , env, error:: Error } ;
910use subtle_encoding:: hex;
10- use tendermint:: block:: Commit ;
11+ use tendermint:: block:: { Commit , Header } ;
1112use tendermint:: validator:: Set as TendermintValidatorSet ;
13+ use tendermint:: Block ;
1214use 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.
3234const 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+
3439impl 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