Skip to content

Commit 71ce841

Browse files
committed
fix after review: small refactor, in order to keep the mutex locked only when necessary + added equivalent message signature verification
1 parent 1ba03ab commit 71ce841

File tree

2 files changed

+72
-25
lines changed

2 files changed

+72
-25
lines changed

consensus/spos/worker.go

Lines changed: 47 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -721,14 +721,7 @@ func (wrk *Worker) ResetConsensusMessages() {
721721
}
722722

723723
func (wrk *Worker) checkValidityAndProcessEquivalentMessages(cnsMsg *consensus.Message, p2pMessage p2p.MessageP2P) error {
724-
wrk.mutEquivalentMessages.Lock()
725-
defer wrk.mutEquivalentMessages.Unlock()
726-
727724
msgType := consensus.MessageType(cnsMsg.MsgType)
728-
err := wrk.processEquivalentMessageUnprotected(msgType, cnsMsg.BlockHeaderHash)
729-
if err != nil {
730-
return err
731-
}
732725

733726
log.Trace("received message from consensus topic",
734727
"msg type", wrk.consensusService.GetStringValue(msgType),
@@ -738,28 +731,41 @@ func (wrk *Worker) checkValidityAndProcessEquivalentMessages(cnsMsg *consensus.M
738731
"size", len(p2pMessage.Data()),
739732
)
740733

734+
if !wrk.enableEpochsHandler.IsEquivalentMessagesFlagEnabled() {
735+
return wrk.consensusMessageValidator.checkConsensusMessageValidity(cnsMsg, p2pMessage.Peer())
736+
}
737+
738+
// if the message is not with final info, no need to check its equivalent messages
739+
if !wrk.consensusService.IsMessageWithFinalInfo(msgType) {
740+
return wrk.consensusMessageValidator.checkConsensusMessageValidity(cnsMsg, p2pMessage.Peer())
741+
}
742+
743+
wrk.mutEquivalentMessages.Lock()
744+
defer wrk.mutEquivalentMessages.Unlock()
745+
746+
err := wrk.processEquivalentMessageUnprotected(cnsMsg)
747+
if err != nil {
748+
return err
749+
}
750+
741751
err = wrk.consensusMessageValidator.checkConsensusMessageValidity(cnsMsg, p2pMessage.Peer())
742752
if err != nil {
743-
wrk.processInvalidEquivalentMessageUnprotected(msgType, cnsMsg.BlockHeaderHash)
753+
wrk.processInvalidEquivalentMessageUnprotected(cnsMsg.BlockHeaderHash)
744754
return err
745755
}
746756

747757
return nil
748758
}
749759

750-
func (wrk *Worker) processEquivalentMessageUnprotected(msgType consensus.MessageType, blockHeaderHash []byte) error {
751-
if wrk.enableEpochsHandler.IsEquivalentMessagesFlagEnabled() {
752-
return nil
753-
}
754-
755-
// early exit if the message is not with final info
756-
if !wrk.consensusService.IsMessageWithFinalInfo(msgType) {
757-
return nil
760+
func (wrk *Worker) processEquivalentMessageUnprotected(cnsMsg *consensus.Message) error {
761+
err := wrk.verifyEquivalentMessageSignature(cnsMsg)
762+
if err != nil {
763+
return err
758764
}
759765

760-
hdrHash := string(blockHeaderHash)
766+
hdrHash := string(cnsMsg.BlockHeaderHash)
761767

762-
// if an equivalent message was seen before, return error to stop further broadcasts
768+
// if a valid equivalent message was seen before, return error to stop further broadcasts
763769
numMessages := wrk.equivalentMessages[hdrHash]
764770
wrk.equivalentMessages[hdrHash] = numMessages + 1
765771
if numMessages > 0 {
@@ -769,17 +775,34 @@ func (wrk *Worker) processEquivalentMessageUnprotected(msgType consensus.Message
769775
return nil
770776
}
771777

772-
func (wrk *Worker) processInvalidEquivalentMessageUnprotected(msgType consensus.MessageType, blockHeaderHash []byte) {
773-
if wrk.enableEpochsHandler.IsEquivalentMessagesFlagEnabled() {
774-
return
778+
func (wrk *Worker) verifyEquivalentMessageSignature(cnsMsg *consensus.Message) error {
779+
if check.IfNil(wrk.consensusState.Header) {
780+
return ErrNilHeader
775781
}
776782

777-
if !wrk.consensusService.IsMessageWithFinalInfo(msgType) {
778-
return
783+
header := wrk.consensusState.Header.ShallowClone()
784+
785+
err := header.SetSignature(cnsMsg.Signature)
786+
if err != nil {
787+
return err
779788
}
780789

781-
hdrHash := string(blockHeaderHash)
790+
err = header.SetPubKeysBitmap(cnsMsg.PubKeysBitmap)
791+
if err != nil {
792+
return err
793+
}
782794

795+
err = wrk.headerSigVerifier.VerifySignature(header)
796+
if err != nil {
797+
log.Debug("verifyEquivalentMessageSignature", "error", err.Error())
798+
return err
799+
}
800+
801+
return nil
802+
}
803+
804+
func (wrk *Worker) processInvalidEquivalentMessageUnprotected(blockHeaderHash []byte) {
805+
hdrHash := string(blockHeaderHash)
783806
delete(wrk.equivalentMessages, hdrHash)
784807
}
785808

consensus/spos/worker_test.go

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -608,10 +608,13 @@ func TestWorker_ProcessReceivedMessageRedundancyNodeShouldResetInactivityIfNeede
608608
assert.True(t, wasCalled)
609609
}
610610

611-
func TestWorker_ProcessReceivedMessageEquivalentMessageShouldReturnError(t *testing.T) {
611+
func TestWorker_ProcessReceivedMessageEquivalentMessage(t *testing.T) {
612612
t.Parallel()
613613

614614
workerArgs := createDefaultWorkerArgs(&statusHandlerMock.AppStatusHandlerStub{})
615+
workerArgs.EnableEpochsHandler = &enableEpochsHandlerMock.EnableEpochsHandlerStub{
616+
IsEquivalentMessagesFlagEnabledField: true,
617+
}
615618
wrk, _ := spos.NewWorker(workerArgs)
616619

617620
equivalentBlockHeaderHash := workerArgs.Hasher.Compute("equivalent block header hash")
@@ -685,6 +688,27 @@ func TestWorker_ProcessReceivedMessageEquivalentMessageShouldReturnError(t *test
685688
fromConnectedPeerId,
686689
&p2pmocks.MessengerStub{},
687690
)
691+
assert.Equal(t, spos.ErrNilHeader, err)
692+
693+
wrk.ConsensusState().Header = &block.Header{
694+
ChainID: chainID,
695+
PrevHash: []byte("prev hash"),
696+
PrevRandSeed: []byte("prev rand seed"),
697+
RandSeed: []byte("rand seed"),
698+
RootHash: []byte("roothash"),
699+
SoftwareVersion: []byte("software version"),
700+
AccumulatedFees: big.NewInt(0),
701+
DeveloperFees: big.NewInt(0),
702+
}
703+
err = wrk.ProcessReceivedMessage(
704+
&p2pmocks.P2PMessageMock{
705+
DataField: buff,
706+
PeerField: currentPid,
707+
SignatureField: []byte("signature"),
708+
},
709+
fromConnectedPeerId,
710+
&p2pmocks.MessengerStub{},
711+
)
688712
assert.NoError(t, err)
689713

690714
equivalentMessages := wrk.GetEquivalentMessages()

0 commit comments

Comments
 (0)