diff --git a/consensus/spos/bls/subroundEndRound.go b/consensus/spos/bls/subroundEndRound.go index 723fc0bcbf3..26c845511b5 100644 --- a/consensus/spos/bls/subroundEndRound.go +++ b/consensus/spos/bls/subroundEndRound.go @@ -189,7 +189,7 @@ func (sr *subroundEndRound) receivedInvalidSignersInfo(_ context.Context, cnsDta return false } - if sr.IsSelfLeaderInCurrentRound() { + if sr.IsSelfLeaderInCurrentRound() || sr.IsMultiKeyLeaderInCurrentRound() { return false } @@ -589,12 +589,23 @@ 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 + } + cnsMsg := consensus.NewConsensusMessage( sr.GetData(), nil, nil, nil, - []byte(sr.SelfPubKey()), + []byte(leader), nil, int(MtInvalidSigners), sr.RoundHandler().Index(), @@ -602,7 +613,7 @@ func (sr *subroundEndRound) createAndBroadcastInvalidSigners(invalidSigners []by nil, nil, nil, - sr.CurrentPid(), + sr.GetAssociatedPid([]byte(leader)), invalidSigners, ) diff --git a/consensus/spos/bls/subroundEndRound_test.go b/consensus/spos/bls/subroundEndRound_test.go index 456277e23fc..b6556b8ad70 100644 --- a/consensus/spos/bls/subroundEndRound_test.go +++ b/consensus/spos/bls/subroundEndRound_test.go @@ -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() @@ -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() @@ -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) {