Skip to content

Commit

Permalink
feat: driver
Browse files Browse the repository at this point in the history
  • Loading branch information
refcell committed Nov 11, 2024
1 parent 243cffe commit 011e6f3
Show file tree
Hide file tree
Showing 15 changed files with 476 additions and 4 deletions.
128 changes: 126 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[workspace]
members = ["crates/*"]
members = ["crates/*", "bin/*"]
resolver = "2"

[workspace.package]
Expand Down Expand Up @@ -38,6 +38,9 @@ rustdoc-args = ["--cfg", "docsrs"]

[workspace.dependencies]
# Workspace
super = { version = "0.11.0", path = "crates/super", default-features = false }
super-net = { version = "0.11.0", path = "crates/net", default-features = false }
super-driver = { version = "0.11.0", path = "crates/driver", default-features = false }
super-derive = { version = "0.11.0", path = "crates/derive", default-features = false }
super-registry = { version = "0.11.0", path = "crates/registry", default-features = false }

Expand Down Expand Up @@ -83,6 +86,7 @@ arbitrary = "1"
# Misc
lru = "0.12.5"
eyre = "0.6.12"
clap = "4.5.20"
tokio = "1.41.0"
futures = "0.3.31"
reqwest = "0.12.9"
Expand Down
24 changes: 24 additions & 0 deletions bin/hera/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
[package]
name = "hera"
version = "0.1.0"
description = "Hera is a Rust implementation of the OP Stack Rollup Node"

edition.workspace = true
authors.workspace = true
license.workspace = true
keywords.workspace = true
repository.workspace = true
categories.workspace = true
rust-version.workspace = true

[dependencies]
# Local
super.workspace = true
super-net.workspace = true
super-driver.workspace = true

# Workspace
eyre.workspace = true
tracing.workspace = true
clap = { workspace = true, features = ["derive", "env"] }
tokio = { workspace = true, features = ["rt-multi-thread", "macros"] }
26 changes: 26 additions & 0 deletions bin/hera/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
## `hera`

_Hera is a Rust implementation of the [OP Stack][opstack] Rollup node._

### Overview

Hera can be run as either a standalone node or as an [Execution Extension][exex]
on top of an L1 [Reth][reth] node in the same process.

Under the hood, Hera is powered by the [Kona-derive][kona] library which handles
the [derivation pipeline][derivation] of the L2 payloads from L1 transactions.

### Usage

```
cargo run --bin hera
```


<!-- Links -->

[reth]: https://github.com/paradigmxyz/reth
[kona]: https://github.com/ethereum-optimism/kona
[exex]: https://www.paradigm.xyz/2024/05/reth-exex
[opstack]: https://docs.optimism.io/
[derivation]: https://docs.optimism.io/stack/protocol/derivation-pipeline
45 changes: 45 additions & 0 deletions bin/hera/src/disc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
//! Discovery subcommand for Hera.
use crate::globals::GlobalArgs;
use clap::Args;
use eyre::Result;
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
use super_net::discovery::builder::DiscoveryBuilder;

/// The Hera discovery subcommand.
#[derive(Debug, Clone, Args)]
#[non_exhaustive]
pub struct DiscCommand {
/// Port to listen for gossip on.
#[clap(long, short = 'l', default_value = "9099", help = "Port to listen for gossip on")]
pub gossip_port: u16,
/// Interval to send discovery packets.
#[clap(long, short = 'i', default_value = "1", help = "Interval to send discovery packets")]
pub interval: u64,
}

impl DiscCommand {
/// Run the discovery subcommand.
pub async fn run(self, args: &GlobalArgs) -> Result<()> {
let socket = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), self.gossip_port);
tracing::info!("Starting discovery service on {:?}", socket);

let mut discovery_builder =
DiscoveryBuilder::new().with_address(socket).with_chain_id(args.l2_chain_id);
let mut discovery = discovery_builder.build()?;
discovery.interval = std::time::Duration::from_secs(self.interval);
let mut peer_recv = discovery.start()?;
tracing::info!("Discovery service started, receiving peers.");

loop {
match peer_recv.recv().await {
Some(peer) => {
tracing::info!("Received peer: {:?}", peer);
}
None => {
tracing::warn!("Failed to receive peer");
}
}
}
}
}
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,
}
59 changes: 59 additions & 0 deletions bin/hera/src/gossip.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
//! Gossip subcommand for Hera.
use super::ROLLUP_CONFIGS;
use crate::globals::GlobalArgs;
use clap::Args;
use eyre::Result;
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
use super_net::driver::NetworkDriver;

/// The Hera gossip subcommand.
#[derive(Debug, Clone, Args)]
#[non_exhaustive]
pub struct GossipCommand {
/// Port to listen for gossip on.
#[clap(long, short = 'l', default_value = "9099", help = "Port to listen for gossip on")]
pub gossip_port: u16,
/// Interval to send discovery packets.
#[clap(long, short = 'i', default_value = "1", help = "Interval to send discovery packets")]
pub interval: u64,
}

impl GossipCommand {
/// Run the gossip subcommand.
pub async fn run(self, args: &GlobalArgs) -> Result<()> {
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;
tracing::info!("Gossip configured with signer: {:?}", signer);

let socket = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), self.gossip_port);
tracing::info!("Starting gossip driver on {:?}", socket);

let mut driver = NetworkDriver::builder()
.with_chain_id(args.l2_chain_id)
.with_unsafe_block_signer(signer)
.with_gossip_addr(socket)
.with_interval(std::time::Duration::from_secs(self.interval))
.build()?;
let recv =
driver.take_unsafe_block_recv().ok_or(eyre::eyre!("No unsafe block receiver"))?;
driver.start()?;
tracing::info!("Gossip driver started, receiving blocks.");
loop {
match recv.recv() {
Ok(block) => {
tracing::info!("Received unsafe block: {:?}", block);
}
Err(e) => {
tracing::warn!("Failed to receive unsafe block: {:?}", e);
}
}
}
}
}
Loading

0 comments on commit 011e6f3

Please sign in to comment.