Pool daemon: rejections by code in STATUS and /api/stats, the ledger's life and this run apart (7 October 2026, Devnet 3 pool-b: STATUS rejected=235,016 was the ledger's lifetime across the daemon's eras while the member had no rejected line in the hour; the two counters now say what they count)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
03dd76c40f
commit
96be28bc71
4 changed files with 26 additions and 7 deletions
|
|
@ -87,7 +87,7 @@ pub fn stats(pool: &Pool) -> Value {
|
|||
"scheme": "PPLNS", "fee_percent": pool.cfg.fee_percent, "min_payout_ign": pool.cfg.min_payout_ign, "pplns_window_blocks": pool.cfg.pplns_window_blocks,
|
||||
"hashrate": round(s.hashrate(600, None, None), 0), "hashrate_unit": "H/s", "hashrate_1h": round(s.hashrate(3600, None, None), 0),
|
||||
"miners": miners, "workers": workers,
|
||||
"shares": { "accepted": s.accepted, "stale": s.stale, "rejected": s.rejected, "window_weight_blocks": round(s.pplns.total_weight, 4), "window_shares": s.pplns.shares.len() },
|
||||
"shares": { "accepted": s.accepted, "stale": s.stale, "rejected": s.rejected, "window_weight_blocks": round(s.pplns.total_weight, 4), "window_shares": s.pplns.shares.len(), "rejected_by_code": s.rejected_by_code, "rejected_by_code_this_run": s.rejected_by_code_run, "counters_since": "ledger (rejected, stale, accepted, rejected_by_code are the ledger's life across restarts; rejected_by_code_this_run is this process)" },
|
||||
"blocks_24h": f24, "blocks_confirmed_24h": c24, "blocks_orphaned_24h": o24,
|
||||
"blocks_total": s.blocks_found, "blocks_confirmed_total": s.blocks_confirmed, "blocks_orphaned_total": s.blocks_orphaned,
|
||||
"last_block": last.map(block_json),
|
||||
|
|
|
|||
|
|
@ -261,8 +261,12 @@ async fn main() {
|
|||
let (miners, workers) = pool.online();
|
||||
let s = pool.state.lock().unwrap();
|
||||
let (n, mean, p50, p99, max) = s.check_cost();
|
||||
let by_code = |m: &std::collections::BTreeMap<String, u64>| {
|
||||
let v: Vec<String> = m.iter().filter(|(c, n)| **n > 0 && c.as_str() != "stale").map(|(c, n)| format!("{c}={n}")).collect();
|
||||
if v.is_empty() { "none".to_string() } else { v.join(",") }
|
||||
};
|
||||
println!(
|
||||
"{} STATUS miners={miners} workers={workers} accepted={} stale={} rejected={} hashrate={:.0} H/s blocks={} confirmed={} orphans={} window={:.3} blocks/{} shares check_ms n={n} mean={mean:.3} p50={p50:.3} p99={p99:.3} max={max:.3}",
|
||||
"{} STATUS miners={miners} workers={workers} accepted={} stale={} rejected={} hashrate={:.0} H/s blocks={} confirmed={} orphans={} window={:.3} blocks/{} shares check_ms n={n} mean={mean:.3} p50={p50:.3} p99={p99:.3} max={max:.3} rejected_by_code(ledger)={} rejected_by_code(this run)={}",
|
||||
state::unix_ms(),
|
||||
s.accepted,
|
||||
s.stale,
|
||||
|
|
@ -272,7 +276,9 @@ async fn main() {
|
|||
s.blocks_confirmed,
|
||||
s.blocks_orphaned,
|
||||
s.pplns.total_weight,
|
||||
s.pplns.shares.len()
|
||||
s.pplns.shares.len(),
|
||||
by_code(&s.rejected_by_code),
|
||||
by_code(&s.rejected_by_code_run)
|
||||
);
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -329,7 +329,7 @@ async fn handle_share(pool: &Arc<Pool>, m: &Arc<Member>, job_id: u64, nonce: u64
|
|||
Err(code) => {
|
||||
{
|
||||
let mut s = pool.state.lock().unwrap();
|
||||
s.refuse_share(&m.address, &m.worker, code == Code::Stale, None);
|
||||
s.refuse_share(&m.address, &m.worker, code.as_str(), None);
|
||||
}
|
||||
{
|
||||
let mut g = m.inner.lock().unwrap();
|
||||
|
|
@ -352,7 +352,7 @@ async fn handle_share(pool: &Arc<Pool>, m: &Arc<Member>, job_id: u64, nonce: u64
|
|||
if v.code != Code::Ok {
|
||||
{
|
||||
let mut s = pool.state.lock().unwrap();
|
||||
s.refuse_share(&m.address, &m.worker, false, Some(v.cost_ms));
|
||||
s.refuse_share(&m.address, &m.worker, v.code.as_str(), Some(v.cost_ms));
|
||||
}
|
||||
m.inner.lock().unwrap().rejected += 1;
|
||||
m.send(Msg::ShareResult { job_id, nonce: hex_u64(nonce), accepted: false, code: v.code.as_str().into(), weight: 0.0, block: false }.line());
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
use crate::pplns::{Payee, Pplns, ShareRec};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::{HashMap, VecDeque};
|
||||
use std::collections::{BTreeMap, HashMap, VecDeque};
|
||||
use std::path::Path;
|
||||
|
||||
pub const WEI_PER_IGN: u128 = 1_000_000_000_000_000_000;
|
||||
|
|
@ -110,6 +110,14 @@ pub struct State {
|
|||
/// Q72: addresses already alerted for silence (cleared when they send again)
|
||||
#[serde(default)]
|
||||
pub alerted: HashMap<String, u64>,
|
||||
/// Rejections by code over the ledger's life (persisted with it, as `rejected` is: 7 October 2026, Devnet 3
|
||||
/// pool-b, the daemon's STATUS said rejected=235,016 while its member had not one rejected line in the hour;
|
||||
/// the daemon's counter is the ledger's lifetime, the member's is its own run)
|
||||
#[serde(default)]
|
||||
pub rejected_by_code: BTreeMap<String, u64>,
|
||||
/// Rejections by code since this process started (what a reader beside a member's own counters wants)
|
||||
#[serde(skip)]
|
||||
pub rejected_by_code_run: BTreeMap<String, u64>,
|
||||
#[serde(skip)]
|
||||
pub dirty: bool,
|
||||
}
|
||||
|
|
@ -136,6 +144,8 @@ impl State {
|
|||
check_ms: VecDeque::new(),
|
||||
history: HashMap::new(),
|
||||
alerted: HashMap::new(),
|
||||
rejected_by_code: BTreeMap::new(),
|
||||
rejected_by_code_run: BTreeMap::new(),
|
||||
dirty: false,
|
||||
}
|
||||
}
|
||||
|
|
@ -245,8 +255,9 @@ impl State {
|
|||
out
|
||||
}
|
||||
|
||||
pub fn refuse_share(&mut self, address: &str, worker: &str, stale: bool, cost_ms: Option<f64>) {
|
||||
pub fn refuse_share(&mut self, address: &str, worker: &str, code: &str, cost_ms: Option<f64>) {
|
||||
let now = unix_ms();
|
||||
let stale = code == "stale";
|
||||
if let Some(c) = cost_ms {
|
||||
self.check_ms.push_back(c);
|
||||
}
|
||||
|
|
@ -255,6 +266,8 @@ impl State {
|
|||
} else {
|
||||
self.rejected += 1;
|
||||
}
|
||||
*self.rejected_by_code.entry(code.to_string()).or_insert(0) += 1;
|
||||
*self.rejected_by_code_run.entry(code.to_string()).or_insert(0) += 1;
|
||||
let w = self.miner(address, worker, now);
|
||||
if stale {
|
||||
w.stale += 1
|
||||
|
|
|
|||
Loading…
Reference in a new issue