diff --git a/parity/cli.rs b/parity/cli.rs index 650c19f94..d3627fda2 100644 --- a/parity/cli.rs +++ b/parity/cli.rs @@ -79,7 +79,8 @@ Networking Options: --no-network Disable p2p networking. --port PORT Override the port on which the node should listen [default: 30303]. - --peers NUM Try to maintain that many peers [default: 25]. + --min-peers NUM Try to maintain at least NUM peers [default: 25]. + --max-peers NUM Allow up to that many peers [default: 50]. --nat METHOD Specify method to use for determining public address. Must be one of: any, none, upnp, extip: [default: any]. @@ -238,7 +239,7 @@ Legacy Options: Overrides the --keys-path option. --datadir PATH Equivalent to --db-path PATH. --networkid INDEX Equivalent to --network-id INDEX. - --maxpeers COUNT Equivalent to --peers COUNT. + --peers NUM Equivalent to --min-peers NUM. --nodekey KEY Equivalent to --node-key KEY. --nodiscover Equivalent to --no-discovery. -j --jsonrpc Does nothing; JSON-RPC is on by default now. @@ -302,7 +303,8 @@ pub struct Args { pub flag_pruning: String, pub flag_tracing: String, pub flag_port: u16, - pub flag_peers: usize, + pub flag_min_peers: u16, + pub flag_max_peers: u16, pub flag_no_discovery: bool, pub flag_nat: String, pub flag_node_key: Option, @@ -364,7 +366,7 @@ pub struct Args { pub flag_geth: bool, pub flag_nodekey: Option, pub flag_nodiscover: bool, - pub flag_maxpeers: Option, + pub flag_peers: Option, pub flag_datadir: Option, pub flag_extradata: Option, pub flag_etherbase: Option, diff --git a/parity/configuration.rs b/parity/configuration.rs index d366da2a6..81b3cb6c6 100644 --- a/parity/configuration.rs +++ b/parity/configuration.rs @@ -18,6 +18,7 @@ use std::time::Duration; use std::io::Read; use std::net::SocketAddr; use std::path::PathBuf; +use std::cmp::max; use cli::{USAGE, Args}; use docopt::{Docopt, Error as DocoptError}; use util::{Hashable, NetworkConfiguration, U256, Uint, is_valid_node_url, Bytes, version_data, Secret, Address}; @@ -251,7 +252,12 @@ impl Configuration { } fn max_peers(&self) -> u32 { - self.args.flag_maxpeers.unwrap_or(self.args.flag_peers) as u32 + let peers = self.args.flag_max_peers as u32; + max(self.min_peers(), peers) + } + + fn min_peers(&self) -> u32 { + self.args.flag_peers.unwrap_or(self.args.flag_min_peers) as u32 } fn work_notify(&self) -> Vec { @@ -386,7 +392,8 @@ impl Configuration { ret.public_address = public; ret.use_secret = self.args.flag_node_key.as_ref().map(|s| s.parse::().unwrap_or_else(|_| s.sha3())); ret.discovery_enabled = !self.args.flag_no_discovery && !self.args.flag_nodiscover; - ret.ideal_peers = self.max_peers(); + ret.max_peers = self.max_peers(); + ret.min_peers = self.min_peers(); let mut net_path = PathBuf::from(self.directories().db); net_path.push("network"); ret.config_path = Some(net_path.to_str().unwrap().to_owned()); @@ -453,6 +460,7 @@ impl Configuration { name: self.args.flag_identity.clone(), chain: self.chain(), max_peers: self.max_peers(), + min_peers: self.min_peers(), network_port: self.args.flag_port, rpc_enabled: !self.args.flag_jsonrpc_off && !self.args.flag_no_jsonrpc, rpc_interface: self.args.flag_rpcaddr.clone().unwrap_or(self.args.flag_jsonrpc_interface.clone()), @@ -700,7 +708,8 @@ mod tests { assert_eq!(conf.network_settings(), NetworkSettings { name: "testname".to_owned(), chain: "morden".to_owned(), - max_peers: 25, + max_peers: 50, + min_peers: 25, network_port: 30303, rpc_enabled: true, rpc_interface: "local".to_owned(), diff --git a/parity/helpers.rs b/parity/helpers.rs index b7b56df32..8e032f13c 100644 --- a/parity/helpers.rs +++ b/parity/helpers.rs @@ -178,7 +178,8 @@ pub fn default_network_config() -> ::util::NetworkConfiguration { discovery_enabled: true, boot_nodes: Vec::new(), use_secret: None, - ideal_peers: 25, + max_peers: 50, + min_peers: 25, reserved_nodes: Vec::new(), non_reserved_mode: NonReservedPeerMode::Accept, } diff --git a/parity/informant.rs b/parity/informant.rs index 429c8e28e..fed1c46d1 100644 --- a/parity/informant.rs +++ b/parity/informant.rs @@ -132,7 +132,7 @@ impl Informant { }, paint(Cyan.bold(), format!("{:2}", sync_info.num_active_peers)), paint(Cyan.bold(), format!("{:2}", sync_info.num_peers)), - paint(Cyan.bold(), format!("{:2}", net_config.ideal_peers)) + paint(Cyan.bold(), format!("{:2}", if sync_info.num_peers as u32 > net_config.min_peers { net_config.max_peers} else { net_config.min_peers} )) ), _ => String::new(), }, diff --git a/rpc/src/v1/tests/mocked/ethcore.rs b/rpc/src/v1/tests/mocked/ethcore.rs index 5b88e8756..73875d131 100644 --- a/rpc/src/v1/tests/mocked/ethcore.rs +++ b/rpc/src/v1/tests/mocked/ethcore.rs @@ -39,6 +39,7 @@ fn settings() -> Arc { Arc::new(NetworkSettings { name: "mynode".to_owned(), chain: "testchain".to_owned(), + min_peers: 25, max_peers: 25, network_port: 30303, rpc_enabled: true, diff --git a/sync/src/api.rs b/sync/src/api.rs index 1d41b97aa..5c0e028e3 100644 --- a/sync/src/api.rs +++ b/sync/src/api.rs @@ -232,8 +232,10 @@ pub struct NetworkConfiguration { pub boot_nodes: Vec, /// Use provided node key instead of default pub use_secret: Option, - /// Number of connected peers to maintain - pub ideal_peers: u32, + /// Max number of connected peers to maintain + pub max_peers: u32, + /// Min number of connected peers to maintain + pub min_peers: u32, /// List of reserved node addresses. pub reserved_nodes: Vec, /// The non-reserved peer mode. @@ -253,7 +255,8 @@ impl NetworkConfiguration { discovery_enabled: self.discovery_enabled, boot_nodes: self.boot_nodes, use_secret: self.use_secret, - ideal_peers: self.ideal_peers, + max_peers: self.max_peers, + min_peers: self.min_peers, reserved_nodes: self.reserved_nodes, non_reserved_mode: if self.allow_non_reserved { NonReservedPeerMode::Accept } else { NonReservedPeerMode::Deny }, }) @@ -271,7 +274,8 @@ impl From for NetworkConfiguration { discovery_enabled: other.discovery_enabled, boot_nodes: other.boot_nodes, use_secret: other.use_secret, - ideal_peers: other.ideal_peers, + max_peers: other.max_peers, + min_peers: other.min_peers, reserved_nodes: other.reserved_nodes, allow_non_reserved: match other.non_reserved_mode { NonReservedPeerMode::Accept => true, _ => false } , } diff --git a/util/src/network/host.rs b/util/src/network/host.rs index bcad97cfe..7b1baf97a 100644 --- a/util/src/network/host.rs +++ b/util/src/network/host.rs @@ -70,8 +70,10 @@ pub struct NetworkConfiguration { pub boot_nodes: Vec, /// Use provided node key instead of default pub use_secret: Option, - /// Number of connected peers to maintain - pub ideal_peers: u32, + /// Minimum number of connected peers to maintain + pub min_peers: u32, + /// Maximum allowd number of peers + pub max_peers: u32, /// List of reserved node addresses. pub reserved_nodes: Vec, /// The non-reserved peer mode. @@ -96,7 +98,8 @@ impl NetworkConfiguration { discovery_enabled: true, boot_nodes: Vec::new(), use_secret: None, - ideal_peers: 25, + min_peers: 25, + max_peers: 50, reserved_nodes: Vec::new(), non_reserved_mode: NonReservedPeerMode::Accept, } @@ -597,19 +600,19 @@ impl Host { } fn connect_peers(&self, io: &IoContext) { - let (ideal_peers, mut pin) = { + let (min_peers, mut pin) = { let info = self.info.read(); if info.capabilities.is_empty() { return; } let config = &info.config; - (config.ideal_peers, config.non_reserved_mode == NonReservedPeerMode::Deny) + (config.min_peers, config.non_reserved_mode == NonReservedPeerMode::Deny) }; let session_count = self.session_count(); let reserved_nodes = self.reserved_nodes.read(); - if session_count >= ideal_peers as usize + reserved_nodes.len() { + if session_count >= min_peers as usize + reserved_nodes.len() { // check if all pinned nodes are connected. if reserved_nodes.iter().all(|n| self.have_session(n) && self.connecting_to(n)) { return; @@ -767,12 +770,12 @@ impl Host { self.num_sessions.fetch_add(1, AtomicOrdering::SeqCst); if !s.info.originated { let session_count = self.session_count(); - let (ideal_peers, reserved_only) = { + let (max_peers, reserved_only) = { let info = self.info.read(); - (info.config.ideal_peers, info.config.non_reserved_mode == NonReservedPeerMode::Deny) + (info.config.max_peers, info.config.non_reserved_mode == NonReservedPeerMode::Deny) }; - if session_count >= ideal_peers as usize || reserved_only { + if session_count >= max_peers as usize || reserved_only { // only proceed if the connecting peer is reserved. if !self.reserved_nodes.read().contains(s.id().unwrap()) { s.disconnect(io, DisconnectReason::TooManyPeers); diff --git a/util/src/network_settings.rs b/util/src/network_settings.rs index 7f0b18f22..9e590c5e7 100644 --- a/util/src/network_settings.rs +++ b/util/src/network_settings.rs @@ -22,7 +22,9 @@ pub struct NetworkSettings { pub name: String, /// Name of the chain we are connected to pub chain: String, - /// Ideal number of peers + /// Min number of peers + pub min_peers: u32, + /// Max number of peers pub max_peers: u32, /// Networking port pub network_port: u16, @@ -39,7 +41,8 @@ impl Default for NetworkSettings { NetworkSettings { name: "".into(), chain: "homestead".into(), - max_peers: 25, + min_peers: 25, + max_peers: 50, network_port: 30303, rpc_enabled: true, rpc_interface: "local".into(),