Go-ibft ignores some future messages (#67)

* Go-ibft ignores some future messages

* Additional test case (same height, lower message round)

* Test for greater height and lower round added

---------

Co-authored-by: Stefan Negovanović <stefan@ethernal.tech>
pull/68/head v0.4.0
Stana Miric 2 years ago committed by GitHub
parent ec72c80bc6
commit 72a09919e6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 24
      core/ibft.go
  2. 84
      core/ibft_test.go

@ -1074,12 +1074,16 @@ func (i *IBFT) AddMessage(message *proto.Message) {
if i.isAcceptableMessage(message) { if i.isAcceptableMessage(message) {
i.messages.AddMessage(message) i.messages.AddMessage(message)
msgs := i.messages.GetValidMessages( // Signal event if the quorum is reached. Since the subscriptions refer to the state height,
message.View, // no need to call this if the message height is not equal to the state height
message.Type, if message.View.Height == i.state.getHeight() {
func(_ *proto.Message) bool { return true }) msgs := i.messages.GetValidMessages(
if i.backend.HasQuorum(message.View.Height, msgs, message.Type) { message.View,
i.messages.SignalEvent(message) message.Type,
func(_ *proto.Message) bool { return true })
if i.backend.HasQuorum(message.View.Height, msgs, message.Type) {
i.messages.SignalEvent(message)
}
} }
} }
} }
@ -1102,8 +1106,12 @@ func (i *IBFT) isAcceptableMessage(message *proto.Message) bool {
return false return false
} }
// Make sure the message round is >= the current state round // Make sure if the heights are the same, the message round is >= the current state round
return message.View.Round >= i.state.getRound() if i.state.getHeight() == message.View.Height {
return message.View.Round >= i.state.getRound()
}
return true
} }
// ExtendRoundTimeout extends each round's timer by the specified amount. // ExtendRoundTimeout extends each round's timer by the specified amount.

@ -1117,54 +1117,80 @@ func TestIBFT_IsAcceptableMessage(t *testing.T) {
testTable := []struct { testTable := []struct {
name string name string
view *proto.View msgView *proto.View
currentView *proto.View stateView *proto.View
invalidSender bool invalidSender bool
acceptable bool acceptable bool
}{ }{
{ {
"invalid sender", name: "invalid sender",
nil, msgView: nil,
baseView, stateView: baseView,
true, invalidSender: true,
false, acceptable: false,
}, },
{ {
"malformed message", name: "malformed message",
nil, msgView: nil,
baseView, stateView: baseView,
false, invalidSender: false,
false, acceptable: false,
}, },
{ {
"higher height number", name: "higher height, same round number",
&proto.View{ msgView: &proto.View{
Height: baseView.Height + 100, Height: baseView.Height + 100,
Round: baseView.Round, Round: baseView.Round,
}, },
baseView, stateView: baseView,
false, invalidSender: false,
true, acceptable: true,
}, },
{ {
"higher round number", name: "higher height, lower round number",
&proto.View{ msgView: &proto.View{
Height: baseView.Height + 100,
Round: baseView.Round,
},
stateView: &proto.View{
Height: baseView.Height, Height: baseView.Height,
Round: baseView.Round + 1, Round: baseView.Round + 1,
}, },
baseView, invalidSender: false,
false, acceptable: true,
true,
}, },
{ {
"lower height number", name: "same heights, higher round number",
baseView, msgView: &proto.View{
&proto.View{ Height: baseView.Height,
Round: baseView.Round + 1,
},
stateView: baseView,
invalidSender: false,
acceptable: true,
},
{
name: "same heights, lower round number",
msgView: &proto.View{
Height: baseView.Height,
Round: baseView.Round + 1,
},
stateView: &proto.View{
Height: baseView.Height,
Round: baseView.Round + 2,
},
invalidSender: false,
acceptable: false,
},
{
name: "lower height number",
msgView: baseView,
stateView: &proto.View{
Height: baseView.Height + 1, Height: baseView.Height + 1,
Round: baseView.Round, Round: baseView.Round,
}, },
false, invalidSender: false,
false, acceptable: false,
}, },
} }
@ -1184,10 +1210,10 @@ func TestIBFT_IsAcceptableMessage(t *testing.T) {
} }
) )
i := NewIBFT(log, backend, transport) i := NewIBFT(log, backend, transport)
i.state.view = testCase.currentView i.state.view = testCase.stateView
message := &proto.Message{ message := &proto.Message{
View: testCase.view, View: testCase.msgView,
} }
assert.Equal(t, testCase.acceptable, i.isAcceptableMessage(message)) assert.Equal(t, testCase.acceptable, i.isAcceptableMessage(message))

Loading…
Cancel
Save