commit 0e369580e4e99d9937c51e47328103d807013e30
parent 1924a69100a9a9012e6682cb188779c796f31155
Author: Joris Hartog <jorishartog@hotmail.com>
Date: Mon, 24 Aug 2026 10:42:09 +0200
Deduplicate automatic finalization skip logs
Diffstat:
2 files changed, 54 insertions(+), 14 deletions(-)
diff --git a/src/main.rs b/src/main.rs
@@ -642,25 +642,16 @@ async fn run_automatic_finalizer(node: SharedNode, gossip: p2p::GossipNetwork, d
let Some(work) = plan.work else {
if let Some(reason) = &plan.skipped_reason {
- let skip = (height, reason.clone());
- if debug && last_logged_skip.as_ref() != Some(&skip) {
+ if debug
+ && should_log_automatic_finalization_skip(&mut last_logged_skip, height, reason)
+ {
println!("auto-finalization skipped at height {height}: {reason}");
- last_logged_skip = Some(skip);
}
}
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
continue;
};
- last_logged_skip = None;
- if debug {
- println!(
- "leader selected locally for candidate block {}; running VDF for {} rounds",
- work.height(),
- work.vdf_rounds()
- );
- }
-
let candidate_height = work.height();
let candidate_parent = work.prev_hash().to_string();
let seed = work.vdf_seed().to_string();
@@ -672,7 +663,9 @@ async fn run_automatic_finalizer(node: SharedNode, gossip: p2p::GossipNetwork, d
};
if let Err(error) = precheck {
let message = format!("skipped before VDF: {error:#}");
- if debug {
+ if debug
+ && should_log_automatic_finalization_skip(&mut last_logged_skip, height, &message)
+ {
println!("auto-finalization {message}");
}
node.lock()
@@ -681,6 +674,14 @@ async fn run_automatic_finalizer(node: SharedNode, gossip: p2p::GossipNetwork, d
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
continue;
}
+ last_logged_skip = None;
+ if debug {
+ println!(
+ "leader selected locally for candidate block {}; running VDF for {} rounds",
+ work.height(),
+ work.vdf_rounds()
+ );
+ }
let (progress_tx, progress_rx) = std::sync::mpsc::channel();
let cancellation = Arc::new(AtomicBool::new(false));
let worker_cancellation = Arc::clone(&cancellation);
@@ -793,6 +794,19 @@ async fn run_automatic_finalizer(node: SharedNode, gossip: p2p::GossipNetwork, d
}
}
+fn should_log_automatic_finalization_skip(
+ last_logged_skip: &mut Option<(u64, String)>,
+ height: u64,
+ reason: &str,
+) -> bool {
+ let skip = (height, reason.to_string());
+ if last_logged_skip.as_ref() == Some(&skip) {
+ return false;
+ }
+ *last_logged_skip = Some(skip);
+ true
+}
+
fn format_vdf_progress(candidate_height: u64, progress: VdfProgress) -> String {
let phase = match progress.phase {
VdfProgressPhase::Output => "output",
diff --git a/src/main_tests.rs b/src/main_tests.rs
@@ -24,7 +24,7 @@ use super::{
initial_burn_per_block, initialize_ledger, load_startup_wallet, measure_vdf_rounds,
parse_startup_bool_env_value, parse_startup_pow_mining_workers_env_value,
persist_chain_snapshot, project_ui_data_store, run_chain_persistence_with_interval,
- validate_wallet_for_mode,
+ should_log_automatic_finalization_skip, validate_wallet_for_mode,
};
fn parse(args: &[&str]) -> anyhow::Result<Option<CliOptions>> {
@@ -427,6 +427,32 @@ fn automatic_pow_worker_searches_outside_node_lock() {
}
#[test]
+fn automatic_finalization_skip_logging_only_reports_state_changes() {
+ let mut last = None;
+
+ assert!(should_log_automatic_finalization_skip(
+ &mut last,
+ 54,
+ "skipped before VDF: block timestamp is too far in the future",
+ ));
+ assert!(!should_log_automatic_finalization_skip(
+ &mut last,
+ 54,
+ "skipped before VDF: block timestamp is too far in the future",
+ ));
+ assert!(should_log_automatic_finalization_skip(
+ &mut last,
+ 55,
+ "skipped before VDF: block timestamp is too far in the future",
+ ));
+ assert!(should_log_automatic_finalization_skip(
+ &mut last,
+ 55,
+ "waiting for burn bundles",
+ ));
+}
+
+#[test]
fn removed_wallet_seed_is_rejected() {
let error = parse(&["--wallet-seed", "alice", "--genesis"]).unwrap_err();
assert!(error.to_string().contains("--wallet-seed was removed"));