feat: add cli ext event hooks example (#4935)

This commit is contained in:
Matthias Seitz
2023-10-06 20:05:03 +02:00
committed by GitHub
parent c825aafbc8
commit 36306ce916
6 changed files with 108 additions and 1 deletions

10
Cargo.lock generated
View File

@ -1267,6 +1267,16 @@ version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961"
[[package]]
name = "cli-extension-event-hooks"
version = "0.0.0"
dependencies = [
"clap",
"eyre",
"reth",
"tokio",
]
[[package]]
name = "cobs"
version = "0.2.3"

View File

@ -48,6 +48,7 @@ members = [
"crates/rpc/rpc-types-compat",
"examples",
"examples/additional-rpc-namespace-in-cli",
"examples/cli-extension-event-hooks",
"examples/rpc-db",
"examples/manual-p2p",
]

View File

@ -8,7 +8,7 @@ use clap::Args;
use reth_basic_payload_builder::{BasicPayloadJobGenerator, BasicPayloadJobGeneratorConfig};
use reth_payload_builder::{PayloadBuilderHandle, PayloadBuilderService};
use reth_tasks::TaskSpawner;
use std::fmt;
use std::{fmt, marker::PhantomData};
/// A trait that allows for extending parts of the CLI with additional functionality.
///
@ -119,6 +119,14 @@ impl RethNodeCommandConfig for DefaultRethNodeCommandConfig {}
impl RethNodeCommandConfig for () {}
/// A helper type for [RethCliExt] extension that don't require any additional clap Arguments.
#[derive(Debug, Clone, Copy)]
pub struct NoArgsCliExt<Conf>(PhantomData<Conf>);
impl<Conf: RethNodeCommandConfig> RethCliExt for NoArgsCliExt<Conf> {
type Node = NoArgs<Conf>;
}
/// A helper struct that allows for wrapping a [RethNodeCommandConfig] value without providing
/// additional CLI arguments.
///
@ -214,6 +222,12 @@ impl<T: RethNodeCommandConfig> RethNodeCommandConfig for NoArgs<T> {
}
}
impl<T> From<T> for NoArgs<T> {
fn from(value: T) -> Self {
Self::with(value)
}
}
#[cfg(test)]
mod tests {
use super::*;

View File

@ -113,6 +113,15 @@ impl<Ext: RethCliExt> Cli<Ext> {
reth_tracing::init(layers);
Ok(guard.flatten())
}
/// Configures the given node extension.
pub fn with_node_extension<C>(mut self, conf: C) -> Self
where
C: Into<Ext::Node>,
{
self.command.set_node_extension(conf.into());
self
}
}
/// Convenience function for parsing CLI options, set up logging and run the chosen command.
@ -156,6 +165,17 @@ pub enum Commands<Ext: RethCliExt = ()> {
Recover(recover::Command),
}
impl<Ext: RethCliExt> Commands<Ext> {
/// Sets the node extension if it is the [NodeCommand](node::NodeCommand).
///
/// This is a noop if the command is not the [NodeCommand](node::NodeCommand).
pub fn set_node_extension(&mut self, ext: Ext::Node) {
if let Commands::Node(command) = self {
command.ext = ext
}
}
}
/// The log configuration.
#[derive(Debug, Args)]
#[command(next_help_heading = "Logging")]

View File

@ -0,0 +1,11 @@
[package]
name = "cli-extension-event-hooks"
version = "0.0.0"
publish = false
edition.workspace = true
license.workspace = true
[dependencies]
reth.workspace = true
clap.workspace = true
eyre = "0.6"

View File

@ -0,0 +1,51 @@
//! Example for how hook into the node via the CLI extension mechanism without registering
//! additional arguments
//!
//! Run with
//!
//! ```not_rust
//! cargo run -p cli-extension-event-hooks -- node
//! ```
//!
//! This launch the regular reth node and also print:
//!
//! > "All components initialized"
//! once all components have been initialized and
//!
//! > "Node started"
//! once the node has been started.
use clap::Parser;
use reth::cli::{
components::RethNodeComponents,
ext::{NoArgsCliExt, RethNodeCommandConfig},
Cli,
};
fn main() {
Cli::<NoArgsCliExt<MyRethConfig>>::parse()
.with_node_extension(MyRethConfig::default())
.run()
.unwrap();
}
/// Our custom cli args extension that adds one flag to reth default CLI.
#[derive(Debug, Clone, Copy, Default)]
#[non_exhaustive]
struct MyRethConfig;
impl RethNodeCommandConfig for MyRethConfig {
fn on_components_initialized<Reth: RethNodeComponents>(
&mut self,
_components: &Reth,
) -> eyre::Result<()> {
println!("All components initialized");
Ok(())
}
fn on_node_started<Reth: RethNodeComponents>(
&mut self,
_components: &Reth,
) -> eyre::Result<()> {
println!("Node started");
Ok(())
}
}