Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed

- Fix race on startup sync. [#3162](https://github.com/evstack/ev-node/pull/3162)
- Strict raft state. [#3167](https://github.com/evstack/ev-node/pull/3167)

## v1.0.0

Expand Down
4 changes: 2 additions & 2 deletions pkg/raft/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ type RaftBlockState = pb.RaftBlockState

// assertValid checks basic constraints but does not ensure that no gaps exist or chain continuity
func assertValid(s *RaftBlockState, next *RaftBlockState) error {
if s.Height > next.Height {
if s.Height >= next.Height {
return fmt.Errorf("invalid height: %d > %d", s.Height, next.Height)
}
if s.Timestamp > next.Timestamp {
if s.Timestamp >= next.Timestamp {
return fmt.Errorf("invalid timestamp: %d > %d", s.Timestamp, next.Timestamp)
Comment on lines +14 to 18
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Error messages are misleading for equality cases.

The conditions now use >= to reject equal values, but the error messages still show >. When s.Height == next.Height, the message "invalid height: 10 > 10" is confusing because 10 is not greater than 10.

Proposed fix to clarify error messages
 func assertValid(s *RaftBlockState, next *RaftBlockState) error {
 	if s.Height >= next.Height {
-		return fmt.Errorf("invalid height: %d > %d", s.Height, next.Height)
+		return fmt.Errorf("invalid height: current %d >= next %d", s.Height, next.Height)
 	}
 	if s.Timestamp >= next.Timestamp {
-		return fmt.Errorf("invalid timestamp: %d > %d", s.Timestamp, next.Timestamp)
+		return fmt.Errorf("invalid timestamp: current %d >= next %d", s.Timestamp, next.Timestamp)
 	}
 	return nil
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if s.Height >= next.Height {
return fmt.Errorf("invalid height: %d > %d", s.Height, next.Height)
}
if s.Timestamp > next.Timestamp {
if s.Timestamp >= next.Timestamp {
return fmt.Errorf("invalid timestamp: %d > %d", s.Timestamp, next.Timestamp)
if s.Height >= next.Height {
return fmt.Errorf("invalid height: current %d >= next %d", s.Height, next.Height)
}
if s.Timestamp >= next.Timestamp {
return fmt.Errorf("invalid timestamp: current %d >= next %d", s.Timestamp, next.Timestamp)
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/raft/types.go` around lines 14 - 18, The error messages are misleading
because the checks use >= but the messages say '>' for s.Height/next.Height and
s.Timestamp/next.Timestamp; update the fmt.Errorf strings in the comparisons
that use s.Height >= next.Height and s.Timestamp >= next.Timestamp to reflect >=
(e.g. "invalid height: %d >= %d" and "invalid timestamp: %d >= %d") or use
wording like "not less than" so the message accurately matches the condition for
the symbols s.Height, next.Height, s.Timestamp and next.Timestamp.

}
return nil
Expand Down
56 changes: 56 additions & 0 deletions pkg/raft/types_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package raft

import (
"testing"

"github.com/stretchr/testify/require"
)

func TestAssertValid(t *testing.T) {
specs := map[string]struct {
s *RaftBlockState
next *RaftBlockState
expErr bool
}{
"ok": {
s: &RaftBlockState{Height: 10, Timestamp: 100},
next: &RaftBlockState{Height: 11, Timestamp: 101},
},
"all equal": {
s: &RaftBlockState{Height: 10, Timestamp: 100},
next: &RaftBlockState{Height: 10, Timestamp: 100},
expErr: true,
},
"equal height": {
s: &RaftBlockState{Height: 10, Timestamp: 100},
next: &RaftBlockState{Height: 10, Timestamp: 101},
expErr: true,
},
"equal timestamp": {
s: &RaftBlockState{Height: 10, Timestamp: 100},
next: &RaftBlockState{Height: 11, Timestamp: 100},
expErr: true,
},
"lower timestamp": {
s: &RaftBlockState{Height: 10, Timestamp: 101},
next: &RaftBlockState{Height: 11, Timestamp: 100},
expErr: true,
},
"lower height": {
s: &RaftBlockState{Height: 11, Timestamp: 100},
next: &RaftBlockState{Height: 10, Timestamp: 101},
expErr: true,
},
}

for name, spec := range specs {
t.Run(name, func(t *testing.T) {
err := assertValid(spec.s, spec.next)
if spec.expErr {
require.Error(t, err)
return
}
require.NoError(t, err)
})
}
}
Loading