Removes the entire fallback submitter mechanism: ckpool patch 0004,
the blocksubmit package, the wiring in main.go, the config fields,
the aggregator's fallback counters and snapshot fields, the healthz
fallback fields, and the TS type fields plus the HealthBanners
fallback alert.
Reasoning: ckpool's primary bitcoind submission must remain the
single source of truth, and getting the parallel "race a fallback
during the submit" semantics right is more architectural complexity
than the marginal reliability gain justifies. The original upstream
behavior — submit to bitcoind, retry indefinitely if unavailable —
is what we want.
Kept intact:
* Submit-attempt vs confirmed counters (block_submit_attempts /
block_submits_confirmed). Useful on their own as a "did bitcoind
confirm the submission?" signal.
* HealthBanners shows submit_gap and zmq_stale only.
* /healthz exposes submit_gap, zmq_stale, etc.
* All P0 reliability work (tailer cursor, reconcile loop, reorg
detection, multi-solve guard) and other P1 (RPC retry, WS
back-pressure, ZMQ tracking, startup readiness gate).
89 lines
2.4 KiB
Go
89 lines
2.4 KiB
Go
// Package config loads kamado-api configuration from environment variables.
|
|
// Missing required values are a hard error at startup; optional values get
|
|
// documented defaults.
|
|
package config
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"strconv"
|
|
"time"
|
|
)
|
|
|
|
type Config struct {
|
|
// HTTP server
|
|
ListenAddr string
|
|
|
|
// CKPool socket
|
|
CKPoolSockDir string
|
|
|
|
// Bitcoin Core RPC
|
|
BitcoinRPCURL string // full URL e.g. http://bitcoind:8332
|
|
BitcoinRPCUser string
|
|
BitcoinRPCPassword string
|
|
BitcoinRPCTimeout time.Duration
|
|
|
|
// ZMQ (Phase 2b)
|
|
BitcoinZMQBlock string // e.g. tcp://bitcoind:28332, empty to disable
|
|
|
|
// CKPool log file, for block-solve detection (Phase 2b)
|
|
CKPoolLogFile string
|
|
|
|
// SQLite DB path for persistence (Phase 2b)
|
|
DBPath string
|
|
|
|
// Poll interval for refreshing ckpool stats
|
|
PollInterval time.Duration
|
|
|
|
// Optional mempool.space-compatible explorer base URL. Empty means
|
|
// the UI uses the public mempool.space; non-empty means the user
|
|
// has pointed Kamado at their own instance via the StartOS config.
|
|
MempoolBaseURL string
|
|
}
|
|
|
|
func FromEnv() (*Config, error) {
|
|
cfg := &Config{
|
|
ListenAddr: getenv("LISTEN_ADDR", ":8080"),
|
|
CKPoolSockDir: getenv("CKPOOL_SOCKDIR", "/run/ckpool"),
|
|
BitcoinRPCURL: os.Getenv("BITCOIN_RPC_URL"),
|
|
BitcoinRPCUser: os.Getenv("BITCOIN_RPC_USER"),
|
|
BitcoinRPCPassword: os.Getenv("BITCOIN_RPC_PASSWORD"),
|
|
BitcoinRPCTimeout: getenvDuration("BITCOIN_RPC_TIMEOUT", 10*time.Second),
|
|
BitcoinZMQBlock: os.Getenv("BITCOIN_ZMQ_BLOCK"),
|
|
CKPoolLogFile: getenv("CKPOOL_LOGFILE", "/var/log/ckpool/ckpool.log"),
|
|
DBPath: getenv("DB_PATH", "/var/lib/kamado/kamado.db"),
|
|
PollInterval: getenvDuration("POLL_INTERVAL", 5*time.Second),
|
|
MempoolBaseURL: os.Getenv("MEMPOOL_BASE_URL"),
|
|
}
|
|
|
|
if cfg.BitcoinRPCURL == "" {
|
|
return nil, fmt.Errorf("BITCOIN_RPC_URL is required")
|
|
}
|
|
if cfg.BitcoinRPCUser == "" || cfg.BitcoinRPCPassword == "" {
|
|
return nil, fmt.Errorf("BITCOIN_RPC_USER and BITCOIN_RPC_PASSWORD are required")
|
|
}
|
|
return cfg, nil
|
|
}
|
|
|
|
func getenv(key, def string) string {
|
|
if v := os.Getenv(key); v != "" {
|
|
return v
|
|
}
|
|
return def
|
|
}
|
|
|
|
func getenvDuration(key string, def time.Duration) time.Duration {
|
|
v := os.Getenv(key)
|
|
if v == "" {
|
|
return def
|
|
}
|
|
// Accept both Go duration syntax ("5s", "10s") and bare seconds ("10").
|
|
if d, err := time.ParseDuration(v); err == nil {
|
|
return d
|
|
}
|
|
if n, err := strconv.Atoi(v); err == nil {
|
|
return time.Duration(n) * time.Second
|
|
}
|
|
return def
|
|
}
|