@@ -48,6 +48,7 @@ use crate::{
4848
4949use clickhouse:: Client ;
5050use std:: { path:: PathBuf , sync:: Arc } ;
51+ use tokio:: task:: JoinHandle ;
5152
5253#[ derive( Debug , Clone , Deserialize , PartialEq , Eq , Default ) ]
5354pub struct ClickhouseConfig {
@@ -155,6 +156,7 @@ impl LiveBuilderConfig for FlashbotsConfig {
155156 where
156157 P : StateProviderFactory + Clone + ' static ,
157158 {
159+ let abort_token = CancellationToken :: new ( ) ;
158160 if self . l1_config . relay_bid_scrapers . is_empty ( ) {
159161 eyre:: bail!( "relay_bid_scrapers is not set" ) ;
160162 }
@@ -171,34 +173,45 @@ impl LiveBuilderConfig for FlashbotsConfig {
171173 )
172174 . await ?;
173175
174- let ( bid_observer, submission_policy) = self
175- . create_bid_observer_and_submission_policy ( & cancellation_token)
176+ let ( bid_observer, submission_policy, clickhouse_shutdown_handle ) = self
177+ . create_bid_observer_and_submission_policy ( & cancellation_token, & abort_token )
176178 . await ?;
177179
178- let ( sink_factory, slot_info_provider, adjustment_fee_payers) =
179- create_sink_factory_and_relays (
180- & self . base_config ,
181- & self . l1_config ,
182- bidding_service. relay_sets ( ) . to_vec ( ) ,
183- wallet_balance_watcher,
184- bid_observer,
185- submission_policy,
186- bidding_service. clone ( ) ,
187- cancellation_token. clone ( ) ,
188- )
189- . await ?;
180+ let (
181+ sink_factory,
182+ slot_info_provider,
183+ adjustment_fee_payers,
184+ optimistic_v3_server_join_handle,
185+ ) = create_sink_factory_and_relays (
186+ & self . base_config ,
187+ & self . l1_config ,
188+ bidding_service. relay_sets ( ) . to_vec ( ) ,
189+ wallet_balance_watcher,
190+ bid_observer,
191+ submission_policy,
192+ bidding_service. clone ( ) ,
193+ cancellation_token. clone ( ) ,
194+ )
195+ . await ?;
190196
191- let live_builder = create_builder_from_sink (
197+ let mut live_builder = create_builder_from_sink (
192198 & self . base_config ,
193199 & self . l1_config ,
194200 provider,
195201 sink_factory,
196202 slot_info_provider,
197203 adjustment_fee_payers,
198204 cancellation_token,
205+ abort_token,
199206 )
200207 . await ?;
201208
209+ if let Some ( handle) = clickhouse_shutdown_handle {
210+ live_builder. add_critical_task ( handle) ;
211+ }
212+ if let Some ( optimistic_v3_server_join_handle) = optimistic_v3_server_join_handle {
213+ live_builder. add_critical_task ( optimistic_v3_server_join_handle) ;
214+ }
202215 let mut module = RpcModule :: new ( ( ) ) ;
203216 module. register_async_method ( "bid_subsidiseBlock" , move |params, _| {
204217 handle_subsidise_block ( bidding_service. clone ( ) , params)
@@ -318,28 +331,35 @@ impl FlashbotsConfig {
318331 /// Depending on the cfg may create:
319332 /// - Dummy sink (no built_blocks_clickhouse_config)
320333 /// - BuiltBlocksWriter that writes to clickhouse
334+ ///
335+ /// Returns (BidObserver, RelaySubmissionPolicy, Option<JoinHandle> for clickhouse shutdown)
321336 #[ allow( clippy:: type_complexity) ]
322337 fn create_clickhouse_writer_and_submission_policy (
323338 & self ,
324- cancellation_token : & CancellationToken ,
339+ clickhouse_abort_token : & CancellationToken ,
325340 block_processor_key : Option < PrivateKeySigner > ,
326341 ) -> eyre:: Result < (
327342 Option < Box < dyn BidObserver + Send + Sync > > ,
328343 Box < dyn RelaySubmissionPolicy + Send + Sync > ,
344+ Option < JoinHandle < ( ) > > ,
329345 ) > {
330346 if let Some ( built_blocks_clickhouse_config) = & self . built_blocks_clickhouse_config {
331347 let rbuilder_version = rbuilder_version ( ) ;
332- let ( writer, submission_policy) = BuiltBlocksWriter :: new (
348+ let ( writer, submission_policy, shutdown_handle ) = BuiltBlocksWriter :: new (
333349 built_blocks_clickhouse_config. clone ( ) ,
334350 rbuilder_version. git_commit ,
335- cancellation_token . clone ( ) ,
351+ clickhouse_abort_token . clone ( ) ,
336352 ) ?;
337- Ok ( ( Some ( Box :: new ( writer) ) , submission_policy) )
353+ Ok ( (
354+ Some ( Box :: new ( writer) ) ,
355+ submission_policy,
356+ Some ( shutdown_handle) ,
357+ ) )
338358 } else {
339359 if block_processor_key. is_some ( ) {
340360 return Self :: bail_blocks_processor_url_not_set ( ) ;
341361 }
342- Ok ( ( None , Box :: new ( AlwaysSubmitPolicy { } ) ) )
362+ Ok ( ( None , Box :: new ( AlwaysSubmitPolicy { } ) , None ) )
343363 }
344364 }
345365
@@ -348,12 +368,17 @@ impl FlashbotsConfig {
348368 }
349369
350370 /// Depending on the cfg add a BlocksProcessorClientBidObserver and/or a true value pusher.
371+ /// Returns (BidObserver, RelaySubmissionPolicy, Option<JoinHandle> for clickhouse shutdown)
372+ /// cancellation_token: used to cancel tbv_pusher
373+ /// clickhouse_abort_token: used to cancel clickhouse tasks if source is hanged.
351374 async fn create_bid_observer_and_submission_policy (
352375 & self ,
353376 cancellation_token : & CancellationToken ,
377+ clickhouse_abort_token : & CancellationToken ,
354378 ) -> eyre:: Result < (
355379 Box < dyn BidObserver + Send + Sync > ,
356380 Box < dyn RelaySubmissionPolicy + Send + Sync > ,
381+ Option < JoinHandle < ( ) > > ,
357382 ) > {
358383 let block_processor_key = if let Some ( key_registration_url) = & self . key_registration_url {
359384 if self . blocks_processor_url . is_none ( ) {
@@ -364,16 +389,20 @@ impl FlashbotsConfig {
364389 None
365390 } ;
366391
367- let ( clickhouse_writer, submission_policy) = self
392+ let ( clickhouse_writer, submission_policy, clickhouse_shutdown_handle ) = self
368393 . create_clickhouse_writer_and_submission_policy (
369- cancellation_token ,
394+ clickhouse_abort_token ,
370395 block_processor_key. clone ( ) ,
371396 ) ?;
372397 let bid_observer = RbuilderOperatorBidObserver {
373398 clickhouse_writer,
374399 tbv_pusher : self . create_tbv_pusher ( block_processor_key, cancellation_token) ?,
375400 } ;
376- Ok ( ( Box :: new ( bid_observer) , submission_policy) )
401+ Ok ( (
402+ Box :: new ( bid_observer) ,
403+ submission_policy,
404+ clickhouse_shutdown_handle,
405+ ) )
377406 }
378407
379408 fn create_tbv_pusher (
0 commit comments