Skip to content

Commit d0f5a05

Browse files
authored
Skip messages from the wrong instance instead of returning an error (#442)
* Skip messages from the wrong instance instead of returning an error Due to async message delivery, we'll frequently get messages from the wrong instance. Log (trace) and drop them. Part of #421. * fix test
1 parent 0304756 commit d0f5a05

File tree

2 files changed

+24
-8
lines changed

2 files changed

+24
-8
lines changed

gpbft/participant.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,8 +161,9 @@ func (p *Participant) ReceiveMessage(vmsg ValidatedMessage) (err error) {
161161

162162
// Drop messages for past instances.
163163
if msg.Vote.Instance < p.currentInstance {
164-
return fmt.Errorf("message %d, current instance %d: %w",
165-
msg.Vote.Instance, p.currentInstance, ErrValidationTooOld)
164+
p.tracer.Log("dropping message from old instance %d while received in instance %d",
165+
msg.Vote.Instance, p.currentInstance)
166+
return nil
166167
}
167168

168169
// If the message is for the current instance, deliver immediately.

gpbft/participant_test.go

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ type participantTestSubject struct {
3737
beacon []byte
3838
time time.Time
3939
delta time.Duration
40+
trace []string
4041
}
4142

4243
func newParticipantTestSubject(t *testing.T, seed int64, instance uint64) *participantTestSubject {
@@ -50,7 +51,7 @@ func newParticipantTestSubject(t *testing.T, seed int64, instance uint64) *parti
5051
)
5152

5253
rng := rand.New(rand.NewSource(seed))
53-
subject := participantTestSubject{
54+
subject := &participantTestSubject{
5455
t: t,
5556
rng: rng,
5657
id: gpbft.ActorID(rng.Uint64()),
@@ -77,11 +78,16 @@ func newParticipantTestSubject(t *testing.T, seed int64, instance uint64) *parti
7778

7879
subject.host = gpbft.NewMockHost(t)
7980
subject.Participant, err = gpbft.NewParticipant(subject.host,
81+
gpbft.WithTracer(subject),
8082
gpbft.WithDelta(delta),
8183
gpbft.WithDeltaBackOffExponent(deltaBackOffExponent))
8284
require.NoError(t, err)
8385
subject.requireNotStarted()
84-
return &subject
86+
return subject
87+
}
88+
89+
func (pt *participantTestSubject) Log(format string, args ...any) {
90+
pt.trace = append(pt.trace, fmt.Sprintf(format, args...))
8591
}
8692

8793
func (pt *participantTestSubject) expectBeginInstance() {
@@ -346,9 +352,10 @@ func TestParticipant(t *testing.T) {
346352
t.Run("on ReceiveMessage", func(t *testing.T) {
347353
const initialInstance = 47
348354
tests := []struct {
349-
name string
350-
message func(subject *participantTestSubject) *gpbft.GMessage
351-
wantErr string
355+
name string
356+
message func(subject *participantTestSubject) *gpbft.GMessage
357+
wantErr string
358+
wantTrace string
352359
}{
353360
{
354361
name: "prior instance message is dropped",
@@ -357,7 +364,7 @@ func TestParticipant(t *testing.T) {
357364
Vote: gpbft.Payload{Instance: initialInstance - 1},
358365
}
359366
},
360-
wantErr: "message is for prior instance",
367+
wantTrace: "dropping message from old instance",
361368
},
362369
{
363370
name: "current instance message with unexpected base is rejected",
@@ -441,6 +448,14 @@ func TestParticipant(t *testing.T) {
441448
} else {
442449
require.ErrorContains(t, gotErr, test.wantErr)
443450
}
451+
if test.wantTrace != "" {
452+
var found bool
453+
for _, msg := range subject.trace {
454+
require.Contains(t, msg, test.wantTrace)
455+
found = true
456+
}
457+
require.True(t, found, "trace %s not found", test.wantTrace)
458+
}
444459
})
445460
}
446461
})

0 commit comments

Comments
 (0)