Skip to content

Commit

Permalink
feat:use listen config in network driver
Browse files Browse the repository at this point in the history
Signed-off-by: Chen Kai <[email protected]>
  • Loading branch information
GrapeBaBa committed Aug 29, 2024
1 parent e7e8b66 commit ceda34a
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 49 deletions.
2 changes: 1 addition & 1 deletion crates/net/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ let socket = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 9099);
let mut driver = NetworkDriver::builder()
.with_chain_id(10) // op mainnet chain id
.with_unsafe_block_signer(signer)
.with_socket(socket)
.with_gossip_addr(socket)
.build()
.expect("Failed to builder network driver");
Expand Down
110 changes: 68 additions & 42 deletions crates/net/src/builder.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
//! Network Builder Module.
use alloy::primitives::Address;
use discv5::ListenConfig;
use eyre::Result;
use std::net::{IpAddr, SocketAddr};
use discv5::ListenConfig;
use discv5::ListenConfig::{DualStack, Ipv4, Ipv6};
use tokio::sync::watch::channel;

use libp2p::{
Expand All @@ -26,10 +25,10 @@ pub struct NetworkDriverBuilder {
pub chain_id: Option<u64>,
/// The unsafe block signer.
pub unsafe_block_signer: Option<Address>,
/// The socket address that the service is listening on.
pub socket: Option<SocketAddr>,
/// The listen config that the service is listening on.
pub listen_config: Option<ListenConfig>,
/// The socket address that the gossip service is listening on.
pub gossip_addr: Option<SocketAddr>,
/// The listen config that the discovery service is listening on.
pub discovery_addr: Option<ListenConfig>,
/// The [GossipConfig] constructs the config for `gossipsub`.
pub gossip_config: Option<GossipConfig>,
/// The [Keypair] for the node.
Expand Down Expand Up @@ -60,15 +59,15 @@ impl NetworkDriverBuilder {
self
}

/// Specifies the socket address that the service is listening on.
pub fn with_socket(&mut self, socket: SocketAddr) -> &mut Self {
self.socket = Some(socket);
/// Specifies the socket address that the gossip service is listening on.
pub fn with_gossip_addr(&mut self, socket: SocketAddr) -> &mut Self {
self.gossip_addr = Some(socket);
self
}

/// Specifies the listen config that the service is listening on.
pub fn with_listen_config(&mut self, listen_config: ListenConfig) -> &mut Self {
self.listen_config = Some(listen_config);
/// Specifies the listen config that the discovery service is listening on.
pub fn with_discovery_addr(&mut self, listen_config: ListenConfig) -> &mut Self {
self.discovery_addr = Some(listen_config);
self
}

Expand Down Expand Up @@ -119,7 +118,7 @@ impl NetworkDriverBuilder {
/// let mut builder = NetworkDriverBuilder::new()
/// .with_unsafe_block_signer(signer)
/// .with_chain_id(chain_id)
/// .with_socket(socket)
/// .with_gossip_addr(socket)
/// .with_gossip_config(cfg);
/// .build()
/// .unwrap();
Expand All @@ -136,10 +135,11 @@ impl NetworkDriverBuilder {
/// Returns an error if any of the following required fields are not set:
/// - [NetworkDriverBuilder::unsafe_block_signer]
/// - [NetworkDriverBuilder::chain_id]
/// - [NetworkDriverBuilder::gossip_addr]
///
/// Returns an error if neither of the following required fields are set:
/// - [NetworkDriverBuilder::socket]
/// - [NetworkDriverBuilder::listen_config]
/// If explicitly set, the following fields are used for discovery address, otherwise the gossip
/// address is used:
/// - [NetworkDriverBuilder::discovery_addr]
///
/// Set these fields using the respective methods on the [NetworkDriverBuilder]
/// before calling this method.
Expand All @@ -156,7 +156,21 @@ impl NetworkDriverBuilder {
/// let driver = NetworkDriverBuilder::new()
/// .with_unsafe_block_signer(signer)
/// .with_chain_id(chain_id)
/// .with_socket(socket)
/// .with_gossip_addr(socket)
/// .build()
/// .unwrap();
///
/// Or if you want to use a different discovery address:
///
/// let chain_id = 10;
/// let signer = Address::random();
/// let socket = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 9099);
/// let listen_config = ListenConfig::from_ip(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 9999);
/// let driver = NetworkDriverBuilder::new()
/// .with_unsafe_block_signer(signer)
/// .with_chain_id(chain_id)
/// .with_gossip_addr(socket)
/// .with_discovery_addr(listen_config)
/// .build()
/// .unwrap();
/// ```
Expand Down Expand Up @@ -192,33 +206,27 @@ impl NetworkDriverBuilder {
)?
.with_behaviour(|_| behaviour)?
.build();
let listen_config = self.listen_config.take().ok_or_else(|| {
let addr = self.socket.ok_or_else(|| eyre::eyre!("address not set"))?;
Ok(ListenConfig::from_ip(addr.ip(), addr.port()))
})?;

let gossip_addr =
self.gossip_addr.take().ok_or(eyre::eyre!("gossip_addr address not set"))?;
let mut multiaddr = Multiaddr::empty();
match listen_config {
Ipv4 { ip: addr, port } => {
multiaddr.push(Protocol::Ip4(addr));
multiaddr.push(Protocol::Tcp(port));
}
Ipv6 { ip: addr, port } => {
multiaddr.push(Protocol::Ip6(addr));
multiaddr.push(Protocol::Tcp(port));
}
DualStack { ipv4: v4addr, ipv4_port: v4port, ipv6: v6addr, ipv6_port: v6port, .. } => {
multiaddr.push(Protocol::Ip4(v4addr));
multiaddr.push(Protocol::Tcp(v4port));
multiaddr.push(Protocol::Ip6(v6addr));
multiaddr.push(Protocol::Tcp(v6port));
}
match gossip_addr.ip() {
IpAddr::V4(ip) => multiaddr.push(Protocol::Ip4(ip)),
IpAddr::V6(ip) => multiaddr.push(Protocol::Ip6(ip)),
}
let gossip = GossipDriver::new(swarm, multiaddr, handler);
multiaddr.push(Protocol::Tcp(gossip_addr.port()));
let gossip = GossipDriver::new(swarm, multiaddr, handler.clone());

// Build the discovery service
let discovery =
DiscoveryBuilder::new().with_listen_config(listen_config).with_chain_id(chain_id).build()?;
let discovery_builder =
DiscoveryBuilder::new().with_address(gossip_addr).with_chain_id(chain_id);

let discovery = if let Some(discovery_addr) = self.discovery_addr.take() {
discovery_builder.with_listen_config(discovery_addr)
} else {
discovery_builder
}
.build()?;
Ok(NetworkDriver { unsafe_block_recv, unsafe_block_signer_sender, gossip, discovery })
}
}
Expand Down Expand Up @@ -254,7 +262,7 @@ mod tests {
else {
panic!("expected error when building NetworkDriver without socket");
};
assert_eq!(err.to_string(), "socket address not set");
assert_eq!(err.to_string(), "gossip_addr address not set");
}

#[test]
Expand All @@ -266,7 +274,7 @@ mod tests {
let driver = NetworkDriverBuilder::new()
.with_unsafe_block_signer(signer)
.with_chain_id(id)
.with_socket(socket)
.with_gossip_addr(socket)
.with_gossip_config(cfg)
.build()
.unwrap();
Expand Down Expand Up @@ -299,7 +307,7 @@ mod tests {
let driver = NetworkDriverBuilder::new()
.with_unsafe_block_signer(signer)
.with_chain_id(id)
.with_socket(socket)
.with_gossip_addr(socket)
.build()
.unwrap();
let mut multiaddr = Multiaddr::empty();
Expand All @@ -312,6 +320,7 @@ mod tests {
// Driver Assertions
assert_eq!(driver.gossip.addr, multiaddr);
assert_eq!(driver.discovery.chain_id, id);
assert_eq!(driver.discovery.disc.local_enr().tcp4().unwrap(), 9099);

// Block Handler Assertions
assert_eq!(driver.gossip.handler.chain_id, id);
Expand All @@ -322,4 +331,21 @@ mod tests {
let v3 = IdentTopic::new(format!("/optimism/{}/2/blocks", id));
assert_eq!(driver.gossip.handler.blocks_v3_topic.hash(), v3.hash());
}

#[test]
fn test_build_network_driver_with_discovery_addr() {
let id = 10;
let signer = Address::random();
let socket = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 9099);
let discovery_addr = ListenConfig::from_ip(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 9098);
let driver = NetworkDriverBuilder::new()
.with_unsafe_block_signer(signer)
.with_chain_id(id)
.with_gossip_addr(socket)
.with_discovery_addr(discovery_addr)
.build()
.unwrap();

assert_eq!(driver.discovery.disc.local_enr().tcp4().unwrap(), 9098);
}
}
29 changes: 23 additions & 6 deletions crates/net/src/discovery/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use discv5::{
enr::{CombinedKey, Enr},
ConfigBuilder, Discv5, ListenConfig,
};
use eyre::Result;
use eyre::{Report, Result};
use std::net::SocketAddr;

use crate::types::enr::OP_CL_KEY;
Expand Down Expand Up @@ -54,11 +54,28 @@ impl DiscoveryBuilder {
opstack.encode(&mut opstack_data);

let key = CombinedKey::generate_secp256k1();
let enr = Enr::builder().add_value_rlp(OP_CL_KEY, opstack_data.into()).build(&key)?;
let listen_config = self.listen_config.take().unwrap_or_else(|| {
let addr = self.address.expect("address not set");
ListenConfig::from_ip(addr.ip(), addr.port())
});
let mut enr_builder = Enr::builder();
enr_builder.add_value_rlp(OP_CL_KEY, opstack_data.into());
let listen_config = self.listen_config.take().map_or_else(
|| {
let addr = self.address.ok_or(eyre::eyre!("address not set"))?;
Ok::<ListenConfig, Report>(ListenConfig::from(addr))
},
Ok,
)?;
match listen_config {
ListenConfig::Ipv4 { ip, port } => {
enr_builder.ip4(ip).tcp4(port);
}
ListenConfig::Ipv6 { ip, port } => {
enr_builder.ip6(ip).tcp6(port);
}
ListenConfig::DualStack { ipv4, ipv4_port, ipv6, ipv6_port } => {
enr_builder.ip4(ipv4).tcp4(ipv4_port);
enr_builder.ip6(ipv6).tcp6(ipv6_port);
}
}
let enr = enr_builder.build(&key)?;
let config = ConfigBuilder::new(listen_config).build();

let disc = Discv5::new(enr, key, config)
Expand Down

0 comments on commit ceda34a

Please sign in to comment.