From 1235b89f316f8238ae57f8627504fd17c5e81f62 Mon Sep 17 00:00:00 2001 From: Sorin Stanculeanu Date: Thu, 9 Jan 2025 17:09:30 +0200 Subject: [PATCH 1/5] added checks on proofs parameters like epoch, nonce and shard --- process/block/baseProcess.go | 29 ++++ .../interceptedEquivalentProof.go | 31 +++++ .../interceptedEquivalentProof_test.go | 126 +++++++++++++++++- .../baseInterceptorsContainerFactory.go | 7 +- .../interceptedEquivalentProofsFactory.go | 14 +- ...interceptedEquivalentProofsFactory_test.go | 25 ++-- ...uivalentProofsInterceptorProcessor_test.go | 2 + testscommon/headerHandlerStub.go | 4 + 8 files changed, 222 insertions(+), 16 deletions(-) diff --git a/process/block/baseProcess.go b/process/block/baseProcess.go index 4f2a3661ece..05cdd858888 100644 --- a/process/block/baseProcess.go +++ b/process/block/baseProcess.go @@ -222,6 +222,35 @@ func (bp *baseProcessor) checkBlockValidity( return process.ErrEpochDoesNotMatch } + return bp.checkPrevProofValidity(headerHandler) +} + +func (bp *baseProcessor) checkPrevProofValidity(headerHandler data.HeaderHandler) error { + if !bp.enableEpochsHandler.IsFlagEnabledInEpoch(common.EquivalentMessagesFlag, headerHandler.GetEpoch()) { + return nil + } + + prevProof := headerHandler.GetPreviousProof() + if check.IfNilReflect(prevProof) { + return process.ErrMissingHeaderProof + } + + headersPool := bp.dataPool.Headers() + prevHeader, err := headersPool.GetHeaderByHash(prevProof.GetHeaderHash()) + if err != nil { + return fmt.Errorf("%w while getting header for proof hash %s", err, hex.EncodeToString(prevProof.GetHeaderHash())) + } + + if prevProof.GetHeaderNonce() != prevHeader.GetNonce() { + return fmt.Errorf("%w, nonce mismatch", process.ErrInvalidHeaderProof) + } + if prevProof.GetHeaderShardId() != prevHeader.GetShardID() { + return fmt.Errorf("%w, shard id mismatch", process.ErrInvalidHeaderProof) + } + if prevProof.GetHeaderEpoch() != prevHeader.GetEpoch() { + return fmt.Errorf("%w, epoch mismatch", process.ErrInvalidHeaderProof) + } + return nil } diff --git a/process/block/interceptedBlocks/interceptedEquivalentProof.go b/process/block/interceptedBlocks/interceptedEquivalentProof.go index 7712aa483b7..b1131725947 100644 --- a/process/block/interceptedBlocks/interceptedEquivalentProof.go +++ b/process/block/interceptedBlocks/interceptedEquivalentProof.go @@ -1,6 +1,7 @@ package interceptedBlocks import ( + "encoding/hex" "fmt" "github.com/multiversx/mx-chain-core-go/core" @@ -25,6 +26,7 @@ type ArgInterceptedEquivalentProof struct { ShardCoordinator sharding.Coordinator HeaderSigVerifier consensus.HeaderSigVerifier Proofs dataRetriever.ProofsPool + Headers dataRetriever.HeadersPool } type interceptedEquivalentProof struct { @@ -32,6 +34,7 @@ type interceptedEquivalentProof struct { isForCurrentShard bool headerSigVerifier consensus.HeaderSigVerifier proofsPool dataRetriever.ProofsPool + headersPool dataRetriever.HeadersPool } // NewInterceptedEquivalentProof returns a new instance of interceptedEquivalentProof @@ -51,6 +54,7 @@ func NewInterceptedEquivalentProof(args ArgInterceptedEquivalentProof) (*interce isForCurrentShard: extractIsForCurrentShard(args.ShardCoordinator, equivalentProof), headerSigVerifier: args.HeaderSigVerifier, proofsPool: args.Proofs, + headersPool: args.Headers, }, nil } @@ -70,6 +74,9 @@ func checkArgInterceptedEquivalentProof(args ArgInterceptedEquivalentProof) erro if check.IfNil(args.Proofs) { return process.ErrNilProofsPool } + if check.IfNil(args.Headers) { + return process.ErrNilHeadersDataPool + } return nil } @@ -115,9 +122,33 @@ func (iep *interceptedEquivalentProof) CheckValidity() error { return proofscache.ErrAlreadyExistingEquivalentProof } + err = iep.checkHeaderParamsFromProof() + if err != nil { + return err + } + return iep.headerSigVerifier.VerifyHeaderProof(iep.proof) } +func (iep *interceptedEquivalentProof) checkHeaderParamsFromProof() error { + header, err := iep.headersPool.GetHeaderByHash(iep.proof.GetHeaderHash()) + if err != nil { + return fmt.Errorf("%w while getting header for proof hash %s", err, hex.EncodeToString(iep.proof.GetHeaderHash())) + } + + if iep.proof.GetHeaderNonce() != header.GetNonce() { + return fmt.Errorf("%w, nonce mismatch", ErrInvalidProof) + } + if iep.proof.GetHeaderShardId() != header.GetShardID() { + return fmt.Errorf("%w, shard id mismatch", ErrInvalidProof) + } + if iep.proof.GetHeaderEpoch() != header.GetEpoch() { + return fmt.Errorf("%w, epoch mismatch", ErrInvalidProof) + } + + return nil +} + func (iep *interceptedEquivalentProof) integrity() error { isProofValid := len(iep.proof.AggregatedSignature) > 0 && len(iep.proof.PubKeysBitmap) > 0 && diff --git a/process/block/interceptedBlocks/interceptedEquivalentProof_test.go b/process/block/interceptedBlocks/interceptedEquivalentProof_test.go index b0a8cd6c9c9..033a67ea08a 100644 --- a/process/block/interceptedBlocks/interceptedEquivalentProof_test.go +++ b/process/block/interceptedBlocks/interceptedEquivalentProof_test.go @@ -4,16 +4,20 @@ import ( "bytes" "errors" "fmt" + "strings" "testing" "github.com/multiversx/mx-chain-core-go/core" + "github.com/multiversx/mx-chain-core-go/data" "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" "github.com/multiversx/mx-chain-go/testscommon/consensus" "github.com/multiversx/mx-chain-go/testscommon/dataRetriever" "github.com/multiversx/mx-chain-go/testscommon/marshallerMock" + "github.com/multiversx/mx-chain-go/testscommon/pool" logger "github.com/multiversx/mx-chain-logger-go" "github.com/stretchr/testify/require" ) @@ -21,6 +25,9 @@ import ( var ( expectedErr = errors.New("expected error") testMarshaller = &marshallerMock.MarshalizerMock{} + providedEpoch = uint32(123) + providedNonce = uint64(345) + providedShard = uint32(0) ) func createMockDataBuff() []byte { @@ -28,9 +35,9 @@ func createMockDataBuff() []byte { PubKeysBitmap: []byte("bitmap"), AggregatedSignature: []byte("sig"), HeaderHash: []byte("hash"), - HeaderEpoch: 123, - HeaderNonce: 345, - HeaderShardId: 0, + HeaderEpoch: providedEpoch, + HeaderNonce: providedNonce, + HeaderShardId: providedShard, } dataBuff, _ := testMarshaller.Marshal(proof) @@ -44,6 +51,19 @@ func createMockArgInterceptedEquivalentProof() ArgInterceptedEquivalentProof { ShardCoordinator: &mock.ShardCoordinatorMock{}, HeaderSigVerifier: &consensus.HeaderSigVerifierMock{}, Proofs: &dataRetriever.ProofsPoolMock{}, + Headers: &pool.HeadersPoolStub{ + GetHeaderByHashCalled: func(hash []byte) (data.HeaderHandler, error) { + return &testscommon.HeaderHandlerStub{ + EpochField: providedEpoch, + GetNonceCalled: func() uint64 { + return providedNonce + }, + GetShardIDCalled: func() uint32 { + return providedShard + }, + }, nil + }, + }, } } @@ -105,6 +125,15 @@ func TestNewInterceptedEquivalentProof(t *testing.T) { require.Equal(t, process.ErrNilProofsPool, err) require.Nil(t, iep) }) + t.Run("nil headers pool should error", func(t *testing.T) { + t.Parallel() + + args := createMockArgInterceptedEquivalentProof() + args.Headers = nil + iep, err := NewInterceptedEquivalentProof(args) + require.Equal(t, process.ErrNilHeadersDataPool, err) + require.Nil(t, iep) + }) t.Run("unmarshal error should error", func(t *testing.T) { t.Parallel() @@ -164,6 +193,97 @@ func TestInterceptedEquivalentProof_CheckValidity(t *testing.T) { require.Equal(t, proofscache.ErrAlreadyExistingEquivalentProof, err) }) + t.Run("missing header for proof hash should error", func(t *testing.T) { + t.Parallel() + + providedErr := errors.New("missing header") + args := createMockArgInterceptedEquivalentProof() + args.Headers = &pool.HeadersPoolStub{ + GetHeaderByHashCalled: func(hash []byte) (data.HeaderHandler, error) { + return nil, providedErr + }, + } + + iep, err := NewInterceptedEquivalentProof(args) + require.NoError(t, err) + + err = iep.CheckValidity() + require.True(t, errors.Is(err, providedErr)) + }) + + t.Run("nonce mismatch should error", func(t *testing.T) { + t.Parallel() + + args := createMockArgInterceptedEquivalentProof() + args.Headers = &pool.HeadersPoolStub{ + GetHeaderByHashCalled: func(hash []byte) (data.HeaderHandler, error) { + return &testscommon.HeaderHandlerStub{ + GetNonceCalled: func() uint64 { + return providedNonce + 1 + }, + }, nil + }, + } + + iep, err := NewInterceptedEquivalentProof(args) + require.NoError(t, err) + + err = iep.CheckValidity() + require.True(t, errors.Is(err, ErrInvalidProof)) + require.True(t, strings.Contains(err.Error(), "nonce mismatch")) + }) + + t.Run("shard id mismatch should error", func(t *testing.T) { + t.Parallel() + + args := createMockArgInterceptedEquivalentProof() + args.Headers = &pool.HeadersPoolStub{ + GetHeaderByHashCalled: func(hash []byte) (data.HeaderHandler, error) { + return &testscommon.HeaderHandlerStub{ + GetNonceCalled: func() uint64 { + return providedNonce + }, + GetShardIDCalled: func() uint32 { + return providedShard + 1 + }, + }, nil + }, + } + + iep, err := NewInterceptedEquivalentProof(args) + require.NoError(t, err) + + err = iep.CheckValidity() + require.True(t, errors.Is(err, ErrInvalidProof)) + require.True(t, strings.Contains(err.Error(), "shard id mismatch")) + }) + + t.Run("epoch mismatch should error", func(t *testing.T) { + t.Parallel() + + args := createMockArgInterceptedEquivalentProof() + args.Headers = &pool.HeadersPoolStub{ + GetHeaderByHashCalled: func(hash []byte) (data.HeaderHandler, error) { + return &testscommon.HeaderHandlerStub{ + GetNonceCalled: func() uint64 { + return providedNonce + }, + GetShardIDCalled: func() uint32 { + return providedShard + }, + EpochField: providedEpoch + 1, + }, nil + }, + } + + iep, err := NewInterceptedEquivalentProof(args) + require.NoError(t, err) + + err = iep.CheckValidity() + require.True(t, errors.Is(err, ErrInvalidProof)) + require.True(t, strings.Contains(err.Error(), "epoch mismatch")) + }) + t.Run("should work", func(t *testing.T) { t.Parallel() diff --git a/process/factory/interceptorscontainer/baseInterceptorsContainerFactory.go b/process/factory/interceptorscontainer/baseInterceptorsContainerFactory.go index bc167e0dab5..0c8fdd511ea 100644 --- a/process/factory/interceptorscontainer/baseInterceptorsContainerFactory.go +++ b/process/factory/interceptorscontainer/baseInterceptorsContainerFactory.go @@ -913,7 +913,12 @@ func (bicf *baseInterceptorsContainerFactory) generateValidatorInfoInterceptor() } func (bicf *baseInterceptorsContainerFactory) createOneShardEquivalentProofsInterceptor(topic string) (process.Interceptor, error) { - equivalentProofsFactory := interceptorFactory.NewInterceptedEquivalentProofsFactory(*bicf.argInterceptorFactory, bicf.dataPool.Proofs()) + args := interceptorFactory.ArgInterceptedEquivalentProofsFactory{ + ArgInterceptedDataFactory: *bicf.argInterceptorFactory, + ProofsPool: bicf.dataPool.Proofs(), + HeadersPool: bicf.dataPool.Headers(), + } + equivalentProofsFactory := interceptorFactory.NewInterceptedEquivalentProofsFactory(args) marshaller := bicf.argInterceptorFactory.CoreComponents.InternalMarshalizer() argProcessor := processor.ArgEquivalentProofsInterceptorProcessor{ diff --git a/process/interceptors/factory/interceptedEquivalentProofsFactory.go b/process/interceptors/factory/interceptedEquivalentProofsFactory.go index 4c5694d1e4d..fae4b1d5a4d 100644 --- a/process/interceptors/factory/interceptedEquivalentProofsFactory.go +++ b/process/interceptors/factory/interceptedEquivalentProofsFactory.go @@ -9,20 +9,29 @@ import ( "github.com/multiversx/mx-chain-go/sharding" ) +// ArgInterceptedEquivalentProofsFactory is the DTO used to create a new instance of interceptedEquivalentProofsFactory +type ArgInterceptedEquivalentProofsFactory struct { + ArgInterceptedDataFactory + ProofsPool dataRetriever.ProofsPool + HeadersPool dataRetriever.HeadersPool +} + type interceptedEquivalentProofsFactory struct { marshaller marshal.Marshalizer shardCoordinator sharding.Coordinator headerSigVerifier consensus.HeaderSigVerifier proofsPool dataRetriever.ProofsPool + headersPool dataRetriever.HeadersPool } // NewInterceptedEquivalentProofsFactory creates a new instance of interceptedEquivalentProofsFactory -func NewInterceptedEquivalentProofsFactory(args ArgInterceptedDataFactory, proofsPool dataRetriever.ProofsPool) *interceptedEquivalentProofsFactory { +func NewInterceptedEquivalentProofsFactory(args ArgInterceptedEquivalentProofsFactory) *interceptedEquivalentProofsFactory { return &interceptedEquivalentProofsFactory{ marshaller: args.CoreComponents.InternalMarshalizer(), shardCoordinator: args.ShardCoordinator, headerSigVerifier: args.HeaderSigVerifier, - proofsPool: proofsPool, + proofsPool: args.ProofsPool, + headersPool: args.HeadersPool, } } @@ -34,6 +43,7 @@ func (factory *interceptedEquivalentProofsFactory) Create(buff []byte) (process. ShardCoordinator: factory.shardCoordinator, HeaderSigVerifier: factory.headerSigVerifier, Proofs: factory.proofsPool, + Headers: factory.headersPool, } return interceptedBlocks.NewInterceptedEquivalentProof(args) } diff --git a/process/interceptors/factory/interceptedEquivalentProofsFactory_test.go b/process/interceptors/factory/interceptedEquivalentProofsFactory_test.go index c96ade9528b..d5c57d0a31f 100644 --- a/process/interceptors/factory/interceptedEquivalentProofsFactory_test.go +++ b/process/interceptors/factory/interceptedEquivalentProofsFactory_test.go @@ -9,16 +9,21 @@ import ( 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/multiversx/mx-chain-go/testscommon/pool" "github.com/stretchr/testify/require" ) -func createMockArgInterceptedDataFactory() ArgInterceptedDataFactory { - return ArgInterceptedDataFactory{ - CoreComponents: &processMock.CoreComponentsMock{ - IntMarsh: &mock.MarshalizerMock{}, +func createMockArgInterceptedEquivalentProofsFactory() ArgInterceptedEquivalentProofsFactory { + return ArgInterceptedEquivalentProofsFactory{ + ArgInterceptedDataFactory: ArgInterceptedDataFactory{ + CoreComponents: &processMock.CoreComponentsMock{ + IntMarsh: &mock.MarshalizerMock{}, + }, + ShardCoordinator: &mock.ShardCoordinatorMock{}, + HeaderSigVerifier: &consensus.HeaderSigVerifierMock{}, }, - ShardCoordinator: &mock.ShardCoordinatorMock{}, - HeaderSigVerifier: &consensus.HeaderSigVerifierMock{}, + ProofsPool: &dataRetriever.ProofsPoolMock{}, + HeadersPool: &pool.HeadersPoolStub{}, } } @@ -28,22 +33,22 @@ func TestInterceptedEquivalentProofsFactory_IsInterfaceNil(t *testing.T) { var factory *interceptedEquivalentProofsFactory require.True(t, factory.IsInterfaceNil()) - factory = NewInterceptedEquivalentProofsFactory(createMockArgInterceptedDataFactory(), &dataRetriever.ProofsPoolMock{}) + factory = NewInterceptedEquivalentProofsFactory(createMockArgInterceptedEquivalentProofsFactory()) require.False(t, factory.IsInterfaceNil()) } func TestNewInterceptedEquivalentProofsFactory(t *testing.T) { t.Parallel() - factory := NewInterceptedEquivalentProofsFactory(createMockArgInterceptedDataFactory(), &dataRetriever.ProofsPoolMock{}) + factory := NewInterceptedEquivalentProofsFactory(createMockArgInterceptedEquivalentProofsFactory()) require.NotNil(t, factory) } func TestInterceptedEquivalentProofsFactory_Create(t *testing.T) { t.Parallel() - args := createMockArgInterceptedDataFactory() - factory := NewInterceptedEquivalentProofsFactory(args, &dataRetriever.ProofsPoolMock{}) + args := createMockArgInterceptedEquivalentProofsFactory() + factory := NewInterceptedEquivalentProofsFactory(args) require.NotNil(t, factory) providedProof := &block.HeaderProof{ diff --git a/process/interceptors/processor/equivalentProofsInterceptorProcessor_test.go b/process/interceptors/processor/equivalentProofsInterceptorProcessor_test.go index b11eca03aec..5b9e3f04c57 100644 --- a/process/interceptors/processor/equivalentProofsInterceptorProcessor_test.go +++ b/process/interceptors/processor/equivalentProofsInterceptorProcessor_test.go @@ -12,6 +12,7 @@ import ( "github.com/multiversx/mx-chain-go/testscommon/consensus" "github.com/multiversx/mx-chain-go/testscommon/dataRetriever" "github.com/multiversx/mx-chain-go/testscommon/marshallerMock" + "github.com/multiversx/mx-chain-go/testscommon/pool" "github.com/stretchr/testify/require" ) @@ -105,6 +106,7 @@ func TestEquivalentProofsInterceptorProcessor_Save(t *testing.T) { ShardCoordinator: &mock.ShardCoordinatorMock{}, HeaderSigVerifier: &consensus.HeaderSigVerifierMock{}, Proofs: &dataRetriever.ProofsPoolMock{}, + Headers: &pool.HeadersPoolStub{}, } argInterceptedEquivalentProof.DataBuff, _ = argInterceptedEquivalentProof.Marshaller.Marshal(&block.HeaderProof{ PubKeysBitmap: []byte("bitmap"), diff --git a/testscommon/headerHandlerStub.go b/testscommon/headerHandlerStub.go index 00613c26d4d..733c8b5c167 100644 --- a/testscommon/headerHandlerStub.go +++ b/testscommon/headerHandlerStub.go @@ -40,6 +40,7 @@ type HeaderHandlerStub struct { SetLeaderSignatureCalled func(signature []byte) error GetPreviousProofCalled func() data.HeaderProofHandler SetPreviousProofCalled func(proof data.HeaderProofHandler) + GetShardIDCalled func() uint32 } // GetAccumulatedFees - @@ -91,6 +92,9 @@ func (hhs *HeaderHandlerStub) ShallowClone() data.HeaderHandler { // GetShardID - func (hhs *HeaderHandlerStub) GetShardID() uint32 { + if hhs.GetShardIDCalled != nil { + return hhs.GetShardIDCalled() + } return 1 } From d4243bc7779381a08ccf032e66c490d98424c5ef Mon Sep 17 00:00:00 2001 From: Sorin Stanculeanu Date: Fri, 10 Jan 2025 17:19:02 +0200 Subject: [PATCH 2/5] fixes after review --- process/block/baseProcess.go | 27 +++++++++-------- .../interceptedEquivalentProof.go | 3 ++ .../interceptedEquivalentProof_test.go | 30 +++++++++++++++++++ process/block/metablock.go | 12 ++++++++ 4 files changed, 59 insertions(+), 13 deletions(-) diff --git a/process/block/baseProcess.go b/process/block/baseProcess.go index 05cdd858888..969b549c1ae 100644 --- a/process/block/baseProcess.go +++ b/process/block/baseProcess.go @@ -222,34 +222,35 @@ func (bp *baseProcessor) checkBlockValidity( return process.ErrEpochDoesNotMatch } - return bp.checkPrevProofValidity(headerHandler) + return bp.checkPrevProofValidity(currentBlockHeader, headerHandler) } -func (bp *baseProcessor) checkPrevProofValidity(headerHandler data.HeaderHandler) error { - if !bp.enableEpochsHandler.IsFlagEnabledInEpoch(common.EquivalentMessagesFlag, headerHandler.GetEpoch()) { +func (bp *baseProcessor) checkPrevProofValidity(prevHeader, headerHandler data.HeaderHandler) error { + if !common.ShouldBlockHavePrevProof(headerHandler, bp.enableEpochsHandler, common.EquivalentMessagesFlag) { return nil } prevProof := headerHandler.GetPreviousProof() - if check.IfNilReflect(prevProof) { - return process.ErrMissingHeaderProof - } + return bp.verifyProofAgainstHeader(prevProof, prevHeader) +} - headersPool := bp.dataPool.Headers() - prevHeader, err := headersPool.GetHeaderByHash(prevProof.GetHeaderHash()) - if err != nil { - return fmt.Errorf("%w while getting header for proof hash %s", err, hex.EncodeToString(prevProof.GetHeaderHash())) +func (bp *baseProcessor) verifyProofAgainstHeader(proof data.HeaderProofHandler, header data.HeaderHandler) error { + if check.IfNilReflect(proof) { + return process.ErrMissingHeaderProof } - if prevProof.GetHeaderNonce() != prevHeader.GetNonce() { + if proof.GetHeaderNonce() != header.GetNonce() { return fmt.Errorf("%w, nonce mismatch", process.ErrInvalidHeaderProof) } - if prevProof.GetHeaderShardId() != prevHeader.GetShardID() { + if proof.GetHeaderShardId() != header.GetShardID() { return fmt.Errorf("%w, shard id mismatch", process.ErrInvalidHeaderProof) } - if prevProof.GetHeaderEpoch() != prevHeader.GetEpoch() { + if proof.GetHeaderEpoch() != header.GetEpoch() { return fmt.Errorf("%w, epoch mismatch", process.ErrInvalidHeaderProof) } + if proof.GetHeaderRound() != header.GetRound() { + return fmt.Errorf("%w, round mismatch", process.ErrInvalidHeaderProof) + } return nil } diff --git a/process/block/interceptedBlocks/interceptedEquivalentProof.go b/process/block/interceptedBlocks/interceptedEquivalentProof.go index b1131725947..fe5c9a71d94 100644 --- a/process/block/interceptedBlocks/interceptedEquivalentProof.go +++ b/process/block/interceptedBlocks/interceptedEquivalentProof.go @@ -145,6 +145,9 @@ func (iep *interceptedEquivalentProof) checkHeaderParamsFromProof() error { if iep.proof.GetHeaderEpoch() != header.GetEpoch() { return fmt.Errorf("%w, epoch mismatch", ErrInvalidProof) } + if iep.proof.GetHeaderRound() != header.GetRound() { + return fmt.Errorf("%w, round mismatch", ErrInvalidProof) + } return nil } diff --git a/process/block/interceptedBlocks/interceptedEquivalentProof_test.go b/process/block/interceptedBlocks/interceptedEquivalentProof_test.go index 033a67ea08a..f1a5e97762e 100644 --- a/process/block/interceptedBlocks/interceptedEquivalentProof_test.go +++ b/process/block/interceptedBlocks/interceptedEquivalentProof_test.go @@ -28,6 +28,7 @@ var ( providedEpoch = uint32(123) providedNonce = uint64(345) providedShard = uint32(0) + providedRound = uint64(123456) ) func createMockDataBuff() []byte { @@ -38,6 +39,7 @@ func createMockDataBuff() []byte { HeaderEpoch: providedEpoch, HeaderNonce: providedNonce, HeaderShardId: providedShard, + HeaderRound: providedRound, } dataBuff, _ := testMarshaller.Marshal(proof) @@ -55,6 +57,7 @@ func createMockArgInterceptedEquivalentProof() ArgInterceptedEquivalentProof { GetHeaderByHashCalled: func(hash []byte) (data.HeaderHandler, error) { return &testscommon.HeaderHandlerStub{ EpochField: providedEpoch, + RoundField: providedRound, GetNonceCalled: func() uint64 { return providedNonce }, @@ -284,6 +287,33 @@ func TestInterceptedEquivalentProof_CheckValidity(t *testing.T) { require.True(t, strings.Contains(err.Error(), "epoch mismatch")) }) + t.Run("round mismatch should error", func(t *testing.T) { + t.Parallel() + + args := createMockArgInterceptedEquivalentProof() + args.Headers = &pool.HeadersPoolStub{ + GetHeaderByHashCalled: func(hash []byte) (data.HeaderHandler, error) { + return &testscommon.HeaderHandlerStub{ + GetNonceCalled: func() uint64 { + return providedNonce + }, + GetShardIDCalled: func() uint32 { + return providedShard + }, + EpochField: providedEpoch, + RoundField: providedRound + 1, + }, nil + }, + } + + iep, err := NewInterceptedEquivalentProof(args) + require.NoError(t, err) + + err = iep.CheckValidity() + require.True(t, errors.Is(err, ErrInvalidProof)) + require.True(t, strings.Contains(err.Error(), "round mismatch")) + }) + t.Run("should work", func(t *testing.T) { t.Parallel() diff --git a/process/block/metablock.go b/process/block/metablock.go index 04220d9936d..5727e9d78c4 100644 --- a/process/block/metablock.go +++ b/process/block/metablock.go @@ -430,6 +430,18 @@ func (mp *metaProcessor) checkProofsForShardData(header *block.MetaBlock) error if !mp.proofsPool.HasProof(shardData.ShardID, shardData.HeaderHash) { return fmt.Errorf("%w for header hash %s", process.ErrMissingHeaderProof, hex.EncodeToString(shardData.HeaderHash)) } + + prevProof := shardData.GetPreviousProof() + headersPool := mp.dataPool.Headers() + prevHeader, err := headersPool.GetHeaderByHash(prevProof.GetHeaderHash()) + if err != nil { + return err + } + + err = mp.verifyProofAgainstHeader(prevProof, prevHeader) + if err != nil { + return err + } } return nil From 681f5068c49a16c9b8f9dd5ccf8941458309fc8b Mon Sep 17 00:00:00 2001 From: Sorin Stanculeanu Date: Fri, 10 Jan 2025 18:32:03 +0200 Subject: [PATCH 3/5] small refactor + extended checks --- common/common.go | 25 ++++++++++++++ common/errors.go | 3 ++ consensus/spos/bls/v2/subroundBlock.go | 33 ++++++++++++------- process/block/baseProcess.go | 23 +------------ .../interceptedEquivalentProof.go | 16 ++------- .../interceptedEquivalentProof_test.go | 9 ++--- process/block/metablock.go | 2 +- process/errors.go | 3 -- 8 files changed, 58 insertions(+), 56 deletions(-) diff --git a/common/common.go b/common/common.go index c3364fa6080..8359dcebfbf 100644 --- a/common/common.go +++ b/common/common.go @@ -1,7 +1,10 @@ package common import ( + "fmt" + "github.com/multiversx/mx-chain-core-go/core" + "github.com/multiversx/mx-chain-core-go/core/check" "github.com/multiversx/mx-chain-core-go/data" ) @@ -24,3 +27,25 @@ func IsFlagEnabledAfterEpochsStartBlock(header data.HeaderHandler, enableEpochsH func ShouldBlockHavePrevProof(header data.HeaderHandler, enableEpochsHandler EnableEpochsHandler, flag core.EnableEpochFlag) bool { return IsFlagEnabledAfterEpochsStartBlock(header, enableEpochsHandler, flag) && header.GetNonce() > 1 } + +// VerifyProofAgainstHeader verifies the fields on the proof match the ones on the header +func VerifyProofAgainstHeader(proof data.HeaderProofHandler, header data.HeaderHandler) error { + if check.IfNilReflect(proof) { + return ErrInvalidHeaderProof + } + + if proof.GetHeaderNonce() != header.GetNonce() { + return fmt.Errorf("%w, nonce mismatch", ErrInvalidHeaderProof) + } + if proof.GetHeaderShardId() != header.GetShardID() { + return fmt.Errorf("%w, shard id mismatch", ErrInvalidHeaderProof) + } + if proof.GetHeaderEpoch() != header.GetEpoch() { + return fmt.Errorf("%w, epoch mismatch", ErrInvalidHeaderProof) + } + if proof.GetHeaderRound() != header.GetRound() { + return fmt.Errorf("%w, round mismatch", ErrInvalidHeaderProof) + } + + return nil +} diff --git a/common/errors.go b/common/errors.go index 47b976de9a8..eeeaf94c804 100644 --- a/common/errors.go +++ b/common/errors.go @@ -10,3 +10,6 @@ var ErrNilWasmChangeLocker = errors.New("nil wasm change locker") // ErrNilStateSyncNotifierSubscriber signals that a nil state sync notifier subscriber has been provided var ErrNilStateSyncNotifierSubscriber = errors.New("nil state sync notifier subscriber") + +// ErrInvalidHeaderProof signals that an invalid equivalent proof has been provided +var ErrInvalidHeaderProof = errors.New("invalid equivalent proof") diff --git a/consensus/spos/bls/v2/subroundBlock.go b/consensus/spos/bls/v2/subroundBlock.go index 2454ad3643e..3ff1459d667 100644 --- a/consensus/spos/bls/v2/subroundBlock.go +++ b/consensus/spos/bls/v2/subroundBlock.go @@ -389,7 +389,7 @@ func isProofEmpty(proof data.HeaderProofHandler) bool { len(proof.GetHeaderHash()) == 0 } -func (sr *subroundBlock) saveProofForPreviousHeaderIfNeeded(header data.HeaderHandler) { +func (sr *subroundBlock) saveProofForPreviousHeaderIfNeeded(header data.HeaderHandler, prevHeader data.HeaderHandler) { hasProof := sr.EquivalentProofsPool().HasProof(sr.ShardCoordinator().SelfId(), header.GetPrevHash()) if hasProof { log.Debug("saveProofForPreviousHeaderIfNeeded: no need to set proof since it is already saved") @@ -397,11 +397,19 @@ func (sr *subroundBlock) saveProofForPreviousHeaderIfNeeded(header data.HeaderHa } proof := header.GetPreviousProof() - err := sr.EquivalentProofsPool().AddProof(proof) + err := common.VerifyProofAgainstHeader(proof, prevHeader) + if err != nil { + log.Debug("saveProofForPreviousHeaderIfNeeded: invalid proof, %w", err) + return + } + + err = sr.EquivalentProofsPool().AddProof(proof) if err != nil { log.Debug("saveProofForPreviousHeaderIfNeeded: failed to add proof, %w", err) return } + + return } // receivedBlockBody method is called when a block body is received through the block body channel @@ -445,30 +453,30 @@ func (sr *subroundBlock) receivedBlockBody(ctx context.Context, cnsDta *consensu return blockProcessedWithSuccess } -func (sr *subroundBlock) isHeaderForCurrentConsensus(header data.HeaderHandler) bool { +func (sr *subroundBlock) isHeaderForCurrentConsensus(header data.HeaderHandler) (bool, data.HeaderHandler) { if check.IfNil(header) { - return false + return false, nil } if header.GetShardID() != sr.ShardCoordinator().SelfId() { - return false + return false, nil } if header.GetRound() != uint64(sr.RoundHandler().Index()) { - return false + return false, nil } prevHeader, prevHash := sr.getPrevHeaderAndHash() if check.IfNil(prevHeader) { - return false + return false, nil } if !bytes.Equal(header.GetPrevHash(), prevHash) { - return false + return false, nil } if header.GetNonce() != prevHeader.GetNonce()+1 { - return false + return false, nil } prevRandSeed := prevHeader.GetRandSeed() - return bytes.Equal(header.GetPrevRandSeed(), prevRandSeed) + return bytes.Equal(header.GetPrevRandSeed(), prevRandSeed), prevHeader } func (sr *subroundBlock) getLeaderForHeader(headerHandler data.HeaderHandler) ([]byte, error) { @@ -495,7 +503,8 @@ func (sr *subroundBlock) receivedBlockHeader(headerHandler data.HeaderHandler) { return } - if !sr.isHeaderForCurrentConsensus(headerHandler) { + isHeaderForCurrentConsensus, prevHeader := sr.isHeaderForCurrentConsensus(headerHandler) + if !isHeaderForCurrentConsensus { return } @@ -539,7 +548,7 @@ func (sr *subroundBlock) receivedBlockHeader(headerHandler data.HeaderHandler) { sr.SetData(sr.Hasher().Compute(string(marshalledHeader))) sr.SetHeader(headerHandler) - sr.saveProofForPreviousHeaderIfNeeded(headerHandler) + sr.saveProofForPreviousHeaderIfNeeded(headerHandler, prevHeader) log.Debug("step 1: block header has been received", "nonce", sr.GetHeader().GetNonce(), diff --git a/process/block/baseProcess.go b/process/block/baseProcess.go index 969b549c1ae..9acb2f34750 100644 --- a/process/block/baseProcess.go +++ b/process/block/baseProcess.go @@ -231,28 +231,7 @@ func (bp *baseProcessor) checkPrevProofValidity(prevHeader, headerHandler data.H } prevProof := headerHandler.GetPreviousProof() - return bp.verifyProofAgainstHeader(prevProof, prevHeader) -} - -func (bp *baseProcessor) verifyProofAgainstHeader(proof data.HeaderProofHandler, header data.HeaderHandler) error { - if check.IfNilReflect(proof) { - return process.ErrMissingHeaderProof - } - - if proof.GetHeaderNonce() != header.GetNonce() { - return fmt.Errorf("%w, nonce mismatch", process.ErrInvalidHeaderProof) - } - if proof.GetHeaderShardId() != header.GetShardID() { - return fmt.Errorf("%w, shard id mismatch", process.ErrInvalidHeaderProof) - } - if proof.GetHeaderEpoch() != header.GetEpoch() { - return fmt.Errorf("%w, epoch mismatch", process.ErrInvalidHeaderProof) - } - if proof.GetHeaderRound() != header.GetRound() { - return fmt.Errorf("%w, round mismatch", process.ErrInvalidHeaderProof) - } - - return nil + return common.VerifyProofAgainstHeader(prevProof, prevHeader) } // checkScheduledRootHash checks if the scheduled root hash from the given header is the same with the current user accounts state root hash diff --git a/process/block/interceptedBlocks/interceptedEquivalentProof.go b/process/block/interceptedBlocks/interceptedEquivalentProof.go index fe5c9a71d94..44f732c0062 100644 --- a/process/block/interceptedBlocks/interceptedEquivalentProof.go +++ b/process/block/interceptedBlocks/interceptedEquivalentProof.go @@ -9,6 +9,7 @@ import ( "github.com/multiversx/mx-chain-core-go/data" "github.com/multiversx/mx-chain-core-go/data/block" "github.com/multiversx/mx-chain-core-go/marshal" + "github.com/multiversx/mx-chain-go/common" "github.com/multiversx/mx-chain-go/consensus" "github.com/multiversx/mx-chain-go/dataRetriever" proofscache "github.com/multiversx/mx-chain-go/dataRetriever/dataPool/proofsCache" @@ -136,20 +137,7 @@ func (iep *interceptedEquivalentProof) checkHeaderParamsFromProof() error { return fmt.Errorf("%w while getting header for proof hash %s", err, hex.EncodeToString(iep.proof.GetHeaderHash())) } - if iep.proof.GetHeaderNonce() != header.GetNonce() { - return fmt.Errorf("%w, nonce mismatch", ErrInvalidProof) - } - if iep.proof.GetHeaderShardId() != header.GetShardID() { - return fmt.Errorf("%w, shard id mismatch", ErrInvalidProof) - } - if iep.proof.GetHeaderEpoch() != header.GetEpoch() { - return fmt.Errorf("%w, epoch mismatch", ErrInvalidProof) - } - if iep.proof.GetHeaderRound() != header.GetRound() { - return fmt.Errorf("%w, round mismatch", ErrInvalidProof) - } - - return nil + return common.VerifyProofAgainstHeader(iep.proof, header) } func (iep *interceptedEquivalentProof) integrity() error { diff --git a/process/block/interceptedBlocks/interceptedEquivalentProof_test.go b/process/block/interceptedBlocks/interceptedEquivalentProof_test.go index f1a5e97762e..c62bd27a34b 100644 --- a/process/block/interceptedBlocks/interceptedEquivalentProof_test.go +++ b/process/block/interceptedBlocks/interceptedEquivalentProof_test.go @@ -10,6 +10,7 @@ import ( "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-core-go/data" "github.com/multiversx/mx-chain-core-go/data/block" + "github.com/multiversx/mx-chain-go/common" "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" @@ -232,7 +233,7 @@ func TestInterceptedEquivalentProof_CheckValidity(t *testing.T) { require.NoError(t, err) err = iep.CheckValidity() - require.True(t, errors.Is(err, ErrInvalidProof)) + require.True(t, errors.Is(err, common.ErrInvalidHeaderProof)) require.True(t, strings.Contains(err.Error(), "nonce mismatch")) }) @@ -257,7 +258,7 @@ func TestInterceptedEquivalentProof_CheckValidity(t *testing.T) { require.NoError(t, err) err = iep.CheckValidity() - require.True(t, errors.Is(err, ErrInvalidProof)) + require.True(t, errors.Is(err, common.ErrInvalidHeaderProof)) require.True(t, strings.Contains(err.Error(), "shard id mismatch")) }) @@ -283,7 +284,7 @@ func TestInterceptedEquivalentProof_CheckValidity(t *testing.T) { require.NoError(t, err) err = iep.CheckValidity() - require.True(t, errors.Is(err, ErrInvalidProof)) + require.True(t, errors.Is(err, common.ErrInvalidHeaderProof)) require.True(t, strings.Contains(err.Error(), "epoch mismatch")) }) @@ -310,7 +311,7 @@ func TestInterceptedEquivalentProof_CheckValidity(t *testing.T) { require.NoError(t, err) err = iep.CheckValidity() - require.True(t, errors.Is(err, ErrInvalidProof)) + require.True(t, errors.Is(err, common.ErrInvalidHeaderProof)) require.True(t, strings.Contains(err.Error(), "round mismatch")) }) diff --git a/process/block/metablock.go b/process/block/metablock.go index 5727e9d78c4..63db47aca21 100644 --- a/process/block/metablock.go +++ b/process/block/metablock.go @@ -438,7 +438,7 @@ func (mp *metaProcessor) checkProofsForShardData(header *block.MetaBlock) error return err } - err = mp.verifyProofAgainstHeader(prevProof, prevHeader) + err = common.VerifyProofAgainstHeader(prevProof, prevHeader) if err != nil { return err } diff --git a/process/errors.go b/process/errors.go index 52d5981ab07..4f786e86e39 100644 --- a/process/errors.go +++ b/process/errors.go @@ -1251,9 +1251,6 @@ var ErrEmptyChainParametersConfiguration = errors.New("empty chain parameters co // ErrNoMatchingConfigForProvidedEpoch signals that there is no matching configuration for the provided epoch var ErrNoMatchingConfigForProvidedEpoch = errors.New("no matching configuration") -// ErrInvalidHeader is raised when header is invalid -var ErrInvalidHeader = errors.New("header is invalid") - // ErrNilHeaderProof signals that a nil header proof has been provided var ErrNilHeaderProof = errors.New("nil header proof") From a1cf4c85749964714336cc9d9d5976ff90649a13 Mon Sep 17 00:00:00 2001 From: Sorin Stanculeanu Date: Mon, 13 Jan 2025 13:54:23 +0200 Subject: [PATCH 4/5] further fixes after review --- common/common.go | 27 +++++++++++++++++++ common/interface.go | 5 ++++ .../interceptedEquivalentProof.go | 25 ++++++++++++++++- .../interceptedEquivalentProof_test.go | 20 +++++++++++++- process/block/metablock.go | 7 ++++- .../baseInterceptorsContainerFactory.go | 1 + .../interceptedEquivalentProofsFactory.go | 4 +++ ...uivalentProofsInterceptorProcessor_test.go | 2 ++ 8 files changed, 88 insertions(+), 3 deletions(-) diff --git a/common/common.go b/common/common.go index 8359dcebfbf..7fb43f9e7c3 100644 --- a/common/common.go +++ b/common/common.go @@ -6,6 +6,8 @@ import ( "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-core-go/core/check" "github.com/multiversx/mx-chain-core-go/data" + "github.com/multiversx/mx-chain-go/storage" + "github.com/multiversx/mx-chain-vm-v1_2-go/ipc/marshaling" ) // IsEpochChangeBlockForFlagActivation returns true if the provided header is the first one after the specified flag's activation @@ -49,3 +51,28 @@ func VerifyProofAgainstHeader(proof data.HeaderProofHandler, header data.HeaderH return nil } + +// GetHeader tries to get the header from pool first and if not founded, searches for it through storer +func GetHeader( + headerHash []byte, + headersPool HeadersPool, + headersStorer storage.Storer, + marshaller marshaling.Marshalizer, +) (data.HeaderHandler, error) { + header, err := headersPool.GetHeaderByHash(headerHash) + if err == nil { + return header, nil + } + + headerBytes, err := headersStorer.SearchFirst(headerHash) + if err != nil { + return nil, err + } + + err = marshaller.Unmarshal(header, headerBytes) + if err != nil { + return nil, err + } + + return header, nil +} diff --git a/common/interface.go b/common/interface.go index 72a2cba2628..e3a42e0ee45 100644 --- a/common/interface.go +++ b/common/interface.go @@ -379,3 +379,8 @@ type ChainParametersSubscriptionHandler interface { ChainParametersChanged(chainParameters config.ChainParametersByEpochConfig) IsInterfaceNil() bool } + +// HeadersPool defines what a headers pool structure can perform +type HeadersPool interface { + GetHeaderByHash(hash []byte) (data.HeaderHandler, error) +} diff --git a/process/block/interceptedBlocks/interceptedEquivalentProof.go b/process/block/interceptedBlocks/interceptedEquivalentProof.go index 44f732c0062..5d3eeda8ba8 100644 --- a/process/block/interceptedBlocks/interceptedEquivalentProof.go +++ b/process/block/interceptedBlocks/interceptedEquivalentProof.go @@ -15,7 +15,9 @@ import ( proofscache "github.com/multiversx/mx-chain-go/dataRetriever/dataPool/proofsCache" "github.com/multiversx/mx-chain-go/process" "github.com/multiversx/mx-chain-go/sharding" + "github.com/multiversx/mx-chain-go/storage" logger "github.com/multiversx/mx-chain-logger-go" + "github.com/multiversx/mx-chain-vm-v1_2-go/ipc/marshaling" ) const interceptedEquivalentProofType = "intercepted equivalent proof" @@ -28,6 +30,7 @@ type ArgInterceptedEquivalentProof struct { HeaderSigVerifier consensus.HeaderSigVerifier Proofs dataRetriever.ProofsPool Headers dataRetriever.HeadersPool + Storage dataRetriever.StorageService } type interceptedEquivalentProof struct { @@ -36,6 +39,8 @@ type interceptedEquivalentProof struct { headerSigVerifier consensus.HeaderSigVerifier proofsPool dataRetriever.ProofsPool headersPool dataRetriever.HeadersPool + storage dataRetriever.StorageService + marshaller marshaling.Marshalizer } // NewInterceptedEquivalentProof returns a new instance of interceptedEquivalentProof @@ -56,6 +61,8 @@ func NewInterceptedEquivalentProof(args ArgInterceptedEquivalentProof) (*interce headerSigVerifier: args.HeaderSigVerifier, proofsPool: args.Proofs, headersPool: args.Headers, + marshaller: args.Marshaller, + storage: args.Storage, }, nil } @@ -78,6 +85,9 @@ func checkArgInterceptedEquivalentProof(args ArgInterceptedEquivalentProof) erro if check.IfNil(args.Headers) { return process.ErrNilHeadersDataPool } + if check.IfNil(args.Storage) { + return process.ErrNilStore + } return nil } @@ -132,7 +142,12 @@ func (iep *interceptedEquivalentProof) CheckValidity() error { } func (iep *interceptedEquivalentProof) checkHeaderParamsFromProof() error { - header, err := iep.headersPool.GetHeaderByHash(iep.proof.GetHeaderHash()) + headersStorer, err := iep.getHeadersStorer(iep.proof.GetHeaderShardId()) + if err != nil { + return err + } + + header, err := common.GetHeader(iep.proof.GetHeaderHash(), iep.headersPool, headersStorer, iep.marshaller) if err != nil { return fmt.Errorf("%w while getting header for proof hash %s", err, hex.EncodeToString(iep.proof.GetHeaderHash())) } @@ -151,6 +166,14 @@ func (iep *interceptedEquivalentProof) integrity() error { return nil } +func (iep *interceptedEquivalentProof) getHeadersStorer(shardID uint32) (storage.Storer, error) { + if shardID == core.MetachainShardId { + return iep.storage.GetStorer(dataRetriever.MetaBlockUnit) + } + + return iep.storage.GetStorer(dataRetriever.BlockHeaderUnit) +} + // GetProof returns the underlying intercepted header proof func (iep *interceptedEquivalentProof) GetProof() data.HeaderProofHandler { return iep.proof diff --git a/process/block/interceptedBlocks/interceptedEquivalentProof_test.go b/process/block/interceptedBlocks/interceptedEquivalentProof_test.go index c62bd27a34b..3d1a96afd17 100644 --- a/process/block/interceptedBlocks/interceptedEquivalentProof_test.go +++ b/process/block/interceptedBlocks/interceptedEquivalentProof_test.go @@ -14,9 +14,11 @@ import ( "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/storage" "github.com/multiversx/mx-chain-go/testscommon" "github.com/multiversx/mx-chain-go/testscommon/consensus" "github.com/multiversx/mx-chain-go/testscommon/dataRetriever" + "github.com/multiversx/mx-chain-go/testscommon/genericMocks" "github.com/multiversx/mx-chain-go/testscommon/marshallerMock" "github.com/multiversx/mx-chain-go/testscommon/pool" logger "github.com/multiversx/mx-chain-logger-go" @@ -68,6 +70,10 @@ func createMockArgInterceptedEquivalentProof() ArgInterceptedEquivalentProof { }, nil }, }, + Storage: &genericMocks.ChainStorerMock{ + BlockHeaders: genericMocks.NewStorerMock(), + Metablocks: genericMocks.NewStorerMock(), + }, } } @@ -151,6 +157,15 @@ func TestNewInterceptedEquivalentProof(t *testing.T) { require.Equal(t, expectedErr, err) require.Nil(t, iep) }) + t.Run("nil storage should error", func(t *testing.T) { + t.Parallel() + + args := createMockArgInterceptedEquivalentProof() + args.Storage = nil + iep, err := NewInterceptedEquivalentProof(args) + require.Equal(t, process.ErrNilStore, err) + require.Nil(t, iep) + }) t.Run("should work", func(t *testing.T) { t.Parallel() @@ -207,12 +222,15 @@ func TestInterceptedEquivalentProof_CheckValidity(t *testing.T) { return nil, providedErr }, } + args.Storage = &genericMocks.ChainStorerMock{ + BlockHeaders: genericMocks.NewStorerMockWithErrKeyNotFound(0), + } iep, err := NewInterceptedEquivalentProof(args) require.NoError(t, err) err = iep.CheckValidity() - require.True(t, errors.Is(err, providedErr)) + require.True(t, errors.Is(err, storage.ErrKeyNotFound)) }) t.Run("nonce mismatch should error", func(t *testing.T) { diff --git a/process/block/metablock.go b/process/block/metablock.go index 63db47aca21..75ffe1a2f6d 100644 --- a/process/block/metablock.go +++ b/process/block/metablock.go @@ -431,9 +431,14 @@ func (mp *metaProcessor) checkProofsForShardData(header *block.MetaBlock) error return fmt.Errorf("%w for header hash %s", process.ErrMissingHeaderProof, hex.EncodeToString(shardData.HeaderHash)) } + shardHeadersStorer, err := mp.store.GetStorer(dataRetriever.BlockHeaderUnit) + if err != nil { + return err + } + prevProof := shardData.GetPreviousProof() headersPool := mp.dataPool.Headers() - prevHeader, err := headersPool.GetHeaderByHash(prevProof.GetHeaderHash()) + prevHeader, err := common.GetHeader(prevProof.GetHeaderHash(), headersPool, shardHeadersStorer, mp.marshalizer) if err != nil { return err } diff --git a/process/factory/interceptorscontainer/baseInterceptorsContainerFactory.go b/process/factory/interceptorscontainer/baseInterceptorsContainerFactory.go index 0c8fdd511ea..271f2ac26aa 100644 --- a/process/factory/interceptorscontainer/baseInterceptorsContainerFactory.go +++ b/process/factory/interceptorscontainer/baseInterceptorsContainerFactory.go @@ -917,6 +917,7 @@ func (bicf *baseInterceptorsContainerFactory) createOneShardEquivalentProofsInte ArgInterceptedDataFactory: *bicf.argInterceptorFactory, ProofsPool: bicf.dataPool.Proofs(), HeadersPool: bicf.dataPool.Headers(), + Storage: bicf.store, } equivalentProofsFactory := interceptorFactory.NewInterceptedEquivalentProofsFactory(args) diff --git a/process/interceptors/factory/interceptedEquivalentProofsFactory.go b/process/interceptors/factory/interceptedEquivalentProofsFactory.go index fae4b1d5a4d..f1ba5a150ff 100644 --- a/process/interceptors/factory/interceptedEquivalentProofsFactory.go +++ b/process/interceptors/factory/interceptedEquivalentProofsFactory.go @@ -14,6 +14,7 @@ type ArgInterceptedEquivalentProofsFactory struct { ArgInterceptedDataFactory ProofsPool dataRetriever.ProofsPool HeadersPool dataRetriever.HeadersPool + Storage dataRetriever.StorageService } type interceptedEquivalentProofsFactory struct { @@ -22,6 +23,7 @@ type interceptedEquivalentProofsFactory struct { headerSigVerifier consensus.HeaderSigVerifier proofsPool dataRetriever.ProofsPool headersPool dataRetriever.HeadersPool + storage dataRetriever.StorageService } // NewInterceptedEquivalentProofsFactory creates a new instance of interceptedEquivalentProofsFactory @@ -32,6 +34,7 @@ func NewInterceptedEquivalentProofsFactory(args ArgInterceptedEquivalentProofsFa headerSigVerifier: args.HeaderSigVerifier, proofsPool: args.ProofsPool, headersPool: args.HeadersPool, + storage: args.Storage, } } @@ -44,6 +47,7 @@ func (factory *interceptedEquivalentProofsFactory) Create(buff []byte) (process. HeaderSigVerifier: factory.headerSigVerifier, Proofs: factory.proofsPool, Headers: factory.headersPool, + Storage: factory.storage, } return interceptedBlocks.NewInterceptedEquivalentProof(args) } diff --git a/process/interceptors/processor/equivalentProofsInterceptorProcessor_test.go b/process/interceptors/processor/equivalentProofsInterceptorProcessor_test.go index 5b9e3f04c57..320262fb581 100644 --- a/process/interceptors/processor/equivalentProofsInterceptorProcessor_test.go +++ b/process/interceptors/processor/equivalentProofsInterceptorProcessor_test.go @@ -11,6 +11,7 @@ import ( "github.com/multiversx/mx-chain-go/process/transaction" "github.com/multiversx/mx-chain-go/testscommon/consensus" "github.com/multiversx/mx-chain-go/testscommon/dataRetriever" + "github.com/multiversx/mx-chain-go/testscommon/genericMocks" "github.com/multiversx/mx-chain-go/testscommon/marshallerMock" "github.com/multiversx/mx-chain-go/testscommon/pool" "github.com/stretchr/testify/require" @@ -107,6 +108,7 @@ func TestEquivalentProofsInterceptorProcessor_Save(t *testing.T) { HeaderSigVerifier: &consensus.HeaderSigVerifierMock{}, Proofs: &dataRetriever.ProofsPoolMock{}, Headers: &pool.HeadersPoolStub{}, + Storage: &genericMocks.ChainStorerMock{}, } argInterceptedEquivalentProof.DataBuff, _ = argInterceptedEquivalentProof.Marshaller.Marshal(&block.HeaderProof{ PubKeysBitmap: []byte("bitmap"), From 3db5c03ff0f1392834adf96f3260638fc91eec75 Mon Sep 17 00:00:00 2001 From: Sorin Stanculeanu Date: Mon, 13 Jan 2025 18:13:45 +0200 Subject: [PATCH 5/5] fixed typo --- common/common.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/common.go b/common/common.go index 7fb43f9e7c3..3d5e874c231 100644 --- a/common/common.go +++ b/common/common.go @@ -52,7 +52,7 @@ func VerifyProofAgainstHeader(proof data.HeaderProofHandler, header data.HeaderH return nil } -// GetHeader tries to get the header from pool first and if not founded, searches for it through storer +// GetHeader tries to get the header from pool first and if not found, searches for it through storer func GetHeader( headerHash []byte, headersPool HeadersPool,