Skip to content

Commit f4d6d8f

Browse files
committed
Add block stale-ness check
I noticed my home node got stuck on a block with the connection it had, but continued to exchange ping and pongs. This adds a very basic check to see if blocks are being withheld from us by disconnecting from a peer if they have not sent a block to us for 20 minutes.
1 parent 96f32ad commit f4d6d8f

File tree

1 file changed

+17
-2
lines changed

1 file changed

+17
-2
lines changed

src/bin/node.rs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use std::{
77
Arc, Mutex, Once,
88
},
99
thread::{self, available_parallelism},
10-
time::Duration,
10+
time::{Duration, Instant},
1111
};
1212

1313
use bitcoin::{BlockHash, Network, TestnetVersion};
@@ -35,6 +35,8 @@ const MAX_BUCKETS: usize = 4;
3535

3636
const DNS_RESOLVER: IpAddr = IpAddr::V4(Ipv4Addr::new(1, 1, 1, 1));
3737

38+
const STALE_BLOCK_DURATION: Duration = Duration::from_secs(60 * 20);
39+
3840
configure_me::include_config!();
3941

4042
fn create_context(
@@ -224,6 +226,7 @@ fn run(
224226
let peer_source = Arc::clone(&addrman);
225227
let kill = Arc::new(Mutex::new(None));
226228
let writer = Arc::clone(&kill);
229+
let stale_block_kill = Arc::clone(&kill);
227230

228231
let peer_processing_handler = thread::spawn(move || {
229232
info!("Starting net processing thread.");
@@ -295,13 +298,25 @@ fn run(
295298

296299
let block_processing_handler = thread::spawn(move || {
297300
info!("Starting block processing thread.");
301+
let mut last_block = Instant::now();
298302
while running_block.load(Ordering::SeqCst) {
299303
match block_rx.recv_timeout(Duration::from_secs(1)) {
300304
Ok(block) => {
301305
debug!("Validating block.");
306+
last_block = Instant::now();
302307
let _ = chainman.process_block(&block);
303308
}
304-
Err(RecvTimeoutError::Timeout) => continue,
309+
Err(RecvTimeoutError::Timeout) => {
310+
if last_block.elapsed() > STALE_BLOCK_DURATION {
311+
last_block = Instant::now();
312+
warn!("Potential stale block. Finding a new peer.");
313+
let mut peer_lock = stale_block_kill.lock().unwrap();
314+
if let Some(conn) = peer_lock.deref_mut() {
315+
let _ = conn.shutdown();
316+
}
317+
}
318+
continue;
319+
}
305320
Err(RecvTimeoutError::Disconnected) => break,
306321
}
307322
}

0 commit comments

Comments
 (0)