From fe41a12ae7cf440893e102c4a7743cadd739cf77 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Wed, 7 Aug 2024 06:19:07 +0200 Subject: [PATCH] fix: don't verify evidence signatures on non-validators --- internal/evidence/verify.go | 29 +++++++++++++++++------------ internal/evidence/verify_test.go | 4 ++-- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/internal/evidence/verify.go b/internal/evidence/verify.go index bb3b4bd4dd..6bc2e75282 100644 --- a/internal/evidence/verify.go +++ b/internal/evidence/verify.go @@ -5,6 +5,7 @@ import ( "context" "fmt" + "github.com/dashpay/tenderdash/libs/log" "github.com/dashpay/tenderdash/types" ) @@ -64,7 +65,7 @@ func (evpool *Pool) verify(ctx context.Context, evidence types.Evidence) error { return err } - if err := VerifyDuplicateVote(ev, state.ChainID, valSet); err != nil { + if err := VerifyDuplicateVote(ev, state.ChainID, valSet, evpool.logger); err != nil { return types.NewErrInvalidEvidence(evidence, err) } @@ -90,15 +91,15 @@ func (evpool *Pool) verify(ctx context.Context, evidence types.Evidence) error { // - the validator is in the validator set at the height of the evidence // - the height, round, type and validator address of the votes must be the same // - the block ID's must be different -// - The signatures must both be valid -func VerifyDuplicateVote(e *types.DuplicateVoteEvidence, chainID string, valSet *types.ValidatorSet) error { +// - The signatures must both be valid (only if we have public keys of the validator set) +func VerifyDuplicateVote(e *types.DuplicateVoteEvidence, chainID string, valSet *types.ValidatorSet, logger log.Logger) error { _, val := valSet.GetByProTxHash(e.VoteA.ValidatorProTxHash) if val == nil { return fmt.Errorf("protxhash %X was not a validator at height %d", e.VoteA.ValidatorProTxHash, e.Height()) } proTxHash := val.ProTxHash pubKey := val.PubKey - if pubKey == nil { + if valSet.HasPublicKeys && pubKey == nil { return fmt.Errorf("we don't have a public key of validator %X at height %d", proTxHash, e.Height()) } @@ -134,14 +135,18 @@ func VerifyDuplicateVote(e *types.DuplicateVoteEvidence, chainID string, valSet voteProTxHash, proTxHash) } - va := e.VoteA.ToProto() - vb := e.VoteB.ToProto() - // Signatures must be valid - if !pubKey.VerifySignatureDigest(types.VoteBlockSignID(chainID, va, valSet.QuorumType, valSet.QuorumHash), e.VoteA.BlockSignature) { - return fmt.Errorf("verifying VoteA: %w", types.ErrVoteInvalidBlockSignature) - } - if !pubKey.VerifySignatureDigest(types.VoteBlockSignID(chainID, vb, valSet.QuorumType, valSet.QuorumHash), e.VoteB.BlockSignature) { - return fmt.Errorf("verifying VoteB: %w", types.ErrVoteInvalidBlockSignature) + if pubKey != nil { + va := e.VoteA.ToProto() + vb := e.VoteB.ToProto() + // Signatures must be valid + if !pubKey.VerifySignatureDigest(types.VoteBlockSignID(chainID, va, valSet.QuorumType, valSet.QuorumHash), e.VoteA.BlockSignature) { + return fmt.Errorf("verifying VoteA: %w", types.ErrVoteInvalidBlockSignature) + } + if !pubKey.VerifySignatureDigest(types.VoteBlockSignID(chainID, vb, valSet.QuorumType, valSet.QuorumHash), e.VoteB.BlockSignature) { + return fmt.Errorf("verifying VoteB: %w", types.ErrVoteInvalidBlockSignature) + } + } else { + logger.Debug("skipping verification of duplicate vote evidence signatures - no access public key", "evidence", e) } return nil diff --git a/internal/evidence/verify_test.go b/internal/evidence/verify_test.go index 39e678f51c..18db60a228 100644 --- a/internal/evidence/verify_test.go +++ b/internal/evidence/verify_test.go @@ -84,9 +84,9 @@ func TestVerifyDuplicateVoteEvidence(t *testing.T) { Timestamp: defaultEvidenceTime, } if c.valid { - assert.Nil(t, evidence.VerifyDuplicateVote(ev, chainID, valSet), "evidence should be valid") + assert.Nil(t, evidence.VerifyDuplicateVote(ev, chainID, valSet, logger), "evidence should be valid") } else { - assert.NotNil(t, evidence.VerifyDuplicateVote(ev, chainID, valSet), "evidence should be invalid") + assert.NotNil(t, evidence.VerifyDuplicateVote(ev, chainID, valSet, logger), "evidence should be invalid") } }