From 28258e6b6593e502f07c356f87b79db090dc5b6d Mon Sep 17 00:00:00 2001 From: refcell Date: Thu, 29 Aug 2024 17:12:18 -0400 Subject: [PATCH] feat(hera): Run the Network Driver (#44) ### Description Runs the `NetworkDriver` in the `hera` binary. Think the op stack enr data isn't being deserialized correctly. [Ether's rlp decoding](https://docs.rs/ethers/latest/ethers/core/utils/rlp/fn.encode.html) uses an `RlpStream` which I'm not sure is the same way `alloy_rlp` decodes. --------- Co-authored-by: nicolas <48695862+merklefruit@users.noreply.github.com> --- Cargo.lock | 10 ++---- Cargo.toml | 6 +++- bin/hera/Cargo.toml | 16 +++------- bin/hera/src/main.rs | 45 +++++++++++++++++++++++++-- bin/op-rs/Cargo.toml | 2 +- crates/net/README.md | 2 +- crates/net/src/builder.rs | 23 ++++++++++++-- crates/net/src/discovery/bootnodes.rs | 13 ++++++++ crates/net/src/driver.rs | 14 +++++++-- crates/net/src/gossip/config.rs | 1 + 10 files changed, 104 insertions(+), 28 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c1bec34..039808d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3000,18 +3000,14 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" name = "hera" version = "0.1.0" dependencies = [ - "anyhow", + "alloy", "clap", "eyre", - "kona-derive", - "reth", - "reth-exex", - "reth-node-api", - "reth-node-ethereum", + "op-net", "rollup", - "superchain-registry", "tokio", "tracing", + "tracing-subscriber", "url", ] diff --git a/Cargo.toml b/Cargo.toml index 31ca407..e88ce6c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -118,6 +118,9 @@ incremental = false [workspace.dependencies] # Workspace op-net = { path = "crates/net" } +kona-providers = { path = "crates/kona-providers" } +rollup = { path = "crates/rollup" } +ser = { path = "crates/ser" } # Optimism superchain-registry = { version = "0.2.6", default-features = false } @@ -165,8 +168,9 @@ libp2p = { version = "0.54.0", features = ["macros", "tokio", "tcp", "noise", "g # Misc tracing = "0.1.0" +tracing-subscriber = "0.3.18" eyre = "0.6.12" -clap = "4" +clap = { version = "4.5.4", features = ["derive", "env"] } lazy_static = "1.5.0" futures = "0.3.30" async-trait = "0.1.81" diff --git a/bin/hera/Cargo.toml b/bin/hera/Cargo.toml index 468d7c4..eb25777 100644 --- a/bin/hera/Cargo.toml +++ b/bin/hera/Cargo.toml @@ -16,20 +16,12 @@ rollup = { path = "../../crates/rollup" } # Workspace eyre.workspace = true +alloy.workspace = true tokio = { workspace = true, features = ["rt-multi-thread", "macros"] } tracing.workspace = true +tracing-subscriber.workspace = true clap.workspace = true url.workspace = true -# Reth Dependencies -reth.workspace = true -reth-exex.workspace = true -reth-node-api.workspace = true -reth-node-ethereum.workspace = true - -# OP Stack Dependencies -superchain-registry = { workspace = true, default-features = false } -kona-derive = { workspace = true, features = ["online", "serde"] } - -# Needed for compatibility with Kona's ChainProvider trait -anyhow = { version = "1.0.86", default-features = false } +# Workspace Crates +op-net.workspace = true diff --git a/bin/hera/src/main.rs b/bin/hera/src/main.rs index ca78bb2..1d7c1eb 100644 --- a/bin/hera/src/main.rs +++ b/bin/hera/src/main.rs @@ -4,12 +4,53 @@ #![doc(issue_tracker_base_url = "https://github.com/paradigmxyz/op-rs/issues/")] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] +use alloy::primitives::address; +use clap::Parser; use eyre::Result; +use op_net::driver::NetworkDriver; +use std::net::{IpAddr, Ipv4Addr, SocketAddr}; -fn main() -> Result<()> { +/// The default L2 chain ID to use. This corresponds to OP Mainnet. +pub const DEFAULT_L2_CHAIN_ID: u64 = 10; + +/// 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, +} + +#[tokio::main] +async fn main() -> Result<()> { + let args = HeraArgs::parse(); rollup::init_telemetry_stack(8090)?; tracing::info!("Hera OP Stack Rollup node"); - Ok(()) + let signer = address!("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"); + 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); + } + } + } } diff --git a/bin/op-rs/Cargo.toml b/bin/op-rs/Cargo.toml index 9938636..b0a9b75 100644 --- a/bin/op-rs/Cargo.toml +++ b/bin/op-rs/Cargo.toml @@ -15,8 +15,8 @@ rollup = { path = "../../crates/rollup" } # Workspace eyre.workspace = true -tracing.workspace = true clap.workspace = true +tracing.workspace = true # Reth Dependencies reth.workspace = true diff --git a/crates/net/README.md b/crates/net/README.md index 206c232..e79b877 100644 --- a/crates/net/README.md +++ b/crates/net/README.md @@ -12,7 +12,7 @@ use op_net::driver::NetworkDriver; // Build the network driver. let signer = address!("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"); let socket = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 9099); -let mut driver = NetworkDriver::builder() +let driver = NetworkDriver::builder() .with_chain_id(10) // op mainnet chain id .with_unsafe_block_signer(signer) .with_gossip_addr(socket) diff --git a/crates/net/src/builder.rs b/crates/net/src/builder.rs index d049d81..9591d76 100644 --- a/crates/net/src/builder.rs +++ b/crates/net/src/builder.rs @@ -3,7 +3,10 @@ use alloy::primitives::Address; use discv5::ListenConfig; use eyre::Result; -use std::net::{IpAddr, SocketAddr}; +use std::{ + net::{IpAddr, SocketAddr}, + time::Duration, +}; use tokio::sync::watch::channel; use libp2p::{ @@ -39,6 +42,8 @@ pub struct NetworkDriverBuilder { pub noise_config: Option, /// The [YamuxConfig] for the swarm. pub yamux_config: Option, + /// The idle connection timeout. + pub timeout: Option, } impl NetworkDriverBuilder { @@ -95,6 +100,12 @@ impl NetworkDriverBuilder { self } + /// Set the swarm's idle connection timeout. + pub fn with_idle_connection_timeout(&mut self, timeout: Duration) -> &mut Self { + self.timeout = Some(timeout); + self + } + /// Specifies the [GossipConfig] for the `gossipsub` configuration. /// /// If not set, the [NetworkDriverBuilder] will use the default gossipsub @@ -192,6 +203,7 @@ impl NetworkDriverBuilder { let behaviour = Behaviour::new(config, &[Box::new(handler.clone())])?; // Build the swarm. + let timeout = self.timeout.take().unwrap_or(Duration::from_secs(60)); let noise_config = self.noise_config.take(); let keypair = self.keypair.take().unwrap_or(Keypair::generate_secp256k1()); let swarm = SwarmBuilder::with_existing_identity(keypair) @@ -205,6 +217,7 @@ impl NetworkDriverBuilder { || self.yamux_config.take().unwrap_or_default(), )? .with_behaviour(|_| behaviour)? + .with_swarm_config(|c| c.with_idle_connection_timeout(timeout)) .build(); let gossip_addr = @@ -227,7 +240,13 @@ impl NetworkDriverBuilder { discovery_builder } .build()?; - Ok(NetworkDriver { unsafe_block_recv, unsafe_block_signer_sender, gossip, discovery }) + + Ok(NetworkDriver { + discovery, + gossip, + unsafe_block_recv: Some(unsafe_block_recv), + unsafe_block_signer_sender: Some(unsafe_block_signer_sender), + }) } } diff --git a/crates/net/src/discovery/bootnodes.rs b/crates/net/src/discovery/bootnodes.rs index 9e20aaa..6c29020 100644 --- a/crates/net/src/discovery/bootnodes.rs +++ b/crates/net/src/discovery/bootnodes.rs @@ -18,5 +18,18 @@ lazy_static! { Enr::from_str("enr:-J24QDXyyxvQYsd0yfsN0cRr1lZ1N11zGTplMNlW4xNEc7LkPXh0NAJ9iSOVdRO95GPYAIc6xmyoCCG6_0JxdL3a0zaGAYiOoAjFgmlkgnY0gmlwhAPckbGHb3BzdGFja4OFQgCJc2VjcDI1NmsxoQJwoS7tzwxqXSyFL7g0JM-KWVbgvjfB8JA__T7yY_cYboN0Y3CCJAaDdWRwgiQG").unwrap(), Enr::from_str("enr:-J24QHmGyBwUZXIcsGYMaUqGGSl4CFdx9Tozu-vQCn5bHIQbR7On7dZbU61vYvfrJr30t0iahSqhc64J46MnUO2JvQaGAYiOoCKKgmlkgnY0gmlwhAPnCzSHb3BzdGFja4OFQgCJc2VjcDI1NmsxoQINc4fSijfbNIiGhcgvwjsjxVFJHUstK9L1T8OTKUjgloN0Y3CCJAaDdWRwgiQG").unwrap(), Enr::from_str("enr:-J24QG3ypT4xSu0gjb5PABCmVxZqBjVw9ca7pvsI8jl4KATYAnxBmfkaIuEqy9sKvDHKuNCsy57WwK9wTt2aQgcaDDyGAYiOoGAXgmlkgnY0gmlwhDbGmZaHb3BzdGFja4OFQgCJc2VjcDI1NmsxoQIeAK_--tcLEiu7HvoUlbV52MspE0uCocsx1f_rYvRenIN0Y3CCJAaDdWRwgiQG").unwrap(), + + // Conduit Bootnode + // discv5::enr::NodeId::from("enode://9d7a3efefe442351217e73b3a593bcb8efffb55b4807699972145324eab5e6b382152f8d24f6301baebbfb5ecd4127bd3faab2842c04cd432bdf50ba092f6645@34.65.109.126:30305"), ].to_vec(); } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_bootnodes() { + assert_eq!(BOOTNODES.len(), 8); + } +} diff --git a/crates/net/src/driver.rs b/crates/net/src/driver.rs index c14e1db..191312f 100644 --- a/crates/net/src/driver.rs +++ b/crates/net/src/driver.rs @@ -17,9 +17,9 @@ use tokio::{select, sync::watch}; /// - Peer discovery with `discv5`. pub struct NetworkDriver { /// Channel to receive unsafe blocks. - pub unsafe_block_recv: Receiver, + pub(crate) unsafe_block_recv: Option>, /// Channel to send unsafe signer updates. - pub unsafe_block_signer_sender: watch::Sender
, + pub(crate) unsafe_block_signer_sender: Option>, /// The swarm instance. pub gossip: GossipDriver, /// The discovery service driver. @@ -32,6 +32,16 @@ impl NetworkDriver { NetworkDriverBuilder::new() } + /// Take the unsafe block receiver. + pub fn take_unsafe_block_recv(&mut self) -> Option> { + self.unsafe_block_recv.take() + } + + /// Take the unsafe block signer sender. + pub fn take_unsafe_block_signer_sender(&mut self) -> Option> { + self.unsafe_block_signer_sender.take() + } + /// Starts the Discv5 peer discovery & libp2p services /// and continually listens for new peers and messages to handle pub fn start(mut self) -> Result<()> { diff --git a/crates/net/src/gossip/config.rs b/crates/net/src/gossip/config.rs index 2e8fdb0..01aad8e 100644 --- a/crates/net/src/gossip/config.rs +++ b/crates/net/src/gossip/config.rs @@ -65,6 +65,7 @@ lazy_static! { /// Notable defaults: /// - flood_publish: false (call `.flood_publish(true)` on the [ConfigBuilder] to enable) /// - backoff_slack: 1 +/// - heart beat interval: 1 second /// - peer exchange is disabled /// - maximum byte size for gossip messages: 2048 bytes ///