Closes the silent-failure modes between "ckpool logs a solve" and "block correctly displayed": * Difficulty estimate matched mempool.space — the projection now uses (inEpoch + 1) intervals so it converges on Bitcoin Core's eventual retarget formula at end-of-epoch instead of undershooting by ~0.05– 0.10 % throughout. * Tailer resumes mid-log on restart — persists (inode, offset) to kv every EOF + on shutdown, and replays the unread tail next time. Any solve line written while kamado-api was down would previously be invisible forever. * Background reconcile loop (60 s) retries hash/reward enrichment for blocks the original RPC missed, so a transient bitcoind-index race no longer permanently leaves a block hashless. * Reorg detection: same loop compares each recent stored hash against getblockhash(height); a mismatch stamps orphaned_at. UI renders these strikethrough with a red "orphaned" tag instead of showing illusory rewards forever. * InsertBlock now reports whether a row was actually inserted; the caller WARN-logs duplicate-height ignores so a re-mined orphaned height can't disappear silently. * Submit-attempt vs confirmed counters surface failed submissions: every "Possible/Submitting block solve" log line increments block_submit_attempts; "Solved and confirmed" increments block_submits_confirmed. A growing gap means bitcoind is rejecting our submissions — previously invisible. * share_err patch refreshed against pinned ckpool source: added SE_NO_JOBID -> 21 and SE_WORKER_MISMATCH -> 24 mappings, kept SE_INVALID_NONCE2 in 20 (it's a malformed-input error, not low-diff). AxeOS users now see actionable Stratum codes instead of "unknown error". UI gets new orphaned_at + block_submit_attempts/confirmed fields on the snapshot type and a strikethrough-with-tag rendering for orphaned blocks in BlocksTable.
139 lines
3.4 KiB
TypeScript
139 lines
3.4 KiB
TypeScript
// Mirrors api/internal/state.Snapshot. Keep field names aligned; the
|
|
// Go side is authoritative.
|
|
|
|
export type PoolStats = {
|
|
start: number;
|
|
update: number;
|
|
workers: number;
|
|
users: number;
|
|
disconnected: number;
|
|
shares: number;
|
|
accepted: number;
|
|
rejected: number;
|
|
dsps1: number;
|
|
dsps5: number;
|
|
dsps15: number;
|
|
dsps60: number;
|
|
dsps360: number;
|
|
dsps1440: number;
|
|
dsps10080: number;
|
|
};
|
|
|
|
export type User = {
|
|
user: string;
|
|
id: number;
|
|
workers: number;
|
|
bestdiff: number;
|
|
bestever: number;
|
|
dsps1: number;
|
|
dsps5: number;
|
|
dsps60: number;
|
|
dsps1440: number;
|
|
dsps10080: number;
|
|
lastshare: number;
|
|
};
|
|
|
|
export type Worker = {
|
|
user: string;
|
|
worker: string;
|
|
id: number;
|
|
dsps1: number;
|
|
dsps5: number;
|
|
dsps60: number;
|
|
dsps1440: number;
|
|
lastshare: number;
|
|
bestdiff: number;
|
|
bestever: number;
|
|
mindiff: number;
|
|
idle: boolean;
|
|
};
|
|
|
|
export type StratumClient = {
|
|
id: number;
|
|
enonce1: string;
|
|
diff: number;
|
|
dsps1: number;
|
|
dsps5: number;
|
|
dsps60: number;
|
|
dsps1440: number;
|
|
lastshare: number;
|
|
starttime: number;
|
|
// Source IP, NOT the BTC payout address. ckpool sets this from
|
|
// inet_ntop(client_addr) in connector.c — see stratum_add_instance.
|
|
// The BTC address comes from `workername` (or the joined Worker.user).
|
|
address: string;
|
|
subscribed: boolean;
|
|
authorised: boolean;
|
|
idle: boolean;
|
|
useragent: string;
|
|
workername: string;
|
|
userid: number;
|
|
// Index into ckpool's serverurl[] array; identifies which stratum
|
|
// bind the client connected on. We use this to tag TLS clients:
|
|
// index 0 is the public plaintext bind, index 1 is the loopback-only
|
|
// bind that stunnel forwards TLS traffic to.
|
|
server: number;
|
|
bestdiff: number;
|
|
};
|
|
|
|
export type BlockchainInfo = {
|
|
chain: string;
|
|
blocks: number;
|
|
headers: number;
|
|
bestblockhash: string;
|
|
difficulty: number;
|
|
mediantime: number;
|
|
verificationprogress: number;
|
|
initialblockdownload: boolean;
|
|
};
|
|
|
|
export type BlockRecord = {
|
|
height: number;
|
|
hash?: string;
|
|
reward_btc?: number;
|
|
found_at: string; // RFC 3339
|
|
source: string;
|
|
share_diff?: number;
|
|
// Set when the periodic chain reconciler finds the recorded hash no
|
|
// longer matches the canonical block at this height (network reorged
|
|
// us out). UI renders these strikethrough.
|
|
orphaned_at?: string; // RFC 3339, omitted when zero
|
|
};
|
|
|
|
export type HashratePoint = {
|
|
t: number; // unix seconds
|
|
v: number; // H/s
|
|
};
|
|
|
|
export type Snapshot = {
|
|
generated_at: string;
|
|
pool: PoolStats | null;
|
|
uptime_seconds: number;
|
|
users: User[] | null;
|
|
workers: Worker[] | null;
|
|
clients: StratumClient[] | null;
|
|
hashrate_hs_1m: number;
|
|
hashrate_hs_5m: number;
|
|
hashrate_hs_1h: number;
|
|
hashrate_hs_24h: number;
|
|
best_diff: number;
|
|
cumulative_shares: number;
|
|
next_block_reward_btc: number;
|
|
next_difficulty_percent: number;
|
|
chain: BlockchainInfo | null;
|
|
network_hashrate_hs: number;
|
|
recent_blocks?: BlockRecord[];
|
|
hashrate_history?: HashratePoint[];
|
|
// Optional override for explorer links. Empty/undefined means the
|
|
// UI falls back to its mempool.space defaults.
|
|
mempool_base_url?: string;
|
|
// Submission attempt tracking — count of "Possible block solve"
|
|
// log lines vs "Solved and confirmed" lines. A growing gap means
|
|
// submissions are being rejected by bitcoind.
|
|
block_submit_attempts: number;
|
|
block_submits_confirmed: number;
|
|
ckpool_ok: boolean;
|
|
bitcoin_ok: boolean;
|
|
last_error?: string;
|
|
};
|