feat(proxy): add UUID session ids and custom diff buckets

Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
Virgil 2026-04-04 11:53:03 +00:00
parent 0d7c60726c
commit 0a195f7962
5 changed files with 110 additions and 13 deletions

View file

@ -397,7 +397,20 @@ func (m *Miner) Expire() {
func newRPCID() string {
value := make([]byte, 16)
_, _ = rand.Read(value)
return hex.EncodeToString(value)
value[6] = (value[6] & 0x0f) | 0x40
value[8] = (value[8] & 0x3f) | 0x80
encoded := make([]byte, 36)
hex.Encode(encoded[0:8], value[0:4])
encoded[8] = '-'
hex.Encode(encoded[9:13], value[4:6])
encoded[13] = '-'
hex.Encode(encoded[14:18], value[6:8])
encoded[18] = '-'
hex.Encode(encoded[19:23], value[8:10])
encoded[23] = '-'
hex.Encode(encoded[24:36], value[10:16])
return string(encoded)
}
func (m *Miner) RemoteAddr() net.Addr {

View file

@ -4,6 +4,7 @@ import (
"bufio"
"encoding/json"
"net"
"strings"
"testing"
"time"
)
@ -46,7 +47,8 @@ func TestMiner_Login_Good(t *testing.T) {
}
result := response["result"].(map[string]interface{})
if result["status"] != "OK" || result["id"] == "" {
id, _ := result["id"].(string)
if result["status"] != "OK" || len(id) != 36 || id[8] != '-' || id[13] != '-' || id[18] != '-' || id[23] != '-' || id[14] != '4' || !strings.ContainsAny(string(id[19]), "89ab") {
t.Fatalf("unexpected login response: %#v", response)
}
}

View file

@ -24,6 +24,7 @@ func New(cfg *Config) (*Proxy, error) {
customDiff := NewCustomDiff(cfg.CustomDiff)
events.Subscribe(EventLogin, customDiff.OnLogin)
workers := NewWorkers(cfg.Workers, events)
workers.SetCustomDiffStats(cfg.CustomDiffStats)
splitter := newSplitter(cfg, events)
proxyValue := &Proxy{
@ -229,6 +230,9 @@ func (p *Proxy) Reload(cfg *Config) {
if p.customDiff != nil {
p.customDiff.SetGlobalDiff(p.config.CustomDiff)
}
if p.workers != nil {
p.workers.SetCustomDiffStats(p.config.CustomDiffStats)
}
if p.rateLimiter != nil {
p.rateLimiter.SetConfig(p.config.RateLimit)
}

View file

@ -92,3 +92,50 @@ func TestWorkers_List_Ugly(t *testing.T) {
t.Fatalf("unexpected worker records: %+v", records)
}
}
func TestWorkers_CustomDiffStats_Good(t *testing.T) {
bus := NewEventBus()
workers := NewWorkers(WorkersByUser, bus)
workers.SetCustomDiffStats(true)
firstMiner := &Miner{id: 1, user: "wallet", customDiff: 1000}
secondMiner := &Miner{id: 2, user: "wallet", customDiff: 2000}
bus.Dispatch(Event{Type: EventLogin, Miner: firstMiner})
bus.Dispatch(Event{Type: EventLogin, Miner: secondMiner})
records := workers.List()
if len(records) != 2 || records[0].Name == records[1].Name {
t.Fatalf("expected separate custom-diff buckets, got %+v", records)
}
}
func TestWorkers_CustomDiffStats_Bad(t *testing.T) {
bus := NewEventBus()
workers := NewWorkers(WorkersByUser, bus)
workers.SetCustomDiffStats(true)
firstMiner := &Miner{id: 1, user: "wallet", customDiff: 1000}
secondMiner := &Miner{id: 2, user: "wallet", customDiff: 1000}
bus.Dispatch(Event{Type: EventLogin, Miner: firstMiner})
bus.Dispatch(Event{Type: EventLogin, Miner: secondMiner})
records := workers.List()
if len(records) != 1 {
t.Fatalf("expected identical custom-diff bucket to merge, got %+v", records)
}
}
func TestWorkers_CustomDiffStats_Ugly(t *testing.T) {
bus := NewEventBus()
workers := NewWorkers(WorkersByUser, bus)
firstMiner := &Miner{id: 1, user: "wallet", customDiff: 1000}
secondMiner := &Miner{id: 2, user: "wallet", customDiff: 2000}
bus.Dispatch(Event{Type: EventLogin, Miner: firstMiner})
bus.Dispatch(Event{Type: EventLogin, Miner: secondMiner})
records := workers.List()
if len(records) != 1 || records[0].Name != "wallet" {
t.Fatalf("expected default worker bucketing to ignore custom diff, got %+v", records)
}
}

View file

@ -1,6 +1,7 @@
package proxy
import (
"strconv"
"sync"
"time"
)
@ -10,11 +11,12 @@ import (
//
// w := proxy.NewWorkers(proxy.WorkersByRigID, bus)
type Workers struct {
mode WorkersMode
entries []WorkerRecord // ordered by first-seen (stable)
nameIndex map[string]int // workerName → entries index
idIndex map[int64]int // minerID → entries index
mu sync.RWMutex
mode WorkersMode
customDiffStats bool
entries []WorkerRecord // ordered by first-seen (stable)
nameIndex map[string]int // workerName → entries index
idIndex map[int64]int // minerID → entries index
mu sync.RWMutex
}
// WorkerRecord is the per-identity aggregate.
@ -66,6 +68,19 @@ func NewWorkers(mode WorkersMode, bus *EventBus) *Workers {
return workers
}
// SetCustomDiffStats toggles per-custom-difficulty worker bucketing.
//
// workers.SetCustomDiffStats(true)
func (w *Workers) SetCustomDiffStats(enabled bool) {
if w == nil {
return
}
w.mu.Lock()
w.customDiffStats = enabled
w.mu.Unlock()
}
// List returns a snapshot of all worker records in first-seen order.
//
// records := workers.List()
@ -186,21 +201,37 @@ func (w *Workers) updateShare(event Event, accepted bool) {
}
func (w *Workers) workerName(miner *Miner) string {
if miner == nil {
return ""
}
w.mu.RLock()
customDiffStats := w.customDiffStats
w.mu.RUnlock()
name := ""
switch w.mode {
case WorkersByRigID:
if miner.RigID() != "" {
return miner.RigID()
name = miner.RigID()
} else {
name = miner.User()
}
return miner.User()
case WorkersByUser:
return miner.User()
name = miner.User()
case WorkersByPass:
return miner.Password()
name = miner.Password()
case WorkersByAgent:
return miner.Agent()
name = miner.Agent()
case WorkersByIP:
return miner.IP()
name = miner.IP()
default:
return ""
}
if !customDiffStats || miner.CustomDiff() == 0 || name == "" {
return name
}
return name + "+cd" + strconv.FormatUint(miner.CustomDiff(), 10)
}