Skip to content

Commit 9dfa0d5

Browse files
authored
fix: Strict raft state (#3167)
* Strict raft state * Changelog
1 parent eabde1a commit 9dfa0d5

3 files changed

Lines changed: 59 additions & 2 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1212
### Fixed
1313

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

1617
## v1.0.0
1718

pkg/raft/types.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ type RaftBlockState = pb.RaftBlockState
1111

1212
// assertValid checks basic constraints but does not ensure that no gaps exist or chain continuity
1313
func assertValid(s *RaftBlockState, next *RaftBlockState) error {
14-
if s.Height > next.Height {
14+
if s.Height >= next.Height {
1515
return fmt.Errorf("invalid height: %d > %d", s.Height, next.Height)
1616
}
17-
if s.Timestamp > next.Timestamp {
17+
if s.Timestamp >= next.Timestamp {
1818
return fmt.Errorf("invalid timestamp: %d > %d", s.Timestamp, next.Timestamp)
1919
}
2020
return nil

pkg/raft/types_test.go

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package raft
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/require"
7+
)
8+
9+
func TestAssertValid(t *testing.T) {
10+
specs := map[string]struct {
11+
s *RaftBlockState
12+
next *RaftBlockState
13+
expErr bool
14+
}{
15+
"ok": {
16+
s: &RaftBlockState{Height: 10, Timestamp: 100},
17+
next: &RaftBlockState{Height: 11, Timestamp: 101},
18+
},
19+
"all equal": {
20+
s: &RaftBlockState{Height: 10, Timestamp: 100},
21+
next: &RaftBlockState{Height: 10, Timestamp: 100},
22+
expErr: true,
23+
},
24+
"equal height": {
25+
s: &RaftBlockState{Height: 10, Timestamp: 100},
26+
next: &RaftBlockState{Height: 10, Timestamp: 101},
27+
expErr: true,
28+
},
29+
"equal timestamp": {
30+
s: &RaftBlockState{Height: 10, Timestamp: 100},
31+
next: &RaftBlockState{Height: 11, Timestamp: 100},
32+
expErr: true,
33+
},
34+
"lower timestamp": {
35+
s: &RaftBlockState{Height: 10, Timestamp: 101},
36+
next: &RaftBlockState{Height: 11, Timestamp: 100},
37+
expErr: true,
38+
},
39+
"lower height": {
40+
s: &RaftBlockState{Height: 11, Timestamp: 100},
41+
next: &RaftBlockState{Height: 10, Timestamp: 101},
42+
expErr: true,
43+
},
44+
}
45+
46+
for name, spec := range specs {
47+
t.Run(name, func(t *testing.T) {
48+
err := assertValid(spec.s, spec.next)
49+
if spec.expErr {
50+
require.Error(t, err)
51+
return
52+
}
53+
require.NoError(t, err)
54+
})
55+
}
56+
}

0 commit comments

Comments
 (0)