88 exporter:: Exporter ,
99 transactions:: Transactions ,
1010 } ,
11+ utils:: rpc_multi_client:: RpcMultiClient ,
1112 } ,
1213 anyhow:: Result ,
1314 futures_util:: future,
1415 serde:: {
1516 Deserialize ,
1617 Serialize ,
1718 } ,
18- solana_client:: nonblocking:: rpc_client:: RpcClient ,
1919 solana_sdk:: commitment_config:: CommitmentConfig ,
2020 std:: {
2121 sync:: Arc ,
2727 time:: Interval ,
2828 } ,
2929 tracing:: instrument,
30+ url:: Url ,
3031} ;
3132
3233#[ derive( Clone , Serialize , Deserialize , Debug ) ]
@@ -111,7 +112,7 @@ pub struct NetworkState {
111112/// fetching the blockhash and slot number.
112113struct NetworkStateQuerier {
113114 /// The RPC client
114- rpc_clients : Vec < RpcClient > ,
115+ rpc_multi_client : RpcMultiClient ,
115116
116117 /// The interval with which to query the network state
117118 query_interval : Interval ,
@@ -129,17 +130,14 @@ impl NetworkStateQuerier {
129130 )
130131 ) ]
131132 pub fn new (
132- rpc_urls : & Vec < String > ,
133+ rpc_urls : & Vec < Url > ,
133134 rpc_timeout : Duration ,
134135 query_interval : Interval ,
135136 network_state_tx : watch:: Sender < NetworkState > ,
136137 ) -> Self {
137- let rpc_clients = rpc_urls
138- . iter ( )
139- . map ( |rpc_url| RpcClient :: new_with_timeout ( rpc_url. clone ( ) , rpc_timeout) )
140- . collect ( ) ;
138+ let rpc_multi_client = RpcMultiClient :: new_with_timeout ( rpc_urls. clone ( ) , rpc_timeout) ;
141139 NetworkStateQuerier {
142- rpc_clients ,
140+ rpc_multi_client ,
143141 query_interval,
144142 network_state_tx,
145143 }
@@ -156,12 +154,11 @@ impl NetworkStateQuerier {
156154
157155 #[ instrument( skip( self ) ) ]
158156 async fn query_network_state ( & mut self ) -> Result < ( ) > {
159- // TODO: These are polled every 200ms and errors are simply logged.
160- // TODO: Should we retry/fallback on failure?
161157 // Fetch the blockhash and current slot in parallel
162- let current_slot_future =
163- self . rpc_clients [ 0 ] . get_slot_with_commitment ( CommitmentConfig :: confirmed ( ) ) ;
164- let latest_blockhash_future = self . rpc_clients [ 0 ] . get_latest_blockhash ( ) ;
158+ let current_slot_future = self
159+ . rpc_multi_client
160+ . get_slot_with_commitment ( CommitmentConfig :: confirmed ( ) ) ;
161+ let latest_blockhash_future = self . rpc_multi_client . get_latest_blockhash ( ) ;
165162
166163 let ( current_slot_result, latest_blockhash_result) =
167164 future:: join ( current_slot_future, latest_blockhash_future) . await ;
@@ -229,8 +226,8 @@ mod exporter {
229226 publish_batches,
230227 Exporter ,
231228 } ,
229+ utils:: rpc_multi_client:: RpcMultiClient ,
232230 } ,
233- solana_client:: nonblocking:: rpc_client:: RpcClient ,
234231 solana_sdk:: commitment_config:: CommitmentConfig ,
235232 std:: sync:: Arc ,
236233 tokio:: sync:: watch,
@@ -249,21 +246,14 @@ mod exporter {
249246 let mut dynamic_compute_unit_price_update_interval =
250247 tokio:: time:: interval ( config. exporter . publish_interval_duration ) ;
251248
252- let clients: Arc < Vec < RpcClient > > = Arc :: new (
253- config
254- . rpc_urls
255- . iter ( )
256- . map ( |rpc_url| {
257- RpcClient :: new_with_timeout_and_commitment (
258- rpc_url. clone ( ) ,
259- config. rpc_timeout ,
260- CommitmentConfig {
261- commitment : config. oracle . commitment ,
262- } ,
263- )
264- } )
265- . collect ( ) ,
266- ) ;
249+ let rpc_multi_client: Arc < RpcMultiClient > =
250+ Arc :: new ( RpcMultiClient :: new_with_timeout_and_commitment (
251+ config. rpc_urls . clone ( ) ,
252+ config. rpc_timeout ,
253+ CommitmentConfig {
254+ commitment : config. oracle . commitment ,
255+ } ,
256+ ) ) ;
267257 let Ok ( key_store) = KeyStore :: new ( config. key_store . clone ( ) ) else {
268258 tracing:: warn!( "Key store not available, Exporter won't start." ) ;
269259 return ;
@@ -282,7 +272,7 @@ mod exporter {
282272 let publisher_buffer_key = Exporter :: get_publisher_buffer_key( & * state) . await ;
283273 if let Err ( err) = publish_batches(
284274 state. clone( ) ,
285- clients . clone( ) ,
275+ rpc_multi_client . clone( ) ,
286276 network,
287277 & network_state_rx,
288278 key_store. accumulator_key,
@@ -310,7 +300,7 @@ mod exporter {
310300 if let Err ( err) = Exporter :: update_recent_compute_unit_price(
311301 & * state,
312302 & publish_keypair,
313- & clients ,
303+ & rpc_multi_client ,
314304 config. exporter. staleness_threshold,
315305 config. exporter. unchanged_publish_threshold,
316306 ) . await {
@@ -329,12 +319,12 @@ mod transaction_monitor {
329319 crate :: agent:: {
330320 solana:: network,
331321 state:: transactions:: Transactions ,
322+ utils:: rpc_multi_client:: RpcMultiClient ,
332323 } ,
333324 serde:: {
334325 Deserialize ,
335326 Serialize ,
336327 } ,
337- solana_client:: nonblocking:: rpc_client:: RpcClient ,
338328 std:: {
339329 sync:: Arc ,
340330 time:: Duration ,
@@ -369,17 +359,16 @@ mod transaction_monitor {
369359 where
370360 S : Transactions ,
371361 {
372- let rpc_clients = config
373- . rpc_urls
374- . iter ( )
375- . map ( |rpc_url| RpcClient :: new_with_timeout ( rpc_url. clone ( ) , config. rpc_timeout ) )
376- . collect ( ) ;
362+ let rpc_multi_client =
363+ RpcMultiClient :: new_with_timeout ( config. rpc_urls . clone ( ) , config. rpc_timeout ) ;
377364 let mut poll_interval =
378365 tokio:: time:: interval ( config. exporter . transaction_monitor . poll_interval_duration ) ;
379366
380367 loop {
381368 poll_interval. tick ( ) . await ;
382- if let Err ( err) = Transactions :: poll_transactions_status ( & * state, & rpc_clients) . await {
369+ if let Err ( err) =
370+ Transactions :: poll_transactions_status ( & * state, & rpc_multi_client) . await
371+ {
383372 tracing:: error!( err = ?err, "Transaction monitor failed." ) ;
384373 }
385374 }
0 commit comments