ix ckpool.conf render dropping the TLS bind port; Let deployments declare what each stratum bind is

This commit is contained in:
2026-08-01 06:22:11 +03:00
parent 2c4c6609ba
commit 8a35b02c7e
10 changed files with 159 additions and 45 deletions
+49 -20
View File
@@ -25,6 +25,21 @@ type HashratePoint struct {
V float64 `json:"v"` // H/s
}
// StratumServer describes one entry in ckpool's serverurl[] array. ckpool
// tags every client with the index of the bind it arrived on, but the index
// alone doesn't say what that bind *is* — that depends on how the deployment
// rendered ckpool.conf. Declaring the array lets the dashboard report the
// actual transport (plaintext, TLS with which certificate) instead of
// hardcoding a bind order.
type StratumServer struct {
// Kind is the stable machine-readable tag the UI switches on:
// "plain", "tls-local" (package-managed self-signed certificate) or
// "tls-public" (CA-issued certificate for a public domain).
Kind string `json:"kind"`
// Label is the human-readable description shown on hover.
Label string `json:"label"`
}
// Snapshot is the merged view served to the UI. All fields are safe to
// JSON-serialize directly.
type Snapshot struct {
@@ -38,7 +53,7 @@ type Snapshot struct {
Clients []ckpool.StratumClient `json:"clients"`
// Derived/enriched fields
HashrateHs float64 `json:"hashrate_hs_1m"` // from PoolStats.DSPS1
HashrateHs float64 `json:"hashrate_hs_1m"` // from PoolStats.DSPS1
HashrateHs5m float64 `json:"hashrate_hs_5m"`
HashrateHs1h float64 `json:"hashrate_hs_1h"`
HashrateHs24h float64 `json:"hashrate_hs_24h"`
@@ -68,8 +83,8 @@ type Snapshot struct {
NextDifficultyPercent float64 `json:"next_difficulty_percent"`
// Bitcoin Core fields
Chain *bitcoind.BlockchainInfo `json:"chain"`
NetworkHashrateHs float64 `json:"network_hashrate_hs"`
Chain *bitcoind.BlockchainInfo `json:"chain"`
NetworkHashrateHs float64 `json:"network_hashrate_hs"`
// Recent found blocks (in-memory history; persisted in Phase 2b.5).
RecentBlocks []BlockRecord `json:"recent_blocks,omitempty"`
@@ -82,6 +97,13 @@ type Snapshot struct {
// the StartOS config "Block Explorer" -> "Custom URL".
MempoolBaseURL string `json:"mempool_base_url,omitempty"`
// Describes ckpool's serverurl[] array: entry N tells the UI what a
// client with `server == N` is actually connected over. Set via the
// STRATUM_SERVERS env by whoever renders ckpool.conf (the StartOS
// wrapper). Empty when undeclared, in which case the UI falls back to
// its historical "index 1 means TLS" assumption.
StratumServers []StratumServer `json:"stratum_servers,omitempty"`
// Counts of share-submit attempts ("Possible/Submitting block solve"
// log lines) and confirmed solves ("Solved and confirmed block").
// A growing gap means bitcoind is rejecting our submissions or
@@ -93,15 +115,15 @@ type Snapshot struct {
// LastZMQEventAge is the seconds-since the last bitcoind hashblock
// frame arrived; -1 means no event seen since startup. ZMQEnabled
// is whether the user configured an endpoint at all.
ZMQEnabled bool `json:"zmq_enabled"`
LastZMQEventAge float64 `json:"last_zmq_event_age,omitempty"` // seconds; >=0
HasLastZMQEvent bool `json:"has_last_zmq_event"`
TipChangedAge float64 `json:"tip_changed_age"` // seconds since tip height last changed
ZMQEnabled bool `json:"zmq_enabled"`
LastZMQEventAge float64 `json:"last_zmq_event_age,omitempty"` // seconds; >=0
HasLastZMQEvent bool `json:"has_last_zmq_event"`
TipChangedAge float64 `json:"tip_changed_age"` // seconds since tip height last changed
// Bitcoin Core peer connections.
PeerCount int `json:"peer_count"`
PeersIn int `json:"peers_in"`
PeersOut int `json:"peers_out"`
PeerCount int `json:"peer_count"`
PeersIn int `json:"peers_in"`
PeersOut int `json:"peers_out"`
// Share counters: raw counts (1 submission = 1 share regardless of diff).
// Session = since ckpool started; AllTime = persisted across restarts.
@@ -151,8 +173,8 @@ const (
kvLatencyLastMs = "latency_last_ms"
kvStaleWorkHashes = "stale_work_hashes"
kvAckedBestDiff = "acked_best_diff"
kvBestDiff = "best_diff"
kvAckedBestDiff = "acked_best_diff"
kvBestDiff = "best_diff"
kvBestShareHash = "best_share_hash"
kvBestShareNetDiff = "best_share_net_diff"
@@ -186,6 +208,10 @@ type Aggregator struct {
// MempoolBaseURL leaves the UI on its mempool.space defaults.
MempoolBaseURL string
// Declared meaning of each ckpool serverurl[] index; see StratumServer.
// Nil leaves the UI on its index-1-means-TLS fallback.
StratumServers []StratumServer
// LogFilePath is the ckpool log path, used for one-time backfill
// of the best share hash when upgrading from a version that didn't
// capture it. Set by main before calling Run.
@@ -220,10 +246,10 @@ type Aggregator struct {
// post-load observation of pool.Shares only establishes the
// baseline — the current ckpool counter was already accounted for
// before we crashed.
cumulativeShares float64
lastPoolShares float64
hasPoolSharesBaseline bool
lastCumulativeSave time.Time
cumulativeShares float64
lastPoolShares float64
hasPoolSharesBaseline bool
lastCumulativeSave time.Time
// Next-block reward cache; refreshed on its own cadence so we don't
// hammer bitcoind with getblocktemplate on every poll tick.
@@ -245,8 +271,8 @@ type Aggregator struct {
// btcFailStreak counts consecutive refreshes where bitcoind was
// unreachable. After a threshold, if no block submission is pending,
// we kill the ckpool process so miners can failover to other pools.
btcFailStreak int
ckpoolKilled bool // true after we sent SIGTERM, reset on bitcoind recovery
btcFailStreak int
ckpoolKilled bool // true after we sent SIGTERM, reset on bitcoind recovery
// readyOnce + ready closes the Ready() channel exactly once after
// the first refresh completes. main blocks briefly on this so the
@@ -401,7 +427,11 @@ func (a *Aggregator) refresh(ctx context.Context) {
ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
defer cancel()
next := Snapshot{GeneratedAt: time.Now(), MempoolBaseURL: a.MempoolBaseURL}
next := Snapshot{
GeneratedAt: time.Now(),
MempoolBaseURL: a.MempoolBaseURL,
StratumServers: a.StratumServers,
}
// --- ckpool: poolstats, users, workers, clients, uptime ---
if ps, err := a.CK.PoolStats(ctx); err == nil {
@@ -776,7 +806,6 @@ func diffBucket(d float64) int {
// DiffBucketLabels are the human-readable labels for each difficulty bucket.
var DiffBucketLabels = [6]string{"< 1M", "1M 100M", "100M 1G", "1G 100G", "100G 1T", "≥ 1T"}
// IngestShareEvents reads individual share events from the log tailer
// and maintains rejection-reason counts and difficulty-distribution
// histograms. Session counters reset when ckpool restarts (detected by