docs(ax): improve proxy API comments
Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
parent
9460f82738
commit
2364633afc
7 changed files with 83 additions and 39 deletions
29
config.go
29
config.go
|
|
@ -1,6 +1,9 @@
|
|||
package proxy
|
||||
|
||||
// LoadConfig("/etc/proxy.json")
|
||||
// Config is the top-level proxy configuration.
|
||||
//
|
||||
// cfg, result := proxy.LoadConfig("/etc/proxy.json")
|
||||
// if !result.OK { return result.Error }
|
||||
type Config struct {
|
||||
Mode string `json:"mode"` // "nicehash" or "simple"
|
||||
Bind []BindAddr `json:"bind"` // listen addresses
|
||||
|
|
@ -22,14 +25,18 @@ type Config struct {
|
|||
configPath string
|
||||
}
|
||||
|
||||
// BindAddr{Host: "0.0.0.0", Port: 3333, TLS: false}
|
||||
// BindAddr is one TCP listen endpoint.
|
||||
//
|
||||
// proxy.BindAddr{Host: "0.0.0.0", Port: 3333, TLS: false}
|
||||
type BindAddr struct {
|
||||
Host string `json:"host"`
|
||||
Port uint16 `json:"port"`
|
||||
TLS bool `json:"tls"`
|
||||
}
|
||||
|
||||
// PoolConfig{URL: "pool.lthn.io:3333", User: "WALLET", Pass: "x", Enabled: true}
|
||||
// PoolConfig is one upstream pool entry.
|
||||
//
|
||||
// proxy.PoolConfig{URL: "pool.lthn.io:3333", User: "WALLET", Pass: "x", Enabled: true}
|
||||
type PoolConfig struct {
|
||||
URL string `json:"url"`
|
||||
User string `json:"user"`
|
||||
|
|
@ -42,7 +49,9 @@ type PoolConfig struct {
|
|||
Enabled bool `json:"enabled"`
|
||||
}
|
||||
|
||||
// TLSConfig{Enabled: true, CertFile: "/etc/proxy/cert.pem", KeyFile: "/etc/proxy/key.pem"}
|
||||
// TLSConfig controls inbound TLS for miner listeners.
|
||||
//
|
||||
// proxy.TLSConfig{Enabled: true, CertFile: "/etc/proxy/cert.pem", KeyFile: "/etc/proxy/key.pem"}
|
||||
type TLSConfig struct {
|
||||
Enabled bool `json:"enabled"`
|
||||
CertFile string `json:"cert"`
|
||||
|
|
@ -51,7 +60,9 @@ type TLSConfig struct {
|
|||
Protocols string `json:"protocols"` // TLS version string; "" = default
|
||||
}
|
||||
|
||||
// HTTPConfig{Enabled: true, Host: "127.0.0.1", Port: 8080, Restricted: true}
|
||||
// HTTPConfig controls the monitoring API server.
|
||||
//
|
||||
// proxy.HTTPConfig{Enabled: true, Host: "127.0.0.1", Port: 8080, Restricted: true}
|
||||
type HTTPConfig struct {
|
||||
Enabled bool `json:"enabled"`
|
||||
Host string `json:"host"`
|
||||
|
|
@ -60,13 +71,17 @@ type HTTPConfig struct {
|
|||
Restricted bool `json:"restricted"` // true = read-only GET only
|
||||
}
|
||||
|
||||
// RateLimit{MaxConnectionsPerMinute: 30, BanDurationSeconds: 300}
|
||||
// RateLimit controls per-IP connection throttling.
|
||||
//
|
||||
// proxy.RateLimit{MaxConnectionsPerMinute: 30, BanDurationSeconds: 300}
|
||||
type RateLimit struct {
|
||||
MaxConnectionsPerMinute int `json:"max-connections-per-minute"` // 0 = disabled
|
||||
BanDurationSeconds int `json:"ban-duration"` // 0 = no ban
|
||||
}
|
||||
|
||||
// WorkersByRigID
|
||||
// WorkersMode selects the login field used as the worker identity.
|
||||
//
|
||||
// proxy.WorkersByRigID
|
||||
type WorkersMode string
|
||||
|
||||
const (
|
||||
|
|
|
|||
13
events.go
13
events.go
|
|
@ -2,15 +2,19 @@ package proxy
|
|||
|
||||
import "sync"
|
||||
|
||||
// EventBus dispatches proxy lifecycle events to synchronous listeners.
|
||||
//
|
||||
// bus := proxy.NewEventBus()
|
||||
// bus.Subscribe(proxy.EventLogin, func(e proxy.Event) { fmt.Println(e.Miner.User()) })
|
||||
// bus.Subscribe(proxy.EventLogin, func(e proxy.Event) { _ = e.Miner.User() })
|
||||
// bus.Subscribe(proxy.EventAccept, stats.OnAccept)
|
||||
type EventBus struct {
|
||||
listeners map[EventType][]EventHandler
|
||||
mu sync.RWMutex
|
||||
}
|
||||
|
||||
// EventType identifies the proxy lifecycle event.
|
||||
// EventType identifies one proxy lifecycle event.
|
||||
//
|
||||
// proxy.EventLogin
|
||||
type EventType int
|
||||
|
||||
const (
|
||||
|
|
@ -21,12 +25,13 @@ const (
|
|||
)
|
||||
|
||||
// EventHandler is the callback signature for all event types.
|
||||
//
|
||||
// handler := func(e proxy.Event) { _ = e.Miner }
|
||||
type EventHandler func(Event)
|
||||
|
||||
// Event carries the data for any proxy lifecycle event.
|
||||
// Fields not relevant to the event type are zero/nil.
|
||||
//
|
||||
// bus.Dispatch(proxy.Event{Type: proxy.EventLogin, Miner: m})
|
||||
// bus.Dispatch(proxy.Event{Type: proxy.EventLogin, Miner: m})
|
||||
type Event struct {
|
||||
Type EventType
|
||||
Miner *Miner // always set
|
||||
|
|
|
|||
9
job.go
9
job.go
|
|
@ -1,13 +1,8 @@
|
|||
package proxy
|
||||
|
||||
// Job holds the current work unit received from a pool. Immutable once assigned.
|
||||
// Job holds one pool work unit and its metadata.
|
||||
//
|
||||
// j := proxy.Job{
|
||||
// Blob: "0707d5ef...b01",
|
||||
// JobID: "4BiGm3/RgGQzgkTI",
|
||||
// Target: "b88d0600",
|
||||
// Algo: "cn/r",
|
||||
// }
|
||||
// j := proxy.Job{Blob: "0707d5ef...b01", JobID: "4BiGm3/RgGQzgkTI", Target: "b88d0600", Algo: "cn/r"}
|
||||
type Job struct {
|
||||
Blob string // hex-encoded block template (160 hex chars = 80 bytes)
|
||||
JobID string // pool-assigned identifier
|
||||
|
|
|
|||
41
proxy.go
41
proxy.go
|
|
@ -17,11 +17,10 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
// p, result := proxy.New(cfg)
|
||||
// Proxy owns the servers, splitters, stats, workers, and monitoring API.
|
||||
//
|
||||
// if result.OK {
|
||||
// p.Start()
|
||||
// }
|
||||
// p, result := proxy.New(cfg)
|
||||
// if result.OK { p.Start() }
|
||||
type Proxy struct {
|
||||
config *Config
|
||||
splitter Splitter
|
||||
|
|
@ -44,6 +43,8 @@ type Proxy struct {
|
|||
submitCount atomic.Int64
|
||||
}
|
||||
|
||||
// Splitter is the shared interface implemented by the NiceHash and simple modes.
|
||||
//
|
||||
// type stubSplitter struct{}
|
||||
//
|
||||
// func (stubSplitter) Connect() {}
|
||||
|
|
@ -64,7 +65,9 @@ type Splitter interface {
|
|||
Upstreams() UpstreamStats
|
||||
}
|
||||
|
||||
// UpstreamStats{Active: 1, Sleep: 0, Error: 0, Total: 1}
|
||||
// UpstreamStats reports pool connection counts.
|
||||
//
|
||||
// stats := proxy.UpstreamStats{Active: 1, Sleep: 0, Error: 0, Total: 1}
|
||||
type UpstreamStats struct {
|
||||
Active uint64 // connections currently receiving jobs
|
||||
Sleep uint64 // idle connections (simple mode reuse pool)
|
||||
|
|
@ -72,12 +75,16 @@ type UpstreamStats struct {
|
|||
Total uint64 // Active + Sleep + Error
|
||||
}
|
||||
|
||||
// LoginEvent{Miner: miner}
|
||||
// LoginEvent is dispatched when a miner completes login.
|
||||
//
|
||||
// event := proxy.LoginEvent{Miner: miner}
|
||||
type LoginEvent struct {
|
||||
Miner *Miner
|
||||
}
|
||||
|
||||
// SubmitEvent{Miner: miner, JobID: "job-1", Nonce: "deadbeef", Result: "HASH", RequestID: 2}
|
||||
// SubmitEvent carries one miner share submission.
|
||||
//
|
||||
// event := proxy.SubmitEvent{Miner: miner, JobID: "job-1", Nonce: "deadbeef", Result: "HASH", RequestID: 2}
|
||||
type SubmitEvent struct {
|
||||
Miner *Miner
|
||||
JobID string
|
||||
|
|
@ -87,12 +94,16 @@ type SubmitEvent struct {
|
|||
RequestID int64
|
||||
}
|
||||
|
||||
// CloseEvent{Miner: miner}
|
||||
// CloseEvent is dispatched when a miner connection closes.
|
||||
//
|
||||
// event := proxy.CloseEvent{Miner: miner}
|
||||
type CloseEvent struct {
|
||||
Miner *Miner
|
||||
}
|
||||
|
||||
// NewConfigWatcher("config.json", func(cfg *Config) { p.Reload(cfg) })
|
||||
// ConfigWatcher polls a config file for changes.
|
||||
//
|
||||
// watcher := proxy.NewConfigWatcher("config.json", func(cfg *proxy.Config) { p.Reload(cfg) })
|
||||
type ConfigWatcher struct {
|
||||
path string
|
||||
onChange func(*Config)
|
||||
|
|
@ -100,7 +111,9 @@ type ConfigWatcher struct {
|
|||
done chan struct{}
|
||||
}
|
||||
|
||||
// limiter := NewRateLimiter(RateLimit{MaxConnectionsPerMinute: 30, BanDurationSeconds: 300})
|
||||
// RateLimiter throttles new connections per source IP.
|
||||
//
|
||||
// limiter := proxy.NewRateLimiter(proxy.RateLimit{MaxConnectionsPerMinute: 30, BanDurationSeconds: 300})
|
||||
// limiter.Allow("1.2.3.4:3333")
|
||||
type RateLimiter struct {
|
||||
config RateLimit
|
||||
|
|
@ -109,13 +122,17 @@ type RateLimiter struct {
|
|||
mu sync.Mutex
|
||||
}
|
||||
|
||||
// tokenBucket{tokens: 30, lastRefill: time.Now()}
|
||||
// tokenBucket is the per-IP refillable counter.
|
||||
//
|
||||
// bucket := tokenBucket{tokens: 30, lastRefill: time.Now()}
|
||||
type tokenBucket struct {
|
||||
tokens int
|
||||
lastRefill time.Time
|
||||
}
|
||||
|
||||
// resolver := NewCustomDiff(50000)
|
||||
// CustomDiff applies a login-time difficulty override.
|
||||
//
|
||||
// resolver := proxy.NewCustomDiff(50000)
|
||||
// resolver.Apply(&Miner{user: "WALLET+75000"})
|
||||
type CustomDiff struct {
|
||||
globalDiff uint64
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ import (
|
|||
|
||||
// Server listens on one BindAddr and creates a Miner for each accepted connection.
|
||||
//
|
||||
// srv, result := proxy.NewServer(bind, tlsCfg, rateLimiter, onAccept)
|
||||
// srv.Start()
|
||||
// srv, result := proxy.NewServer(bind, tlsCfg, rateLimiter, onAccept)
|
||||
// if result.OK { srv.Start() }
|
||||
type Server struct {
|
||||
addr BindAddr
|
||||
tlsCfg *tls.Config // nil for plain TCP
|
||||
|
|
|
|||
20
stats.go
20
stats.go
|
|
@ -6,9 +6,11 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
// stats := NewStats()
|
||||
// bus.Subscribe(EventAccept, stats.OnAccept)
|
||||
// bus.Subscribe(EventReject, stats.OnReject)
|
||||
// Stats tracks the proxy-wide counters and rolling hashrate windows.
|
||||
//
|
||||
// stats := proxy.NewStats()
|
||||
// bus.Subscribe(proxy.EventAccept, stats.OnAccept)
|
||||
// bus.Subscribe(proxy.EventReject, stats.OnReject)
|
||||
type Stats struct {
|
||||
accepted atomic.Uint64
|
||||
rejected atomic.Uint64
|
||||
|
|
@ -25,7 +27,9 @@ type Stats struct {
|
|||
mu sync.Mutex
|
||||
}
|
||||
|
||||
// HashrateWindow60s
|
||||
// HashrateWindow60s selects the 60-second hashrate window.
|
||||
//
|
||||
// proxy.HashrateWindow60s
|
||||
const (
|
||||
HashrateWindow60s = 0 // 1 minute
|
||||
HashrateWindow600s = 1 // 10 minutes
|
||||
|
|
@ -35,14 +39,18 @@ const (
|
|||
HashrateWindowAll = 5 // all-time (single accumulator, no window)
|
||||
)
|
||||
|
||||
// newTickWindow(60)
|
||||
// tickWindow is a fixed-capacity ring buffer of per-second difficulty totals.
|
||||
//
|
||||
// window := newTickWindow(60)
|
||||
type tickWindow struct {
|
||||
buckets []uint64
|
||||
pos int
|
||||
size int // window size in seconds = len(buckets)
|
||||
}
|
||||
|
||||
// NewStats().Summary()
|
||||
// StatsSummary is the serialisable snapshot returned by Stats.Summary().
|
||||
//
|
||||
// summary := proxy.NewStats().Summary()
|
||||
type StatsSummary struct {
|
||||
Accepted uint64 `json:"accepted"`
|
||||
Rejected uint64 `json:"rejected"`
|
||||
|
|
|
|||
|
|
@ -5,7 +5,9 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
// workers := NewWorkers(WorkersByRigID, bus)
|
||||
// Workers tracks per-identity aggregates derived from miner login fields.
|
||||
//
|
||||
// workers := proxy.NewWorkers(proxy.WorkersByRigID, bus)
|
||||
// records := workers.List()
|
||||
type Workers struct {
|
||||
mode WorkersMode
|
||||
|
|
@ -16,6 +18,8 @@ type Workers struct {
|
|||
mu sync.RWMutex
|
||||
}
|
||||
|
||||
// WorkerRecord is the aggregate row returned by Workers.List().
|
||||
//
|
||||
// record.Hashrate(60)
|
||||
type WorkerRecord struct {
|
||||
Name string
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue