diff --git a/grin.toml b/grin.toml index 4df0dd958..9787284ed 100644 --- a/grin.toml +++ b/grin.toml @@ -78,6 +78,19 @@ port = 13414 #will *never* connect to peers in deny list #peers_deny = ["192.168.0.3:13414", "192.168.0.4:13414"] +#dandelion relay time +#dandelion_relay_time = 600 + +#how long a banned peer should stay banned +#ban_window = 10800 + +#maximum number of peers +#peer_max_count = 25 + +#preferred minimum number of peers (we'll actively keep trying to add peers +#until we get to at least this number +#peer_min_preferred_count = 8 + ######################################### ### WALLET CONFIGURATION ### ######################################### diff --git a/grin/src/seed.rs b/grin/src/seed.rs index bf4f4b0fd..f0d5d347b 100644 --- a/grin/src/seed.rs +++ b/grin/src/seed.rs @@ -30,10 +30,6 @@ use hyper; use p2p; use util::LOGGER; -const DANDELION_RELAY_TIME: i64 = 600; -const BAN_WINDOW: i64 = 10800; -const PEER_MAX_COUNT: u32 = 25; -const PEER_PREFERRED_COUNT: u32 = 8; const SEEDS_URL: &'static str = "http://grin-tech.org/seeds.txt"; pub fn connect_and_monitor( @@ -63,9 +59,14 @@ pub fn connect_and_monitor( listen_for_addrs(peers.clone(), p2p_server.clone(), capabilities, &rx); // monitor additional peers if we need to add more - monitor_peers(peers.clone(), capabilities, tx.clone()); + monitor_peers( + peers.clone(), + p2p_server.config.clone(), + capabilities, + tx.clone(), + ); - update_dandelion_relay(peers.clone()); + update_dandelion_relay(peers.clone(), p2p_server.config.clone()); prev = current_time; } @@ -81,6 +82,7 @@ pub fn connect_and_monitor( fn monitor_peers( peers: Arc, + config: p2p::P2PConfig, capabilities: p2p::Capabilities, tx: mpsc::Sender, ) { @@ -95,7 +97,7 @@ fn monitor_peers( p2p::State::Banned => { let interval = now_utc().to_timespec().sec - x.last_banned; // Unban peer - if interval >= BAN_WINDOW { + if interval >= config.ban_window() { peers.unban_peer(&x.addr); debug!( LOGGER, @@ -123,10 +125,10 @@ fn monitor_peers( ); // maintenance step first, clean up p2p server peers - peers.clean_peers(PEER_MAX_COUNT as usize); + peers.clean_peers(config.peer_max_count() as usize); // not enough peers, getting more from db - if peers.peer_count() >= PEER_PREFERRED_COUNT { + if peers.peer_count() >= config.peer_min_preferred_count() { return; } @@ -150,7 +152,7 @@ fn monitor_peers( } } -fn update_dandelion_relay(peers: Arc) { +fn update_dandelion_relay(peers: Arc, config: p2p::P2PConfig) { // Dandelion Relay Updater let dandelion_relay = peers.get_dandelion_relay(); if dandelion_relay.is_empty() { @@ -159,7 +161,7 @@ fn update_dandelion_relay(peers: Arc) { } else { for last_added in dandelion_relay.keys() { let dandelion_interval = now_utc().to_timespec().sec - last_added; - if dandelion_interval >= DANDELION_RELAY_TIME { + if dandelion_interval >= config.dandelion_relay_time() { debug!(LOGGER, "monitor_peers: updating expired dandelion relay"); peers.update_dandelion_relay(); } @@ -205,7 +207,7 @@ fn listen_for_addrs( ) { let pc = peers.peer_count(); for addr in rx.try_iter() { - if pc < PEER_MAX_COUNT { + if pc < p2p.config.peer_max_count() { let peers_c = peers.clone(); let p2p_c = p2p.clone(); let _ = thread::Builder::new() diff --git a/p2p/src/serv.rs b/p2p/src/serv.rs index 6e04b5c9f..263b5bdf2 100644 --- a/p2p/src/serv.rs +++ b/p2p/src/serv.rs @@ -33,7 +33,7 @@ use util::LOGGER; /// P2P server implementation, handling bootstrapping to find and connect to /// peers, receiving connections from other peers and keep track of all of them. pub struct Server { - config: P2PConfig, + pub config: P2PConfig, capabilities: Capabilities, handshake: Arc, pub peers: Arc, diff --git a/p2p/src/types.rs b/p2p/src/types.rs index e1b38c5e0..b34bc492b 100644 --- a/p2p/src/types.rs +++ b/p2p/src/types.rs @@ -34,6 +34,18 @@ pub const MAX_BLOCK_BODIES: u32 = 16; /// Maximum number of peer addresses a peer should ever send pub const MAX_PEER_ADDRS: u32 = 256; +/// Dandelion relay time +const DANDELION_RELAY_TIME: i64 = 600; + +/// How long a banned peer should be banned for +const BAN_WINDOW: i64 = 10800; + +/// The max peer count +const PEER_MAX_COUNT: u32 = 25; + +/// min preferred peer count +const PEER_MIN_PREFERRED_COUNT: u32 = 8; + #[derive(Debug)] pub enum Error { Serialization(ser::Error), @@ -90,6 +102,14 @@ pub struct P2PConfig { pub peers_allow: Option>, pub peers_deny: Option>, + + pub dandelion_relay_time: Option, + + pub ban_window: Option, + + pub peer_max_count: Option, + + pub peer_min_preferred_count: Option, } /// Default address for peer-to-peer connections. @@ -101,6 +121,46 @@ impl Default for P2PConfig { port: 13414, peers_allow: None, peers_deny: None, + dandelion_relay_time: Some(DANDELION_RELAY_TIME), + ban_window: Some(BAN_WINDOW), + peer_max_count: Some(PEER_MAX_COUNT), + peer_min_preferred_count: Some(PEER_MIN_PREFERRED_COUNT), + } + } +} + +/// Note certain fields are options just so they don't have to be +/// included in grin.toml, but we don't want them to ever return none +impl P2PConfig { + /// return dandelion_relay_time + pub fn dandelion_relay_time(&self) -> i64 { + match self.dandelion_relay_time { + Some(n) => n, + None => DANDELION_RELAY_TIME, + } + } + + /// return ban window + pub fn ban_window(&self) -> i64 { + match self.ban_window { + Some(n) => n, + None => BAN_WINDOW, + } + } + + /// return peer_max_count + pub fn peer_max_count(&self) -> u32 { + match self.peer_max_count { + Some(n) => n, + None => PEER_MAX_COUNT, + } + } + + /// return peer_preferred_count + pub fn peer_min_preferred_count(&self) -> u32 { + match self.peer_min_preferred_count { + Some(n) => n, + None => PEER_MIN_PREFERRED_COUNT, } } } diff --git a/p2p/tests/peer_handshake.rs b/p2p/tests/peer_handshake.rs index 90be2f1c1..770cc8bae 100644 --- a/p2p/tests/peer_handshake.rs +++ b/p2p/tests/peer_handshake.rs @@ -45,6 +45,7 @@ fn peer_handshake() { port: open_port(), peers_allow: None, peers_deny: None, + ..p2p::P2PConfig::default() }; let net_adapter = Arc::new(p2p::DummyAdapter {}); let server = Arc::new(