Add erasure-coded multi-lane spread foundation.
Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled
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:
82
agent/deploy/erasure_codec.go
Normal file
82
agent/deploy/erasure_codec.go
Normal file
@@ -0,0 +1,82 @@
|
||||
package deploy
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
|
||||
"github.com/klauspost/reedsolomon"
|
||||
)
|
||||
|
||||
const (
|
||||
erasureSchemeReedSolomonV1 = "reed_solomon_v1"
|
||||
erasureDefaultDataShards = 4
|
||||
erasureDefaultParityShards = 2
|
||||
)
|
||||
|
||||
type erasureParams struct {
|
||||
DataShards int
|
||||
ParityShards int
|
||||
}
|
||||
|
||||
func (p erasureParams) normalize() (erasureParams, error) {
|
||||
if p.DataShards <= 0 {
|
||||
p.DataShards = erasureDefaultDataShards
|
||||
}
|
||||
if p.ParityShards <= 0 {
|
||||
p.ParityShards = erasureDefaultParityShards
|
||||
}
|
||||
if p.DataShards < 1 || p.ParityShards < 1 {
|
||||
return erasureParams{}, fmt.Errorf("erasure: invalid shard counts")
|
||||
}
|
||||
return p, nil
|
||||
}
|
||||
|
||||
func (p erasureParams) minShards() int {
|
||||
return p.DataShards
|
||||
}
|
||||
|
||||
func (p erasureParams) totalShards() int {
|
||||
return p.DataShards + p.ParityShards
|
||||
}
|
||||
|
||||
// decodeErasureShards reconstructs payload from Reed–Solomon shards (nil = missing).
|
||||
func decodeErasureShards(shards [][]byte, payloadSize int, p erasureParams) ([]byte, error) {
|
||||
p, err := p.normalize()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(shards) < p.totalShards() {
|
||||
return nil, fmt.Errorf("erasure: shard slice too short")
|
||||
}
|
||||
present := 0
|
||||
for i := 0; i < p.totalShards(); i++ {
|
||||
if len(shards[i]) > 0 {
|
||||
present++
|
||||
}
|
||||
}
|
||||
if present < p.minShards() {
|
||||
return nil, fmt.Errorf("erasure: need %d shards, have %d", p.minShards(), present)
|
||||
}
|
||||
enc, err := reedsolomon.New(p.DataShards, p.ParityShards)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := enc.Reconstruct(shards); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ok, err := enc.Verify(shards)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("erasure: verification failed")
|
||||
}
|
||||
if payloadSize <= 0 {
|
||||
payloadSize = len(shards[0]) * p.DataShards
|
||||
}
|
||||
var out bytes.Buffer
|
||||
if err := enc.Join(&out, shards, payloadSize); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out.Bytes(), nil
|
||||
}
|
||||
Reference in New Issue
Block a user