From 21a98cb43a4b20cce09d797ca173d929cfe5ad1d Mon Sep 17 00:00:00 2001 From: igneum-labs <337424239+igneum-labs@users.noreply.github.com> Date: Wed, 7 Oct 2026 06:10:39 +0000 Subject: [PATCH] Pool daemon: --template-timeout-s (default 20, was a fixed 5 s): pool-1's node builds a template in 1.6 to 1.8 s under load, four parallel member fetches overran 5 s and no job was issued for 7 minutes (7 October 2026, 06:08Z) Co-Authored-By: Claude Fable 5.1 --- pool/src/config.rs | 8 +++++++- pool/src/node.rs | 4 ++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/pool/src/config.rs b/pool/src/config.rs index 48b066a51..cdfe690c4 100644 --- a/pool/src/config.rs +++ b/pool/src/config.rs @@ -35,12 +35,16 @@ pub struct Config { pub snapshot_interval_s: u64, /// How long the start-up waits for the node to answer a template before the daemon refuses to start (exit 3) pub node_wait_secs: u64, + /// Per-member template fetch timeout. 7 October 2026, 06:08Z: pool-1's node built a template in 1.6 to 1.8 s under + /// its own miner plus four members, the fixed 5 s gave up on the parallel fetches, no job was issued for 7 minutes, + /// every block the stale templates found was an orphan, and vardiff could not act (a new target rides with a job) + pub template_timeout_s: u64, } impl Config { pub fn usage() -> ! { eprintln!( - "usage: igneum-pool [--node grpc://127.0.0.1:26610]... [--evm-rpc http://127.0.0.1:26790] [--listen 0.0.0.0:4463] [--node-wait-secs 60]\n\ + "usage: igneum-pool [--node grpc://127.0.0.1:26610]... [--evm-rpc http://127.0.0.1:26790] [--listen 0.0.0.0:4463] [--node-wait-secs 60] [--template-timeout-s 20]\n\ \x20 [--http 127.0.0.1:4480] [--data-dir ./data] [--payout-key ] [--fee-percent 1] [--min-payout 1.0]\n\ \x20 [--pplns-window 2.0] [--payout-interval-s 60] [--dry-run] [--network devnet|testnet|mainnet]\n\ \x20 [--share-interval-s 10] [--min-shift 0] [--max-shift 60] [--stale-grace-ms 2000] [--orphan-after-daa 120]\n\ @@ -73,6 +77,7 @@ impl Config { verify_threads: 2, snapshot_interval_s: 15, node_wait_secs: 60, + template_timeout_s: 20, }; let mut i = 0; while i < args.len() { @@ -104,6 +109,7 @@ impl Config { "--verify-threads" => c.verify_threads = val().parse::().unwrap_or_else(|_| Config::usage()).max(1), "--snapshot-interval-s" => c.snapshot_interval_s = val().parse().unwrap_or_else(|_| Config::usage()), "--node-wait-secs" => c.node_wait_secs = val().parse().unwrap_or_else(|_| Config::usage()), + "--template-timeout-s" => c.template_timeout_s = val().parse::().unwrap_or_else(|_| Config::usage()).max(1), "-h" | "--help" => Config::usage(), _ => Config::usage(), } diff --git a/pool/src/node.rs b/pool/src/node.rs index 24cb8ae37..a3a92d6ae 100644 --- a/pool/src/node.rs +++ b/pool/src/node.rs @@ -39,7 +39,7 @@ pub fn extra_data(member: &Member, pool_address: &[u8; 20]) -> Vec { /// cache build), so it runs under `spawn_blocking`. pub async fn fetch_job(pool: &Arc, member: &Arc) -> Result<(), String> { let t0 = Instant::now(); - let tmpl = match tokio::time::timeout(Duration::from_secs(5), pool.node.get_block_template(pool.pay_address.clone(), extra_data(member, &pool.pool_address))).await { + let tmpl = match tokio::time::timeout(Duration::from_secs(pool.cfg.template_timeout_s), pool.node.get_block_template(pool.pay_address.clone(), extra_data(member, &pool.pool_address))).await { Ok(Ok(t)) => t, Ok(Err(e)) => { pool.template_failures.fetch_add(1, Ordering::Relaxed); @@ -47,7 +47,7 @@ pub async fn fetch_job(pool: &Arc, member: &Arc) -> Result<(), Str } Err(_) => { pool.template_failures.fetch_add(1, Ordering::Relaxed); - return Err("template timed out".to_string()); + return Err(format!("template timed out after {} s (--template-timeout-s)", pool.cfg.template_timeout_s)); } }; pool.last_template_ok_ms.store(unix_ms(), Ordering::Relaxed);