@@ -25,22 +25,25 @@ func (s *SBFT) testBacklog(m *Msg, src uint64) bool {
25
25
}
26
26
27
27
func (s * SBFT ) testBacklog2 (m * Msg , src uint64 ) bool {
28
- record := func (seq uint64 ) bool {
29
- if seq > s .cur .subject .Seq .Seq {
28
+ record := func (seq * SeqView ) bool {
29
+ if ! s .activeView {
30
+ return true
31
+ }
32
+ if seq .Seq > s .cur .subject .Seq .Seq || seq .View > s .seq .View {
30
33
return true
31
34
}
32
35
return false
33
36
}
34
37
35
- if pp := m .GetPreprepare (); pp != nil && ! s . cur . executed {
36
- return true
38
+ if pp := m .GetPreprepare (); pp != nil {
39
+ return record ( pp . Seq ) && ! s . cur . checkpointDone
37
40
} else if p := m .GetPrepare (); p != nil {
38
- return record (p .Seq . Seq )
41
+ return record (p .Seq )
39
42
} else if c := m .GetCommit (); c != nil {
40
- return record (c .Seq . Seq )
43
+ return record (c .Seq )
41
44
} else if cs := m .GetCheckpoint (); cs != nil {
42
45
c := & Checkpoint {}
43
- return record (c .Seq )
46
+ return record (& SeqView { Seq : c .Seq } )
44
47
}
45
48
return false
46
49
}
@@ -53,22 +56,19 @@ func (s *SBFT) recordBacklogMsg(m *Msg, src uint64) {
53
56
//
54
57
// Prevent DoS by limiting the number of messages per replica.
55
58
//
56
- // If the backlog limit is exceeded, discard all messages with
57
- // Seq before the replica's hello message (we can, because we
58
- // can play forward to this batch via state transfer). If
59
- // there is no hello message, we must be really slow or the
60
- // replica must be byzantine. In this case we probably should
61
- // re-establish the connection.
59
+ // If the backlog limit is exceeded, re-establish the
60
+ // connection.
62
61
//
63
62
// After the connection has been re-established, we will
64
- // receive a hello, and the following messages will trigger
65
- // the pruning of old messages. If this pruning lead us not
66
- // to make progress, the backlog processing algorithm as lined
67
- // out below will take care of starting a state transfer,
68
- // using the hello message we received on reconnect.
63
+ // receive a hello, which will advance our state and discard
64
+ // old messages.
69
65
s .replicaState [src ].backLog = append (s .replicaState [src ].backLog , m )
70
66
}
71
67
68
+ func (s * SBFT ) discardBacklog (src uint64 ) {
69
+ s .replicaState [src ].backLog = nil
70
+ }
71
+
72
72
func (s * SBFT ) processBacklog () {
73
73
processed := true
74
74
notReady := uint64 (0 )
@@ -111,18 +111,6 @@ func (s *SBFT) processBacklog() {
111
111
// we should reconnect to get a working connection going
112
112
// again.
113
113
//
114
- // If a noFaultyQuorum (-1, because we're not faulty, just
115
- // were disconnected) is backlogged, we know that we need to
116
- // perform a state transfer. Of course, f of these might be
117
- // byzantine, and the remaining f that are not backlogged will
118
- // allow us to get unstuck. To check against that, we need to
119
- // only consider backlogged replicas of which we have a hello
120
- // message that talks about a future Seq.
121
- //
122
- // We need to pick the highest Seq of all the hello messages
123
- // we received, perform a state transfer to that Batch, and
124
- // discard all backlogged messages that refer to a lower Seq.
125
- //
126
114
// Do we need to detect that a connection is stuck and we
127
115
// should reconnect?
128
116
}
0 commit comments