//! Types for launching execution extensions (ExEx). use futures::{future::BoxFuture, FutureExt}; use reth_exex::ExExContext; use reth_node_api::FullNodeComponents; use std::future::Future; /// A trait for launching an ExEx. trait LaunchExEx: Send { /// Launches the ExEx. /// /// The ExEx should be able to run independently and emit events on the channels provided in /// the [`ExExContext`]. fn launch( self, ctx: ExExContext, ) -> impl Future> + Send>> + Send; } type BoxExEx = BoxFuture<'static, eyre::Result<()>>; /// A version of [LaunchExEx] that returns a boxed future. Makes the trait object-safe. pub(crate) trait BoxedLaunchExEx: Send { fn launch(self: Box, ctx: ExExContext) -> BoxFuture<'static, eyre::Result>; } /// Implements [BoxedLaunchExEx] for any [LaunchExEx] that is [Send] and `'static`. /// /// Returns a [BoxFuture] that resolves to a [BoxExEx]. impl BoxedLaunchExEx for E where E: LaunchExEx + Send + 'static, Node: FullNodeComponents, { fn launch( self: Box, ctx: ExExContext, ) -> BoxFuture<'static, eyre::Result> { async move { let exex = LaunchExEx::launch(*self, ctx).await?; Ok(Box::pin(exex) as BoxExEx) } .boxed() } } /// Implements `LaunchExEx` for any closure that takes an [ExExContext] and returns a future /// resolving to an ExEx. impl LaunchExEx for F where Node: FullNodeComponents, F: FnOnce(ExExContext) -> Fut + Send, Fut: Future> + Send, E: Future> + Send, { fn launch( self, ctx: ExExContext, ) -> impl Future> + Send>> + Send { self(ctx) } }