Tweak heartbeat task to run less often if there's no progress to be made

This commit is contained in:
Luke Parker
2025-01-03 13:59:14 -05:00
parent 5fc8500f8d
commit 3f3b0255f8

View File

@@ -41,22 +41,21 @@ impl<TD: Db> ContinuallyRan for HeartbeatTask<TD> {
// If our blockchain hasn't had a block in the past minute, trigger the heartbeat protocol // If our blockchain hasn't had a block in the past minute, trigger the heartbeat protocol
const TIME_TO_TRIGGER_SYNCING: Duration = Duration::from_secs(60); const TIME_TO_TRIGGER_SYNCING: Duration = Duration::from_secs(60);
// Fetch the state from the tip of the blockchain let mut tip = self.reader.tip();
let state = |reader: &TributaryReader<_, _>| { let time_since = {
let tip = reader.tip(); let block_time = if let Some(time_of_block) = self.reader.time_of_block(&tip) {
let block_time = if let Some(time_of_block) = reader.time_of_block(&tip) {
SystemTime::UNIX_EPOCH + Duration::from_secs(time_of_block) SystemTime::UNIX_EPOCH + Duration::from_secs(time_of_block)
} else { } else {
// If we couldn't fetch this block's time, assume it's old // If we couldn't fetch this block's time, assume it's old
// We don't want to declare its unix time as 0 and claim it's 50+ years old though // We don't want to declare its unix time as 0 and claim it's 50+ years old though
log::warn!(
"heartbeat task couldn't fetch the time of a block, flagging it as a minute old"
);
SystemTime::now() - TIME_TO_TRIGGER_SYNCING SystemTime::now() - TIME_TO_TRIGGER_SYNCING
}; };
(tip, SystemTime::now().duration_since(block_time).unwrap_or(Duration::ZERO)) SystemTime::now().duration_since(block_time).unwrap_or(Duration::ZERO)
}; };
let mut tip_is_stale = false;
// The current state, and a boolean of it's stale
let (mut tip, mut time_since) = state(&self.reader);
let mut state_is_stale = false;
let mut synced_block = false; let mut synced_block = false;
if TIME_TO_TRIGGER_SYNCING <= time_since { if TIME_TO_TRIGGER_SYNCING <= time_since {
@@ -71,9 +70,9 @@ impl<TD: Db> ContinuallyRan for HeartbeatTask<TD> {
'peer: for peer in self.p2p.peers(self.set.network).await { 'peer: for peer in self.p2p.peers(self.set.network).await {
loop { loop {
// Create the request for blocks // Create the request for blocks
if state_is_stale { if tip_is_stale {
(tip, time_since) = state(&self.reader); tip = self.reader.tip();
state_is_stale = false; tip_is_stale = false;
} }
let request = Request::Heartbeat { set: self.set, latest_block_hash: tip }; let request = Request::Heartbeat { set: self.set, latest_block_hash: tip };
let Ok(Response::Blocks(blocks)) = peer.send(request).await else { continue 'peer }; let Ok(Response::Blocks(blocks)) = peer.send(request).await else { continue 'peer };
@@ -96,8 +95,8 @@ impl<TD: Db> ContinuallyRan for HeartbeatTask<TD> {
continue 'peer; continue 'peer;
} }
// Because we synced a block, flag the state as stale // Because we synced a block, flag the tip as stale
state_is_stale = true; tip_is_stale = true;
// And that we did sync a block // And that we did sync a block
synced_block = true; synced_block = true;
} }
@@ -110,6 +109,16 @@ impl<TD: Db> ContinuallyRan for HeartbeatTask<TD> {
} }
} }
} }
// This will cause the tak to be run less and less often, ensuring we aren't spamming the
// net if we legitimately aren't making progress
if !synced_block {
Err(format!(
"tried to sync blocks for {:?} since we haven't seen one in {} seconds but didn't",
self.set,
time_since.as_secs(),
))?;
}
} }
Ok(synced_block) Ok(synced_block)