Skip to content

Commit

Permalink
Merge pull request #5817 from multiversx/fix_multikey_invalid_signers
Browse files Browse the repository at this point in the history
Fix invalid signers message broadcast on multikey
  • Loading branch information
sstanculeanu authored Jan 16, 2024
2 parents a7707af + d5d23aa commit 0e20091
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 22 deletions.
17 changes: 14 additions & 3 deletions consensus/spos/bls/subroundEndRound.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ func (sr *subroundEndRound) receivedInvalidSignersInfo(_ context.Context, cnsDta
return false
}

if sr.IsSelfLeaderInCurrentRound() {
if sr.IsSelfLeaderInCurrentRound() || sr.IsMultiKeyLeaderInCurrentRound() {
return false
}

Expand Down Expand Up @@ -589,20 +589,31 @@ func (sr *subroundEndRound) createAndBroadcastHeaderFinalInfo() {
}

func (sr *subroundEndRound) createAndBroadcastInvalidSigners(invalidSigners []byte) {
isSelfLeader := sr.IsSelfLeaderInCurrentRound() && sr.ShouldConsiderSelfKeyInConsensus()
if !(isSelfLeader || sr.IsMultiKeyLeaderInCurrentRound()) {
return
}

leader, errGetLeader := sr.GetLeader()
if errGetLeader != nil {
log.Debug("createAndBroadcastInvalidSigners.GetLeader", "error", errGetLeader)
return

Check warning on line 600 in consensus/spos/bls/subroundEndRound.go

View check run for this annotation

Codecov / codecov/patch

consensus/spos/bls/subroundEndRound.go#L599-L600

Added lines #L599 - L600 were not covered by tests
}

cnsMsg := consensus.NewConsensusMessage(
sr.GetData(),
nil,
nil,
nil,
[]byte(sr.SelfPubKey()),
[]byte(leader),
nil,
int(MtInvalidSigners),
sr.RoundHandler().Index(),
sr.ChainID(),
nil,
nil,
nil,
sr.CurrentPid(),
sr.GetAssociatedPid([]byte(leader)),
invalidSigners,
)

Expand Down
116 changes: 97 additions & 19 deletions consensus/spos/bls/subroundEndRound_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1322,7 +1322,7 @@ func TestSubroundEndRound_ReceivedInvalidSignersInfo(t *testing.T) {
assert.False(t, res)
})

t.Run("received message for self leader", func(t *testing.T) {
t.Run("received message from self leader should return false", func(t *testing.T) {
t.Parallel()

container := mock.InitConsensusCore()
Expand All @@ -1339,6 +1339,53 @@ func TestSubroundEndRound_ReceivedInvalidSignersInfo(t *testing.T) {
assert.False(t, res)
})

t.Run("received message from self multikey leader should return false", func(t *testing.T) {
t.Parallel()

container := mock.InitConsensusCore()
keysHandler := &testscommon.KeysHandlerStub{
IsKeyManagedByCurrentNodeCalled: func(pkBytes []byte) bool {
return string(pkBytes) == "A"
},
}
ch := make(chan bool, 1)
consensusState := initConsensusStateWithKeysHandler(keysHandler)
sr, _ := spos.NewSubround(
bls.SrSignature,
bls.SrEndRound,
-1,
int64(85*roundTimeDuration/100),
int64(95*roundTimeDuration/100),
"(END_ROUND)",
consensusState,
ch,
executeStoredMessages,
container,
chainID,
currentPid,
&statusHandler.AppStatusHandlerStub{},
)

srEndRound, _ := bls.NewSubroundEndRound(
sr,
extend,
bls.ProcessingThresholdPercent,
displayStatistics,
&statusHandler.AppStatusHandlerStub{},
&mock.SentSignatureTrackerStub{},
)

srEndRound.SetSelfPubKey("A")

cnsData := consensus.Message{
BlockHeaderHash: []byte("X"),
PubKey: []byte("A"),
}

res := srEndRound.ReceivedInvalidSignersInfo(&cnsData)
assert.False(t, res)
})

t.Run("received hash does not match the hash from current consensus state", func(t *testing.T) {
t.Parallel()

Expand Down Expand Up @@ -1556,29 +1603,60 @@ func TestVerifyInvalidSigners(t *testing.T) {
func TestSubroundEndRound_CreateAndBroadcastInvalidSigners(t *testing.T) {
t.Parallel()

wg := &sync.WaitGroup{}
wg.Add(1)
t.Run("redundancy node should not send while main is active", func(t *testing.T) {
t.Parallel()

expectedInvalidSigners := []byte("invalid signers")
expectedInvalidSigners := []byte("invalid signers")

wasCalled := false
container := mock.InitConsensusCore()
messenger := &mock.BroadcastMessengerMock{
BroadcastConsensusMessageCalled: func(message *consensus.Message) error {
wg.Done()
assert.Equal(t, expectedInvalidSigners, message.InvalidSigners)
wasCalled = true
return nil
},
}
container.SetBroadcastMessenger(messenger)
sr := *initSubroundEndRoundWithContainer(container, &statusHandler.AppStatusHandlerStub{})
container := mock.InitConsensusCore()
nodeRedundancy := &mock.NodeRedundancyHandlerStub{
IsRedundancyNodeCalled: func() bool {
return true
},
IsMainMachineActiveCalled: func() bool {
return true
},
}
container.SetNodeRedundancyHandler(nodeRedundancy)
messenger := &mock.BroadcastMessengerMock{
BroadcastConsensusMessageCalled: func(message *consensus.Message) error {
assert.Fail(t, "should have not been called")
return nil
},
}
container.SetBroadcastMessenger(messenger)
sr := *initSubroundEndRoundWithContainer(container, &statusHandler.AppStatusHandlerStub{})

sr.CreateAndBroadcastInvalidSigners(expectedInvalidSigners)
sr.CreateAndBroadcastInvalidSigners(expectedInvalidSigners)
})
t.Run("should work", func(t *testing.T) {
t.Parallel()

wg.Wait()
wg := &sync.WaitGroup{}
wg.Add(1)

require.True(t, wasCalled)
expectedInvalidSigners := []byte("invalid signers")

wasCalled := false
container := mock.InitConsensusCore()
messenger := &mock.BroadcastMessengerMock{
BroadcastConsensusMessageCalled: func(message *consensus.Message) error {
assert.Equal(t, expectedInvalidSigners, message.InvalidSigners)
wasCalled = true
wg.Done()
return nil
},
}
container.SetBroadcastMessenger(messenger)
sr := *initSubroundEndRoundWithContainer(container, &statusHandler.AppStatusHandlerStub{})
sr.SetSelfPubKey("A")

sr.CreateAndBroadcastInvalidSigners(expectedInvalidSigners)

wg.Wait()

require.True(t, wasCalled)
})
}

func TestGetFullMessagesForInvalidSigners(t *testing.T) {
Expand Down

0 comments on commit 0e20091

Please sign in to comment.