Skip to content

Commit

Permalink
feat(hera): Subcommands (#63)
Browse files Browse the repository at this point in the history
### Description

> [!WARNING]
>
> Blocked by #62.

Splits the `hera` command into `network` and `node` subcommands to clean
up the binary entrypoints.
  • Loading branch information
refcell authored Aug 31, 2024
1 parent a63e429 commit 0bbb8e4
Show file tree
Hide file tree
Showing 4 changed files with 137 additions and 46 deletions.
19 changes: 19 additions & 0 deletions bin/hera/src/globals.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//! Global arguments for the Hera CLI.
use clap::Parser;

/// Global arguments for the Hera CLI.
#[derive(Parser, Clone, Debug)]
pub(crate) struct GlobalArgs {
/// The L2 chain ID to use.
#[clap(long, short = 'c', default_value = "10", help = "The L2 chain ID to use")]
pub l2_chain_id: u64,
/// A port to serve prometheus metrics on.
#[clap(
long,
short = 'm',
default_value = "9090",
help = "The port to serve prometheus metrics on"
)]
pub metrics_port: u16,
}
79 changes: 33 additions & 46 deletions bin/hera/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,60 +4,47 @@
#![doc(issue_tracker_base_url = "https://github.com/paradigmxyz/op-rs/issues/")]
#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]

use clap::Parser;
use clap::{Parser, Subcommand};
use eyre::Result;
use op_net::driver::NetworkDriver;
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
use superchain_registry::ROLLUP_CONFIGS;

/// The default L2 chain ID to use. This corresponds to OP Mainnet.
pub const DEFAULT_L2_CHAIN_ID: u64 = 10;
mod globals;
mod network;
mod node;

/// The Hera CLI Arguments.
#[derive(Debug, Clone, Parser)]
pub struct HeraArgs {
/// Chain ID of the L2 network
#[clap(long = "hera.l2-chain-id", default_value_t = DEFAULT_L2_CHAIN_ID)]
pub l2_chain_id: u64,
#[derive(Parser, Clone, Debug)]
#[command(author, version, about, long_about = None)]
pub(crate) struct HeraArgs {
/// Global arguments for the Hera CLI.
#[clap(flatten)]
pub global: globals::GlobalArgs,
/// The subcommand to run.
#[clap(subcommand)]
pub subcommand: HeraSubcommand,
}

/// Subcommands for the CLI.
#[derive(Debug, Clone, Subcommand)]
pub(crate) enum HeraSubcommand {
/// Run the standalone Hera node.
Node(node::NodeCommand),
/// Networking utility commands.
Network(network::NetworkCommand),
}

#[tokio::main]
async fn main() -> Result<()> {
// Parse arguments.
let args = HeraArgs::parse();
rollup::init_telemetry_stack(8090)?;

tracing::info!("Hera OP Stack Rollup node");

let signer = ROLLUP_CONFIGS
.get(&args.l2_chain_id)
.ok_or(eyre::eyre!("No rollup config found for chain ID"))?
.genesis
.system_config
.as_ref()
.ok_or(eyre::eyre!("No system config found for chain ID"))?
.batcher_address;
let socket = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), 9099);
let mut driver = NetworkDriver::builder()
.with_chain_id(args.l2_chain_id)
.with_unsafe_block_signer(signer)
.with_gossip_addr(socket)
.build()
.expect("Failed to builder network driver");

// Call `.start()` on the driver.
let recv = driver.take_unsafe_block_recv().ok_or(eyre::eyre!("No unsafe block receiver"))?;
driver.start().expect("Failed to start network driver");

tracing::info!("NetworkDriver started successfully.");

loop {
match recv.recv() {
Ok(block) => {
tracing::info!("Received unsafe block: {:?}", block);
}
Err(e) => {
tracing::warn!("Failed to receive unsafe block: {:?}", e);
}
}

// Initialize the telemetry stack.
rollup::init_telemetry_stack(args.global.metrics_port)?;

// Dispatch on subcommand.
match args.subcommand {
HeraSubcommand::Node(node) => node.run(&args.global).await?,
HeraSubcommand::Network(network) => network.run(&args.global).await?,
}

Ok(())
}
68 changes: 68 additions & 0 deletions bin/hera/src/network.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
//! Networking subcommand for Hera.
use crate::globals::GlobalArgs;
use clap::Args;
use eyre::Result;
use op_net::driver::NetworkDriver;
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
use superchain_registry::ROLLUP_CONFIGS;

/// The Hera network subcommand.
#[derive(Debug, Clone, Args)]
#[non_exhaustive]
pub struct NetworkCommand {
/// Run the peer discovery service.
#[clap(long, short = 'p', help = "Runs peer discovery")]
pub disc: bool,
/// Run the gossip driver.
#[clap(long, short = 'g', help = "Runs the unsafe block gossipping service")]
pub gossip: bool,
/// Port to listen for gossip on.
#[clap(long, short = 'l', default_value = "9099", help = "Port to listen for gossip on")]
pub gossip_port: u16,
}

impl NetworkCommand {
/// Run the network subcommand.
pub async fn run(&self, args: &GlobalArgs) -> Result<()> {
if self.disc {
println!("Running peer discovery");
}
if self.gossip {
println!("Running gossip driver");
}
let signer = ROLLUP_CONFIGS
.get(&args.l2_chain_id)
.ok_or(eyre::eyre!("No rollup config found for chain ID"))?
.genesis
.system_config
.as_ref()
.ok_or(eyre::eyre!("No system config found for chain ID"))?
.batcher_address;
let socket = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), self.gossip_port);
let mut driver = NetworkDriver::builder()
.with_chain_id(args.l2_chain_id)
.with_unsafe_block_signer(signer)
.with_gossip_addr(socket)
.build()
.expect("Failed to builder network driver");

// Call `.start()` on the driver.
let recv =
driver.take_unsafe_block_recv().ok_or(eyre::eyre!("No unsafe block receiver"))?;
driver.start().expect("Failed to start network driver");

tracing::info!("NetworkDriver started successfully.");

loop {
match recv.recv() {
Ok(block) => {
tracing::info!("Received unsafe block: {:?}", block);
}
Err(e) => {
tracing::warn!("Failed to receive unsafe block: {:?}", e);
}
}
}
}
}
17 changes: 17 additions & 0 deletions bin/hera/src/node.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//! Node subcommand for Hera.
use crate::globals::GlobalArgs;
use clap::Args;
use eyre::Result;

/// The Hera node subcommand.
#[derive(Debug, Clone, Args)]
#[non_exhaustive]
pub struct NodeCommand {}

impl NodeCommand {
/// Run the node subcommand.
pub async fn run(&self, _args: &GlobalArgs) -> Result<()> {
unimplemented!()
}
}

0 comments on commit 0bbb8e4

Please sign in to comment.