Files
reth/crates/net/network/src/config.rs
2022-12-11 02:05:07 -08:00

263 lines
8.4 KiB
Rust

//! Network config support
use crate::{
import::{BlockImport, ProofOfStakeBlockImport},
peers::PeersConfig,
session::SessionsConfig,
};
use reth_discv4::{Discv4Config, Discv4ConfigBuilder, NodeRecord, DEFAULT_DISCOVERY_PORT};
use reth_primitives::{Chain, ForkId, H256};
use reth_tasks::TaskExecutor;
use secp256k1::SecretKey;
use std::{
net::{Ipv4Addr, SocketAddr, SocketAddrV4},
sync::Arc,
};
/// reexports for convenience
#[doc(hidden)]
mod __reexport {
pub use reth_discv4::bootnodes::*;
pub use secp256k1::SecretKey;
}
pub use __reexport::*;
/// Convenience function to create a new random [`SecretKey`]
pub fn rng_secret_key() -> SecretKey {
SecretKey::new(&mut rand::thread_rng())
}
/// All network related initialization settings.
pub struct NetworkConfig<C> {
/// The client type that can interact with the chain.
pub client: Arc<C>,
/// The node's secret key, from which the node's identity is derived.
pub secret_key: SecretKey,
/// All boot nodes to start network discovery with.
pub boot_nodes: Vec<NodeRecord>,
/// How to set up discovery.
pub discovery_v4_config: Discv4Config,
/// Address to use for discovery
pub discovery_addr: SocketAddr,
/// Address to listen for incoming connections
pub listener_addr: SocketAddr,
/// How to instantiate peer manager.
pub peers_config: PeersConfig,
/// How to configure the [SessionManager](crate::session::SessionManager).
pub sessions_config: SessionsConfig,
/// A fork identifier as defined by EIP-2124.
/// Serves as the chain compatibility identifier.
pub fork_id: Option<ForkId>,
/// The id of the network
pub chain: Chain,
/// Genesis hash of the network
pub genesis_hash: H256,
/// The block importer type.
pub block_import: Box<dyn BlockImport>,
/// The default mode of the network.
pub network_mode: NetworkMode,
/// The executor to use for spawning tasks.
pub executor: Option<TaskExecutor>,
}
// === impl NetworkConfig ===
impl<C> NetworkConfig<C> {
/// Create a new instance with all mandatory fields set, rest is field with defaults.
pub fn new(client: Arc<C>, secret_key: SecretKey) -> Self {
Self::builder(client, secret_key).build()
}
/// Convenience method for creating the corresponding builder type
pub fn builder(client: Arc<C>, secret_key: SecretKey) -> NetworkConfigBuilder<C> {
NetworkConfigBuilder::new(client, secret_key)
}
/// Sets the config to use for the discovery v4 protocol.
pub fn set_discovery_v4(mut self, discovery_config: Discv4Config) -> Self {
self.discovery_v4_config = discovery_config;
self
}
/// Sets the address for the incoming connection listener.
pub fn set_listener_addr(mut self, listener_addr: SocketAddr) -> Self {
self.listener_addr = listener_addr;
self
}
}
/// Builder for [`NetworkConfig`](struct.NetworkConfig.html).
#[allow(missing_docs)]
pub struct NetworkConfigBuilder<C> {
/// The client type that can interact with the chain.
client: Arc<C>,
/// The node's secret key, from which the node's identity is derived.
secret_key: SecretKey,
/// How to set up discovery.
discovery_v4_builder: Discv4ConfigBuilder,
/// All boot nodes to start network discovery with.
boot_nodes: Vec<NodeRecord>,
/// Address to use for discovery
discovery_addr: Option<SocketAddr>,
/// Listener for incoming connections
listener_addr: Option<SocketAddr>,
/// How to instantiate peer manager.
peers_config: Option<PeersConfig>,
/// How to configure the sessions manager
sessions_config: Option<SessionsConfig>,
/// A fork identifier as defined by EIP-2124.
/// Serves as the chain compatibility identifier.
fork_id: Option<ForkId>,
/// The network's chain id
chain: Chain,
/// Network genesis hash
genesis_hash: H256,
/// The block importer type.
block_import: Box<dyn BlockImport>,
/// The default mode of the network.
network_mode: NetworkMode,
/// The executor to use for spawning tasks.
executor: Option<TaskExecutor>,
}
// === impl NetworkConfigBuilder ===
#[allow(missing_docs)]
impl<C> NetworkConfigBuilder<C> {
pub fn new(client: Arc<C>, secret_key: SecretKey) -> Self {
Self {
client,
secret_key,
discovery_v4_builder: Default::default(),
boot_nodes: vec![],
discovery_addr: None,
listener_addr: None,
peers_config: None,
sessions_config: None,
fork_id: None,
chain: Chain::Named(reth_primitives::rpc::Chain::Mainnet),
genesis_hash: Default::default(),
block_import: Box::<ProofOfStakeBlockImport>::default(),
network_mode: Default::default(),
executor: None,
}
}
/// set a custom peer config for how peers are handled
pub fn peer_config(mut self, config: PeersConfig) -> Self {
self.peers_config = Some(config);
self
}
/// Sets the executor to use for spawning tasks.
pub fn executor(mut self, executor: TaskExecutor) -> Self {
self.executor = Some(executor);
self
}
/// Sets a custom config for how sessions are handled.
pub fn sessions_config(mut self, config: SessionsConfig) -> Self {
self.sessions_config = Some(config);
self
}
/// Sets the genesis hash for the network.
pub fn genesis_hash(mut self, genesis_hash: H256) -> Self {
self.genesis_hash = genesis_hash;
self
}
/// Sets the [`BlockImport`] type to configure.
pub fn block_import<T: BlockImport + 'static>(mut self, block_import: T) -> Self {
self.block_import = Box::new(block_import);
self
}
/// Sets the socket address the network will listen on
pub fn listener_addr(mut self, listener_addr: SocketAddr) -> Self {
self.listener_addr = Some(listener_addr);
self
}
/// Sets the socket address the discovery network will listen on
pub fn discovery_addr(mut self, discovery_addr: SocketAddr) -> Self {
self.discovery_addr = Some(discovery_addr);
self
}
/// Sets the discv4 config to use.
pub fn discovery(mut self, builder: Discv4ConfigBuilder) -> Self {
self.discovery_v4_builder = builder;
self
}
/// Sets the discv4 config to use.
pub fn boot_nodes(mut self, nodes: impl IntoIterator<Item = NodeRecord>) -> Self {
self.boot_nodes = nodes.into_iter().collect();
self
}
/// Consumes the type and creates the actual [`NetworkConfig`]
pub fn build(self) -> NetworkConfig<C> {
let Self {
client,
secret_key,
discovery_v4_builder,
boot_nodes,
discovery_addr,
listener_addr,
peers_config,
sessions_config,
fork_id,
chain,
genesis_hash,
block_import,
network_mode,
executor,
} = self;
NetworkConfig {
client,
secret_key,
boot_nodes,
discovery_v4_config: discovery_v4_builder.build(),
discovery_addr: discovery_addr.unwrap_or_else(|| {
SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::UNSPECIFIED, DEFAULT_DISCOVERY_PORT))
}),
listener_addr: listener_addr.unwrap_or_else(|| {
SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::UNSPECIFIED, DEFAULT_DISCOVERY_PORT))
}),
peers_config: peers_config.unwrap_or_default(),
sessions_config: sessions_config.unwrap_or_default(),
fork_id,
chain,
genesis_hash,
block_import,
network_mode,
executor,
}
}
}
/// Describes the mode of the network wrt. POS or POW.
///
/// This affects block propagation in the `eth` sub-protocol [EIP-3675](https://eips.ethereum.org/EIPS/eip-3675#devp2p)
///
/// In POS `NewBlockHashes` and `NewBlock` messages become invalid.
#[derive(Debug, Clone, Copy, Eq, PartialEq, Default)]
pub enum NetworkMode {
/// Network is in proof-of-work mode.
Work,
/// Network is in proof-of-stake mode
#[default]
Stake,
}
// === impl NetworkMode ===
impl NetworkMode {
/// Returns true if network has entered proof-of-stake
pub fn is_stake(&self) -> bool {
matches!(self, NetworkMode::Stake)
}
}