diff --git a/Cargo.lock b/Cargo.lock index 3a1620059109..8677e0681894 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4664,6 +4664,22 @@ dependencies = [ "unicase", ] +[[package]] +name = "minimal" +version = "0.0.0" +dependencies = [ + "eyre", + "futures", + "reth", + "reth-exex", + "reth-node-api", + "reth-node-core", + "reth-node-ethereum", + "reth-primitives", + "reth-provider", + "tokio", +] + [[package]] name = "minimal-lexical" version = "0.2.1" diff --git a/Cargo.toml b/Cargo.toml index a9d0fd7ed8e1..e35b8ccd6be8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -77,6 +77,7 @@ members = [ "examples/trace-transaction-cli/", "examples/polygon-p2p/", "examples/custom-inspector/", + "examples/exex/minimal/", "testing/ef-tests/", ] default-members = ["bin/reth"] diff --git a/examples/exex/minimal/Cargo.toml b/examples/exex/minimal/Cargo.toml new file mode 100644 index 000000000000..c1c586fd5c38 --- /dev/null +++ b/examples/exex/minimal/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "minimal" +version = "0.0.0" +publish = false +edition.workspace = true +license.workspace = true + +[dependencies] +reth.workspace = true +reth-exex.workspace = true +reth-node-api.workspace = true +reth-node-core.workspace = true +reth-node-ethereum.workspace = true +reth-primitives.workspace = true +reth-provider.workspace = true + +eyre.workspace = true +tokio.workspace = true +futures.workspace = true diff --git a/examples/exex/minimal/src/main.rs b/examples/exex/minimal/src/main.rs new file mode 100644 index 000000000000..671d9e7dedb0 --- /dev/null +++ b/examples/exex/minimal/src/main.rs @@ -0,0 +1,57 @@ +use std::{ + pin::Pin, + task::{Context, Poll}, +}; + +use futures::Future; +use reth::builder::FullNodeTypes; +use reth_exex::{ExExContext, ExExEvent}; +use reth_node_ethereum::EthereumNode; +use reth_provider::CanonStateNotification; + +struct MinimalExEx { + ctx: ExExContext, +} + +impl Future for MinimalExEx { + type Output = eyre::Result<()>; + + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let this = self.get_mut(); + + // Process all new chain state notifications until there are no more + while let Poll::Ready(Some(notification)) = this.ctx.notifications.poll_recv(cx) { + // Process one notification + match ¬ification { + CanonStateNotification::Commit { new } => { + println!("Received commit: {:?}", new.first().number..=new.tip().number); + } + CanonStateNotification::Reorg { old, new } => { + println!( + "Received reorg: {:?} -> {:?}", + old.first().number..=old.tip().number, + new.first().number..=new.tip().number + ); + } + }; + + // Send a finished height event, signaling the node that we don't need any blocks below + // this height anymore + this.ctx.events.send(ExExEvent::FinishedHeight(notification.tip().number))?; + } + + Poll::Pending + } +} + +fn main() -> eyre::Result<()> { + reth::cli::Cli::parse_args().run(|builder, _| async move { + let handle = builder + .node(EthereumNode::default()) + .install_exex("Optimism", move |ctx| futures::future::ok(MinimalExEx { ctx })) + .launch() + .await?; + + handle.wait_for_node_exit().await + }) +}