feat(coordinator): quorum verification for untrusted (volunteer) results
Replaces the C1 quarantine with real verification. Trusted results (lab token, verified, or admin worker) are accepted directly as before. An untrusted worker's result is recorded as one vote per (task, owner) in a new task_results table; the task only completes once QUORUM_SIZE distinct owners submit the same result hash, otherwise it returns to the queue for another independent compute. - migration 0013 task_results (one vote per owner, quorum by result_sha256) - CompleteTask branches on worker trust; unknown worker defaults trusted (safe: completing needs the lease, whose owner is always a known registered worker) - claim drops the quarantine and excludes chunks the owner already voted on - domain Task.ReleaseAfterVote; QUORUM_SIZE config (default 2) - unit tests: trusted direct-complete, untrusted needs-quorum, can-claim Reducer and job done/total logic untouched — still one completed task per chunk.
This commit is contained in:
@@ -61,6 +61,9 @@ type Config struct {
|
||||
LeaseDuration time.Duration
|
||||
// Default attempt ceiling for newly created tasks.
|
||||
DefaultMaxAttempts int
|
||||
// How many distinct owners must agree on an untrusted result before it is
|
||||
// accepted (trusted workers are accepted directly).
|
||||
QuorumSize int
|
||||
// How often the background lease-reaper runs.
|
||||
ReaperInterval time.Duration
|
||||
// A worker silent for longer than this is marked offline by the reaper.
|
||||
@@ -103,6 +106,7 @@ func LoadConfig() (Config, error) {
|
||||
HeartbeatInterval: 15 * time.Second,
|
||||
LeaseDuration: 2 * time.Minute,
|
||||
DefaultMaxAttempts: 3,
|
||||
QuorumSize: 2,
|
||||
ReaperInterval: 30 * time.Second,
|
||||
WorkerOfflineAfter: 1 * time.Minute,
|
||||
}
|
||||
@@ -147,6 +151,12 @@ func LoadConfig() (Config, error) {
|
||||
if cfg.DefaultMaxAttempts, err = getEnvInt("DEFAULT_MAX_ATTEMPTS", cfg.DefaultMaxAttempts); err != nil {
|
||||
return Config{}, err
|
||||
}
|
||||
if cfg.QuorumSize, err = getEnvInt("QUORUM_SIZE", cfg.QuorumSize); err != nil {
|
||||
return Config{}, err
|
||||
}
|
||||
if cfg.QuorumSize < 1 {
|
||||
return Config{}, fmt.Errorf("QUORUM_SIZE must be positive")
|
||||
}
|
||||
if cfg.DefaultMaxAttempts < 1 {
|
||||
return Config{}, fmt.Errorf("DEFAULT_MAX_ATTEMPTS must be positive")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user