diff --git a/p2p/src/peers.rs b/p2p/src/peers.rs index b4b931b57..7953428cd 100644 --- a/p2p/src/peers.rs +++ b/p2p/src/peers.rs @@ -37,16 +37,18 @@ pub struct Peers { store: PeerStore, peers: RwLock>>>, dandelion_relay: RwLock>>>, + config: P2PConfig, } unsafe impl Send for Peers {} unsafe impl Sync for Peers {} impl Peers { - pub fn new(store: PeerStore, adapter: Arc, _config: P2PConfig) -> Peers { + pub fn new(store: PeerStore, adapter: Arc, config: P2PConfig) -> Peers { Peers { adapter, store, + config, peers: RwLock::new(HashMap::new()), dandelion_relay: RwLock::new(HashMap::new()), } @@ -500,6 +502,10 @@ impl Peers { peer.stop(); } } + + pub fn enough_peers(&self) -> bool { + self.connected_peers().len() >= self.config.peer_min_preferred_count() as usize + } } impl ChainAdapter for Peers { diff --git a/servers/src/grin/sync.rs b/servers/src/grin/sync.rs index 971a2e6da..68e23c499 100644 --- a/servers/src/grin/sync.rs +++ b/servers/src/grin/sync.rs @@ -80,9 +80,24 @@ pub fn run_sync( // short period of time for tests to do the right thing. let wait_secs = if skip_sync_wait { 3 } else { 30 }; + let head = chain.head().unwrap(); + awaiting_peers.store(true, Ordering::Relaxed); let mut n = 0; - while peers.more_work_peers().len() < 4 && n < wait_secs { + const MIN_PEERS: usize = 3; + loop { + let wp = peers.more_work_peers(); + // exit loop when: + // * we have more than MIN_PEERS more_work peers + // * we are synced already, e.g. grin was quickly restarted + // * timeout + if wp.len() > MIN_PEERS + || (wp.len() == 0 + && peers.enough_peers() + && head.total_difficulty > Difficulty::zero()) || n > wait_secs + { + break; + } thread::sleep(time::Duration::from_secs(1)); n += 1; }