feat(proxy): add UUID session ids and custom diff buckets
Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
parent
0d7c60726c
commit
0a195f7962
5 changed files with 110 additions and 13 deletions
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
53
worker.go
53
worker.go
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue