diff --git a/servers/src/grin/server.rs b/servers/src/grin/server.rs index 83a06b0fe..c0a24b171 100644 --- a/servers/src/grin/server.rs +++ b/servers/src/grin/server.rs @@ -264,6 +264,14 @@ impl Server { Ok(()) } + /// Ping all peers, mostly useful for tests to have connected peers share + /// their heights + pub fn ping_peers(&self)-> Result<(), Error> { + let head = self.chain.head()?; + self.p2p.peers.check_all(head.total_difficulty, head.height); + Ok(()) + } + /// Number of peers pub fn peer_count(&self) -> u32 { self.p2p.peers.peer_count() @@ -426,4 +434,9 @@ impl Server { self.p2p.stop(); self.stop.store(true, Ordering::Relaxed); } + + /// Stops the test miner without stopping the p2p layer + pub fn stop_test_miner(&self) { + self.stop.store(true, Ordering::Relaxed); + } } diff --git a/servers/src/grin/sync.rs b/servers/src/grin/sync.rs index 101dca5bc..4f5302fdb 100644 --- a/servers/src/grin/sync.rs +++ b/servers/src/grin/sync.rs @@ -439,7 +439,7 @@ fn get_locator_heights(height: u64) -> Vec { // Utility struct to group what information the main sync loop has to track struct SyncInfo { prev_body_sync: (DateTime, u64), - prev_header_sync: (DateTime, u64), + prev_header_sync: (DateTime, u64, u64), prev_fast_sync: Option>, highest_height: u64, } @@ -449,7 +449,7 @@ impl SyncInfo { let now = Utc::now(); SyncInfo { prev_body_sync: (now.clone(), 0), - prev_header_sync: (now.clone(), 0), + prev_header_sync: (now.clone(), 0, 0), prev_fast_sync: None, highest_height: 0, } @@ -457,15 +457,23 @@ impl SyncInfo { fn header_sync_due(&mut self, header_head: &chain::Tip) -> bool { let now = Utc::now(); - let (prev_ts, prev_height) = self.prev_header_sync; + let (timeout, latest_height, prev_height) = self.prev_header_sync; + + // received all necessary headers, can ask for more + let all_headers_received = header_head.height >= prev_height + (p2p::MAX_BLOCK_HEADERS as u64) - 4; + // no headers processed and we're past timeout, need to ask for more + let stalling = header_head.height == latest_height && now > timeout; - if header_head.height >= prev_height + (p2p::MAX_BLOCK_HEADERS as u64) - 4 - || now - prev_ts > Duration::seconds(10) - { - self.prev_header_sync = (now, header_head.height); - return true; + if all_headers_received || stalling { + self.prev_header_sync = (now + Duration::seconds(10), header_head.height, header_head.height); + true + } else { + // resetting the timeout as long as we progress + if header_head.height > latest_height { + self.prev_header_sync = (now + Duration::seconds(2), header_head.height, prev_height); + } + false } - false } fn body_sync_due(&mut self, head: &chain::Tip) -> bool { diff --git a/servers/tests/simulnet.rs b/servers/tests/simulnet.rs index 59b305975..a62e8d038 100644 --- a/servers/tests/simulnet.rs +++ b/servers/tests/simulnet.rs @@ -267,7 +267,7 @@ fn simulate_fast_sync() { let s1 = servers::Server::new(framework::config(2000, "grin-fast", 2000)).unwrap(); s1.start_test_miner(None); - while s1.head().height < 21 { + while s1.head().height < 20 { thread::sleep(time::Duration::from_millis(1_000)); } @@ -275,9 +275,12 @@ fn simulate_fast_sync() { conf.archive_mode = Some(false); let s2 = servers::Server::new(conf).unwrap(); - while s2.head().height < 21 { + + while s2.header_head().height < 1 { + s2.ping_peers(); thread::sleep(time::Duration::from_millis(1_000)); } + s1.stop_test_miner(); // Get the current header from s1. let s1_header = s1.chain.head_header().unwrap();