diff --git a/dataRetriever/dataPool/proofsCache/errors.go b/dataRetriever/dataPool/proofsCache/errors.go index 63376ef0a92..630dd8cc394 100644 --- a/dataRetriever/dataPool/proofsCache/errors.go +++ b/dataRetriever/dataPool/proofsCache/errors.go @@ -7,3 +7,6 @@ var ErrMissingProof = errors.New("missing proof") // ErrNilProof signals that a nil proof has been provided var ErrNilProof = errors.New("nil proof provided") + +// ErrAlreadyExistingEquivalentProof signals that the provided proof was already exiting in the pool +var ErrAlreadyExistingEquivalentProof = errors.New("already existing equivalent proof") diff --git a/dataRetriever/dataPool/proofsCache/proofsPool.go b/dataRetriever/dataPool/proofsCache/proofsPool.go index 6362f601928..a412794a6db 100644 --- a/dataRetriever/dataPool/proofsCache/proofsPool.go +++ b/dataRetriever/dataPool/proofsCache/proofsPool.go @@ -41,7 +41,7 @@ func (pp *proofsPool) AddProof( hasProof := pp.HasProof(shardID, headerHash) if hasProof { - return fmt.Errorf("there was already a valid proof for header, headerHash: %s", hex.EncodeToString(headerHash)) + return fmt.Errorf("%w, headerHash: %s", ErrAlreadyExistingEquivalentProof, hex.EncodeToString(headerHash)) } pp.mutCache.Lock() diff --git a/dataRetriever/dataPool/proofsCache/proofsPool_test.go b/dataRetriever/dataPool/proofsCache/proofsPool_test.go index b2e4ffdcecc..c4e373eeba7 100644 --- a/dataRetriever/dataPool/proofsCache/proofsPool_test.go +++ b/dataRetriever/dataPool/proofsCache/proofsPool_test.go @@ -66,6 +66,9 @@ func TestProofsPool_ShouldWork(t *testing.T) { _ = pp.AddProof(proof3) _ = pp.AddProof(proof4) + err := pp.AddProof(proof4) + require.True(t, errors.Is(err, proofscache.ErrAlreadyExistingEquivalentProof)) + proof, err := pp.GetProof(shardID, []byte("hash3")) require.Nil(t, err) require.Equal(t, proof3, proof) diff --git a/process/block/interceptedBlocks/interceptedEquivalentProof.go b/process/block/interceptedBlocks/interceptedEquivalentProof.go index b1ddba19b67..a7937a5aef2 100644 --- a/process/block/interceptedBlocks/interceptedEquivalentProof.go +++ b/process/block/interceptedBlocks/interceptedEquivalentProof.go @@ -9,6 +9,8 @@ import ( "github.com/multiversx/mx-chain-core-go/data/block" "github.com/multiversx/mx-chain-core-go/marshal" "github.com/multiversx/mx-chain-go/consensus" + "github.com/multiversx/mx-chain-go/dataRetriever" + proofscache "github.com/multiversx/mx-chain-go/dataRetriever/dataPool/proofsCache" "github.com/multiversx/mx-chain-go/process" "github.com/multiversx/mx-chain-go/sharding" logger "github.com/multiversx/mx-chain-logger-go" @@ -22,12 +24,14 @@ type ArgInterceptedEquivalentProof struct { Marshaller marshal.Marshalizer ShardCoordinator sharding.Coordinator HeaderSigVerifier consensus.HeaderSigVerifier + Proofs dataRetriever.ProofsPool } type interceptedEquivalentProof struct { proof *block.HeaderProof isForCurrentShard bool headerSigVerifier consensus.HeaderSigVerifier + proofsPool dataRetriever.ProofsPool } // NewInterceptedEquivalentProof returns a new instance of interceptedEquivalentProof @@ -46,6 +50,7 @@ func NewInterceptedEquivalentProof(args ArgInterceptedEquivalentProof) (*interce proof: equivalentProof, isForCurrentShard: extractIsForCurrentShard(args.ShardCoordinator, equivalentProof), headerSigVerifier: args.HeaderSigVerifier, + proofsPool: args.Proofs, }, nil } @@ -62,6 +67,9 @@ func checkArgInterceptedEquivalentProof(args ArgInterceptedEquivalentProof) erro if check.IfNil(args.HeaderSigVerifier) { return process.ErrNilHeaderSigVerifier } + if check.IfNil(args.Proofs) { + return process.ErrNilProofsPool + } return nil } @@ -101,6 +109,11 @@ func (iep *interceptedEquivalentProof) CheckValidity() error { return err } + ok := iep.proofsPool.HasProof(iep.proof.GetHeaderShardId(), iep.proof.GetHeaderHash()) + if ok { + return proofscache.ErrAlreadyExistingEquivalentProof + } + return iep.headerSigVerifier.VerifyHeaderProof(iep.proof) } diff --git a/process/block/interceptedBlocks/interceptedEquivalentProof_test.go b/process/block/interceptedBlocks/interceptedEquivalentProof_test.go index e46fa651634..b0a8cd6c9c9 100644 --- a/process/block/interceptedBlocks/interceptedEquivalentProof_test.go +++ b/process/block/interceptedBlocks/interceptedEquivalentProof_test.go @@ -9,8 +9,10 @@ import ( "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-core-go/data/block" "github.com/multiversx/mx-chain-go/consensus/mock" + proofscache "github.com/multiversx/mx-chain-go/dataRetriever/dataPool/proofsCache" "github.com/multiversx/mx-chain-go/process" "github.com/multiversx/mx-chain-go/testscommon/consensus" + "github.com/multiversx/mx-chain-go/testscommon/dataRetriever" "github.com/multiversx/mx-chain-go/testscommon/marshallerMock" logger "github.com/multiversx/mx-chain-logger-go" "github.com/stretchr/testify/require" @@ -41,6 +43,7 @@ func createMockArgInterceptedEquivalentProof() ArgInterceptedEquivalentProof { Marshaller: testMarshaller, ShardCoordinator: &mock.ShardCoordinatorMock{}, HeaderSigVerifier: &consensus.HeaderSigVerifierMock{}, + Proofs: &dataRetriever.ProofsPoolMock{}, } } @@ -93,6 +96,15 @@ func TestNewInterceptedEquivalentProof(t *testing.T) { require.Equal(t, process.ErrNilHeaderSigVerifier, err) require.Nil(t, iep) }) + t.Run("nil proofs pool should error", func(t *testing.T) { + t.Parallel() + + args := createMockArgInterceptedEquivalentProof() + args.Proofs = nil + iep, err := NewInterceptedEquivalentProof(args) + require.Equal(t, process.ErrNilProofsPool, err) + require.Nil(t, iep) + }) t.Run("unmarshal error should error", func(t *testing.T) { t.Parallel() @@ -134,6 +146,24 @@ func TestInterceptedEquivalentProof_CheckValidity(t *testing.T) { err = iep.CheckValidity() require.Equal(t, ErrInvalidProof, err) }) + + t.Run("already exiting proof should error", func(t *testing.T) { + t.Parallel() + + args := createMockArgInterceptedEquivalentProof() + args.Proofs = &dataRetriever.ProofsPoolMock{ + HasProofCalled: func(shardID uint32, headerHash []byte) bool { + return true + }, + } + + iep, err := NewInterceptedEquivalentProof(args) + require.NoError(t, err) + + err = iep.CheckValidity() + require.Equal(t, proofscache.ErrAlreadyExistingEquivalentProof, err) + }) + t.Run("should work", func(t *testing.T) { t.Parallel() diff --git a/process/errors.go b/process/errors.go index c72948e190f..395ebf17620 100644 --- a/process/errors.go +++ b/process/errors.go @@ -1254,9 +1254,6 @@ var ErrNoMatchingConfigForProvidedEpoch = errors.New("no matching configuration" // ErrInvalidHeader is raised when header is invalid var ErrInvalidHeader = errors.New("header is invalid") -// ErrNilEquivalentProofsPool signals that a nil equivalent proofs pool has been provided -var ErrNilEquivalentProofsPool = errors.New("nil equivalent proofs pool") - // ErrNilHeaderProof signals that a nil header proof has been provided var ErrNilHeaderProof = errors.New("nil header proof") diff --git a/process/factory/interceptorscontainer/baseInterceptorsContainerFactory.go b/process/factory/interceptorscontainer/baseInterceptorsContainerFactory.go index eab22fac66d..bc167e0dab5 100644 --- a/process/factory/interceptorscontainer/baseInterceptorsContainerFactory.go +++ b/process/factory/interceptorscontainer/baseInterceptorsContainerFactory.go @@ -913,7 +913,7 @@ func (bicf *baseInterceptorsContainerFactory) generateValidatorInfoInterceptor() } func (bicf *baseInterceptorsContainerFactory) createOneShardEquivalentProofsInterceptor(topic string) (process.Interceptor, error) { - equivalentProofsFactory := interceptorFactory.NewInterceptedEquivalentProofsFactory(*bicf.argInterceptorFactory) + equivalentProofsFactory := interceptorFactory.NewInterceptedEquivalentProofsFactory(*bicf.argInterceptorFactory, bicf.dataPool.Proofs()) marshaller := bicf.argInterceptorFactory.CoreComponents.InternalMarshalizer() argProcessor := processor.ArgEquivalentProofsInterceptorProcessor{ diff --git a/process/interceptors/factory/interceptedEquivalentProofsFactory.go b/process/interceptors/factory/interceptedEquivalentProofsFactory.go index 0a007fef3d6..4c5694d1e4d 100644 --- a/process/interceptors/factory/interceptedEquivalentProofsFactory.go +++ b/process/interceptors/factory/interceptedEquivalentProofsFactory.go @@ -3,6 +3,7 @@ package factory import ( "github.com/multiversx/mx-chain-core-go/marshal" "github.com/multiversx/mx-chain-go/consensus" + "github.com/multiversx/mx-chain-go/dataRetriever" "github.com/multiversx/mx-chain-go/process" "github.com/multiversx/mx-chain-go/process/block/interceptedBlocks" "github.com/multiversx/mx-chain-go/sharding" @@ -12,14 +13,16 @@ type interceptedEquivalentProofsFactory struct { marshaller marshal.Marshalizer shardCoordinator sharding.Coordinator headerSigVerifier consensus.HeaderSigVerifier + proofsPool dataRetriever.ProofsPool } // NewInterceptedEquivalentProofsFactory creates a new instance of interceptedEquivalentProofsFactory -func NewInterceptedEquivalentProofsFactory(args ArgInterceptedDataFactory) *interceptedEquivalentProofsFactory { +func NewInterceptedEquivalentProofsFactory(args ArgInterceptedDataFactory, proofsPool dataRetriever.ProofsPool) *interceptedEquivalentProofsFactory { return &interceptedEquivalentProofsFactory{ marshaller: args.CoreComponents.InternalMarshalizer(), shardCoordinator: args.ShardCoordinator, headerSigVerifier: args.HeaderSigVerifier, + proofsPool: proofsPool, } } @@ -30,6 +33,7 @@ func (factory *interceptedEquivalentProofsFactory) Create(buff []byte) (process. Marshaller: factory.marshaller, ShardCoordinator: factory.shardCoordinator, HeaderSigVerifier: factory.headerSigVerifier, + Proofs: factory.proofsPool, } return interceptedBlocks.NewInterceptedEquivalentProof(args) } diff --git a/process/interceptors/factory/interceptedEquivalentProofsFactory_test.go b/process/interceptors/factory/interceptedEquivalentProofsFactory_test.go index 9ee099b1c6a..c96ade9528b 100644 --- a/process/interceptors/factory/interceptedEquivalentProofsFactory_test.go +++ b/process/interceptors/factory/interceptedEquivalentProofsFactory_test.go @@ -8,6 +8,7 @@ import ( "github.com/multiversx/mx-chain-go/consensus/mock" processMock "github.com/multiversx/mx-chain-go/process/mock" "github.com/multiversx/mx-chain-go/testscommon/consensus" + "github.com/multiversx/mx-chain-go/testscommon/dataRetriever" "github.com/stretchr/testify/require" ) @@ -27,14 +28,14 @@ func TestInterceptedEquivalentProofsFactory_IsInterfaceNil(t *testing.T) { var factory *interceptedEquivalentProofsFactory require.True(t, factory.IsInterfaceNil()) - factory = NewInterceptedEquivalentProofsFactory(createMockArgInterceptedDataFactory()) + factory = NewInterceptedEquivalentProofsFactory(createMockArgInterceptedDataFactory(), &dataRetriever.ProofsPoolMock{}) require.False(t, factory.IsInterfaceNil()) } func TestNewInterceptedEquivalentProofsFactory(t *testing.T) { t.Parallel() - factory := NewInterceptedEquivalentProofsFactory(createMockArgInterceptedDataFactory()) + factory := NewInterceptedEquivalentProofsFactory(createMockArgInterceptedDataFactory(), &dataRetriever.ProofsPoolMock{}) require.NotNil(t, factory) } @@ -42,7 +43,7 @@ func TestInterceptedEquivalentProofsFactory_Create(t *testing.T) { t.Parallel() args := createMockArgInterceptedDataFactory() - factory := NewInterceptedEquivalentProofsFactory(args) + factory := NewInterceptedEquivalentProofsFactory(args, &dataRetriever.ProofsPoolMock{}) require.NotNil(t, factory) providedProof := &block.HeaderProof{ diff --git a/process/interceptors/processor/equivalentProofsInterceptorProcessor.go b/process/interceptors/processor/equivalentProofsInterceptorProcessor.go index 0f66cbc3100..ef8beff12af 100644 --- a/process/interceptors/processor/equivalentProofsInterceptorProcessor.go +++ b/process/interceptors/processor/equivalentProofsInterceptorProcessor.go @@ -34,7 +34,7 @@ func NewEquivalentProofsInterceptorProcessor(args ArgEquivalentProofsInterceptor func checkArgsEquivalentProofs(args ArgEquivalentProofsInterceptorProcessor) error { if check.IfNil(args.EquivalentProofsPool) { - return process.ErrNilEquivalentProofsPool + return process.ErrNilProofsPool } if check.IfNil(args.Marshaller) { return process.ErrNilMarshalizer diff --git a/process/interceptors/processor/equivalentProofsInterceptorProcessor_test.go b/process/interceptors/processor/equivalentProofsInterceptorProcessor_test.go index 78f815a67b8..b11eca03aec 100644 --- a/process/interceptors/processor/equivalentProofsInterceptorProcessor_test.go +++ b/process/interceptors/processor/equivalentProofsInterceptorProcessor_test.go @@ -42,7 +42,7 @@ func TestNewEquivalentProofsInterceptorProcessor(t *testing.T) { args.EquivalentProofsPool = nil epip, err := NewEquivalentProofsInterceptorProcessor(args) - require.Equal(t, process.ErrNilEquivalentProofsPool, err) + require.Equal(t, process.ErrNilProofsPool, err) require.Nil(t, epip) }) t.Run("nil Marshaller should error", func(t *testing.T) { @@ -104,6 +104,7 @@ func TestEquivalentProofsInterceptorProcessor_Save(t *testing.T) { Marshaller: args.Marshaller, ShardCoordinator: &mock.ShardCoordinatorMock{}, HeaderSigVerifier: &consensus.HeaderSigVerifierMock{}, + Proofs: &dataRetriever.ProofsPoolMock{}, } argInterceptedEquivalentProof.DataBuff, _ = argInterceptedEquivalentProof.Marshaller.Marshal(&block.HeaderProof{ PubKeysBitmap: []byte("bitmap"), diff --git a/process/interceptors/processor/hdrInterceptorProcessor.go b/process/interceptors/processor/hdrInterceptorProcessor.go index 9743f0d2d47..e60489c2ae5 100644 --- a/process/interceptors/processor/hdrInterceptorProcessor.go +++ b/process/interceptors/processor/hdrInterceptorProcessor.go @@ -34,7 +34,7 @@ func NewHdrInterceptorProcessor(argument *ArgHdrInterceptorProcessor) (*HdrInter return nil, process.ErrNilCacher } if check.IfNil(argument.Proofs) { - return nil, process.ErrNilEquivalentProofsPool + return nil, process.ErrNilProofsPool } if check.IfNil(argument.BlockBlackList) { return nil, process.ErrNilBlackListCacher diff --git a/process/interceptors/processor/hdrInterceptorProcessor_test.go b/process/interceptors/processor/hdrInterceptorProcessor_test.go index 74dd77d321e..cc35b04d06b 100644 --- a/process/interceptors/processor/hdrInterceptorProcessor_test.go +++ b/process/interceptors/processor/hdrInterceptorProcessor_test.go @@ -69,7 +69,7 @@ func TestNewHdrInterceptorProcessor_NilProofsPoolShouldErr(t *testing.T) { hip, err := processor.NewHdrInterceptorProcessor(arg) assert.Nil(t, hip) - assert.Equal(t, process.ErrNilEquivalentProofsPool, err) + assert.Equal(t, process.ErrNilProofsPool, err) } func TestNewHdrInterceptorProcessor_NilEnableEpochsHandlerShouldErr(t *testing.T) {