[Issue #707] Implement Byzantine-Resistant Quorum - #710
Conversation
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
Reviewer's GuideIntroduces a reputation-backed consensus mechanism where quorum decisions are weighted by node trust scores, implementing a ReputationStore for node reputation and a ConsensusEngine that uses those scores and per-vote confidence to evaluate quorum, along with unit tests and module wiring. Sequence diagram for EvaluateQuorum using ReputationStoresequenceDiagram
participant Arbiter
participant ConsensusEngine
participant ReputationStore
Arbiter->>ConsensusEngine: SubmitVote(vote)
ConsensusEngine-->>Arbiter: (ack)
Arbiter->>ConsensusEngine: EvaluateQuorum()
loop for each vote
ConsensusEngine->>ReputationStore: GetReputation(nodeID)
ReputationStore-->>ConsensusEngine: reputation
Note over ConsensusEngine: accumulate weightedTotal
end
ConsensusEngine-->>Arbiter: quorumReached(bool)
File-Level Changes
Assessment against linked issues
Possibly linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
Warning Rate limit exceeded
You’ve run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (6)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Hey - I've left some high level feedback:
- In
ConsensusEngine,EvaluateQuorumnever clears or time-boundsvotes, so decisions will accumulate all historical votes and the slice will grow unbounded; consider either resettingvotesafter evaluation or scoping them to a particular round/epoch. - The combination of
ReputationStore.GetReputationdefaulting to0andEvaluateQuorumtreatingrep == 0as a missing value (and forcing it to1.0) makes it impossible to distinguish unknown nodes from nodes explicitly driven to zero reputation; consider adding explicit defaults in the store or returning presence information so zero-rep can be meaningfully represented.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In `ConsensusEngine`, `EvaluateQuorum` never clears or time-bounds `votes`, so decisions will accumulate all historical votes and the slice will grow unbounded; consider either resetting `votes` after evaluation or scoping them to a particular round/epoch.
- The combination of `ReputationStore.GetReputation` defaulting to `0` and `EvaluateQuorum` treating `rep == 0` as a missing value (and forcing it to `1.0`) makes it impossible to distinguish unknown nodes from nodes explicitly driven to zero reputation; consider adding explicit defaults in the store or returning presence information so zero-rep can be meaningfully represented.Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
There was a problem hiding this comment.
Pull request overview
Implements a reputation-weighted quorum mechanism intended to make Nexus/Arbiter consensus more Byzantine-resistant by weighting votes based on node reputation and vote confidence.
Changes:
- Added a new
ReputationStorefor tracking per-node reputation. - Added a new
ConsensusEnginewith vote submission and quorum evaluation. - Added unit tests for both reputation tracking and quorum evaluation.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
phoenix_os/arbiter/go.mod |
Removes the module go directive; currently leaves the module without explicit Go version/deps. |
phoenix_os/arbiter/consensus.go |
Introduces the weighted quorum voting engine. |
phoenix_os/arbiter/consensus_test.go |
Adds a unit test for the quorum evaluation behavior. |
agents/internal/swarm/reputation.go |
Adds a reputation store for tracking node trust values. |
agents/internal/swarm/reputation_test.go |
Adds a unit test for the reputation store. |
agents/internal/swarm/go.mod |
Introduces a nested Go module for the new swarm reputation package. |
Comments suppressed due to low confidence (2)
phoenix_os/arbiter/go.mod:2
- Removing the
godirective from thisgo.modmakes the module’s language/version semantics implicit and inconsistent with the other Go modules in this repo (and with the rootgo.work’sgo 1.26). Re-add an explicitgoversion (matching the workspace/toolchain) to avoid surprising module behavior.
module phoenix/arbiter
phoenix_os/arbiter/go.mod:2
consensus.gointroduces a non-stdlib import, but thisgo.modcurrently has norequireentries. Even withgo.work, thearbitermodule will need arequireon the module that provides the imported package (with the workspace supplying the local replacement), otherwisego test/go buildwill report “no required module provides package …”.
module phoenix/arbiter
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| import ( | ||
| "sync" | ||
| "time" | ||
|
|
||
| "phoenix/agents/internal/swarm" | ||
| ) |
| if v.Decision { | ||
| weightedTotal += rep * v.Confidence | ||
| } | ||
| totalReputation += rep |
| func (e *ConsensusEngine) SubmitVote(v Vote) { | ||
| e.mu.Lock() | ||
| defer e.mu.Unlock() | ||
| e.votes = append(e.votes, v) | ||
| } |
| "phoenix/agents/internal/swarm" | ||
| "testing" | ||
| ) | ||
|
|
||
| func TestConsensusEngine(t *testing.T) { | ||
| rep := swarm.NewReputationStore() |
| func TestConsensusEngine(t *testing.T) { | ||
| rep := swarm.NewReputationStore() | ||
| rep.UpdateReputation("node1", 10.0) // High trust | ||
| rep.UpdateReputation("node2", 1.0) // Low trust | ||
|
|
||
| engine := NewConsensusEngine(rep, 0.5) | ||
|
|
||
| // High trust node votes true | ||
| engine.SubmitVote(Vote{"node1", true, 0.9}) | ||
| // Low trust node votes false | ||
| engine.SubmitVote(Vote{"node2", false, 0.9}) | ||
|
|
||
| if !engine.EvaluateQuorum() { | ||
| t.Error("Expected quorum to be true based on high trust node") | ||
| } | ||
| } |
| @@ -0,0 +1 @@ | |||
| module phoenix/swarm | |||
Problem
The Nexus lacks a mechanism to prevent swarm-wide self-DoS (Byzantine swarm poisoning) by compromised nodes.
Changes
Tests
Risk
Medium
Closes #707
Summary by Sourcery
Introduce a reputation-weighted consensus mechanism to harden swarm quorum decisions against compromised nodes.
New Features:
Tests: