//! 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`. pub 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; } /// A boxed exex future. pub type BoxExEx = BoxFuture<'static, eyre::Result<()>>; /// A version of [`LaunchExEx`] that returns a boxed future. Makes the trait object-safe. pub trait BoxedLaunchExEx: Send { /// Launches the `ExEx` and returns a boxed future. 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) } }