Files
KamadoPool/ui/src/types.ts
T
satoshi df0dbf89e5 Harden block-recording pipeline: P0 reliability fixes
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.
2026-04-27 16:30:15 +03:00

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;
};