From f4ba6ae4fce4213ee1f1f289ccf11b9e13a809bb Mon Sep 17 00:00:00 2001 From: MariusC Date: Tue, 5 Nov 2024 15:42:07 +0200 Subject: [PATCH 1/3] FIX: Do not request incoming headers upon receiving --- .../chainSimulator/common/common.go | 28 ++++++++++ .../chainSimulator/sovereignChainSimulator.go | 31 ++--------- .../tests/processBlock/incomingHeader_test.go | 55 +++++++++++++++---- process/track/sovereignChainBlockProcessor.go | 4 ++ 4 files changed, 81 insertions(+), 37 deletions(-) diff --git a/cmd/sovereignnode/chainSimulator/common/common.go b/cmd/sovereignnode/chainSimulator/common/common.go index e478c9a1a03..6b1781b4a7a 100644 --- a/cmd/sovereignnode/chainSimulator/common/common.go +++ b/cmd/sovereignnode/chainSimulator/common/common.go @@ -2,10 +2,38 @@ package common import ( "github.com/multiversx/mx-chain-core-go/data" + "github.com/multiversx/mx-chain-go/config" + "github.com/multiversx/mx-chain-go/factory" + "github.com/multiversx/mx-chain-go/factory/runType" "github.com/multiversx/mx-chain-go/node/chainSimulator/process" + sovRunType "github.com/multiversx/mx-chain-go/sovereignnode/runType" ) // GetCurrentSovereignHeader returns current sovereign chain block handler from blockchain hook func GetCurrentSovereignHeader(nodeHandler process.NodeHandler) data.SovereignChainHeaderHandler { return nodeHandler.GetChainHandler().GetCurrentBlockHeader().(data.SovereignChainHeaderHandler) } + +// CreateSovereignRunTypeComponents will create sovereign run type components +func CreateSovereignRunTypeComponents(args runType.ArgsRunTypeComponents, sovereignExtraConfig config.SovereignConfig) (factory.RunTypeComponentsHolder, error) { + argsSovRunType, err := sovRunType.CreateSovereignArgsRunTypeComponents(args, sovereignExtraConfig) + if err != nil { + return nil, err + } + + sovereignComponentsFactory, err := runType.NewSovereignRunTypeComponentsFactory(*argsSovRunType) + if err != nil { + return nil, err + } + + managedRunTypeComponents, err := runType.NewManagedRunTypeComponents(sovereignComponentsFactory) + if err != nil { + return nil, err + } + err = managedRunTypeComponents.Create() + if err != nil { + return nil, err + } + + return managedRunTypeComponents, nil +} diff --git a/cmd/sovereignnode/chainSimulator/sovereignChainSimulator.go b/cmd/sovereignnode/chainSimulator/sovereignChainSimulator.go index 74cdd9c5d0e..a7cbc539e23 100644 --- a/cmd/sovereignnode/chainSimulator/sovereignChainSimulator.go +++ b/cmd/sovereignnode/chainSimulator/sovereignChainSimulator.go @@ -13,8 +13,8 @@ import ( "github.com/multiversx/mx-chain-go/node/chainSimulator" "github.com/multiversx/mx-chain-go/process" "github.com/multiversx/mx-chain-go/process/block/sovereign/incomingHeader" + sovCommon "github.com/multiversx/mx-chain-go/sovereignnode/chainSimulator/common" sovereignConfig "github.com/multiversx/mx-chain-go/sovereignnode/config" - sovRunType "github.com/multiversx/mx-chain-go/sovereignnode/runType" ) const ( @@ -57,8 +57,10 @@ func NewSovereignChainSimulator(args ArgsSovereignChainSimulator) (chainSimulato args.CreateIncomingHeaderSubscriber = func(config config.WebSocketConfig, dataPool dataRetriever.PoolsHolder, mainChainNotarizationStartRound uint64, runTypeComponents factory.RunTypeComponentsHolder) (process.IncomingHeaderSubscriber, error) { return incomingHeader.CreateIncomingHeaderProcessor(config, dataPool, mainChainNotarizationStartRound, runTypeComponents) } - args.CreateRunTypeComponents = func(argsRunType runType.ArgsRunTypeComponents) (factory.RunTypeComponentsHolder, error) { - return createSovereignRunTypeComponents(argsRunType, *configs.SovereignExtraConfig) + if args.CreateRunTypeComponents == nil { + args.CreateRunTypeComponents = func(args runType.ArgsRunTypeComponents) (factory.RunTypeComponentsHolder, error) { + return sovCommon.CreateSovereignRunTypeComponents(args, *configs.SovereignExtraConfig) + } } args.NodeFactory = node.NewSovereignNodeFactory(configs.SovereignExtraConfig.GenesisConfig.NativeESDT) args.ChainProcessorFactory = NewSovereignChainHandlerFactory() @@ -105,26 +107,3 @@ func createSovereignRunTypeCoreComponents() (factory.RunTypeCoreComponentsHolder return managedRunTypeCoreComponents, nil } - -func createSovereignRunTypeComponents(args runType.ArgsRunTypeComponents, sovereignExtraConfig config.SovereignConfig) (factory.RunTypeComponentsHolder, error) { - argsSovRunType, err := sovRunType.CreateSovereignArgsRunTypeComponents(args, sovereignExtraConfig) - if err != nil { - return nil, err - } - - sovereignComponentsFactory, err := runType.NewSovereignRunTypeComponentsFactory(*argsSovRunType) - if err != nil { - return nil, err - } - - managedRunTypeComponents, err := runType.NewManagedRunTypeComponents(sovereignComponentsFactory) - if err != nil { - return nil, err - } - err = managedRunTypeComponents.Create() - if err != nil { - return nil, err - } - - return managedRunTypeComponents, nil -} diff --git a/cmd/sovereignnode/chainSimulator/tests/processBlock/incomingHeader_test.go b/cmd/sovereignnode/chainSimulator/tests/processBlock/incomingHeader_test.go index b1de79654b9..331d6feef00 100644 --- a/cmd/sovereignnode/chainSimulator/tests/processBlock/incomingHeader_test.go +++ b/cmd/sovereignnode/chainSimulator/tests/processBlock/incomingHeader_test.go @@ -14,9 +14,15 @@ import ( "github.com/multiversx/mx-chain-core-go/data/sovereign" "github.com/multiversx/mx-chain-core-go/data/transaction" "github.com/multiversx/mx-chain-go/config" + "github.com/multiversx/mx-chain-go/dataRetriever/requestHandlers" + "github.com/multiversx/mx-chain-go/factory" + "github.com/multiversx/mx-chain-go/factory/runType" proc "github.com/multiversx/mx-chain-go/process" "github.com/multiversx/mx-chain-go/process/block/sovereign/incomingHeader" "github.com/multiversx/mx-chain-go/sovereignnode/chainSimulator/common" + "github.com/multiversx/mx-chain-go/testscommon" + "github.com/multiversx/mx-chain-go/testscommon/components" + factory2 "github.com/multiversx/mx-chain-go/testscommon/factory" "github.com/stretchr/testify/require" chainSim "github.com/multiversx/mx-chain-go/integrationTests/chainSimulator" @@ -145,7 +151,7 @@ func TestSovereignChainSimulator_AddIncomingHeaderCase1(t *testing.T) { var prevSovHdr data.SovereignChainHeaderHandler var previousExtendedHeader data.HeaderHandler - for currIncomingHeaderRound := startRound - 5; currIncomingHeaderRound < startRound+40; currIncomingHeaderRound++ { + for currIncomingHeaderRound := startRound - 5; currIncomingHeaderRound < startRound+1500; currIncomingHeaderRound++ { // Handlers are notified on go routines; wait a bit so that pools are updated incomingHdr := addIncomingHeader(t, nodeHandler, &incomingHdrNonce, prevIncomingHeader) @@ -306,6 +312,22 @@ func TestSovereignChainSimulator_AddIncomingHeaderCase3(t *testing.T) { } startRound := uint64(101) + sovConfig := config.SovereignConfig{} + + sovRequestHandler := &testscommon.ExtendedShardHeaderRequestHandlerStub{ + RequestExtendedShardHeaderCalled: func(hash []byte) { + require.Fail(t, "should not request any extended header") + }, + RequestExtendedShardHeaderByNonceCalled: func(nonce uint64) { + require.Fail(t, "should not request any extended header") + }, + } + sovRequestHandlerFactory := &factory2.RequestHandlerFactoryMock{ + CreateRequestHandlerCalled: func(args requestHandlers.RequestHandlerArgs) (proc.RequestHandler, error) { + return sovRequestHandler, nil + }, + } + cs, err := sovereignChainSimulator.NewSovereignChainSimulator(sovereignChainSimulator.ArgsSovereignChainSimulator{ SovereignConfigPath: sovereignConfigPath, ArgsChainSimulator: &chainSimulator.ArgsChainSimulator{ @@ -319,9 +341,19 @@ func TestSovereignChainSimulator_AddIncomingHeaderCase3(t *testing.T) { HasValue: true, }, ApiInterface: api.NewNoApiInterface(), - MinNodesPerShard: 2, + MinNodesPerShard: 1, AlterConfigsFunction: func(cfg *config.Configs) { cfg.GeneralConfig.SovereignConfig.MainChainNotarization.MainChainNotarizationStartRound = startRound + sovConfig = cfg.GeneralConfig.SovereignConfig + }, + CreateRunTypeComponents: func(args runType.ArgsRunTypeComponents) (factory.RunTypeComponentsHolder, error) { + runTypeComps, err := common.CreateSovereignRunTypeComponents(args, sovConfig) + require.Nil(t, err) + + runTypeCompsHolder := components.GetRunTypeComponentsStub(runTypeComps) + runTypeCompsHolder.RequestHandlerFactory = sovRequestHandlerFactory + + return runTypeCompsHolder, nil }, }, }) @@ -355,25 +387,26 @@ func TestSovereignChainSimulator_AddIncomingHeaderCase3(t *testing.T) { require.Empty(t, currentSovBlock.GetExtendedShardHeaderHashes()) extendedHeaderHashes := make([][]byte, 0) - // From now on, we generate 3 incoming headers per sovereign block - for i := 1; i < 50; i++ { + for i := 1; i < 100; i++ { incomingHdr := addIncomingHeader(t, nodeHandler, &incomingHdrNonce, prevHeader) extendedHeaderHashes = append(extendedHeaderHashes, getExtendedHeaderHash(t, nodeHandler, incomingHdr)) + //time.Sleep(time.Millisecond * 50) + if i%3 == 0 { err = cs.GenerateBlocks(1) require.Nil(t, err) - currentSovBlock = common.GetCurrentSovereignHeader(nodeHandler) - require.Len(t, extendedHeaderHashes, 3) - require.Equal(t, extendedHeaderHashes, currentSovBlock.GetExtendedShardHeaderHashes()) - - lastCrossNotarizedRound += 3 - extendedHeaderHashes = make([][]byte, 0) + //currentSovBlock = common.GetCurrentSovereignHeader(nodeHandler) + //require.Len(t, extendedHeaderHashes, 3) + //require.Equal(t, extendedHeaderHashes, currentSovBlock.GetExtendedShardHeaderHashes()) + // + //lastCrossNotarizedRound += 3 + //extendedHeaderHashes = make([][]byte, 0) } - checkLastCrossNotarizedRound(t, sovBlockTracker, lastCrossNotarizedRound) + //checkLastCrossNotarizedRound(t, sovBlockTracker, lastCrossNotarizedRound) prevHeader = incomingHdr.Header } diff --git a/process/track/sovereignChainBlockProcessor.go b/process/track/sovereignChainBlockProcessor.go index c03bba38b97..04f75ba957d 100644 --- a/process/track/sovereignChainBlockProcessor.go +++ b/process/track/sovereignChainBlockProcessor.go @@ -82,6 +82,10 @@ func (scbp *sovereignChainBlockProcessor) processReceivedHeader(headerHandler da } func (scbp *sovereignChainBlockProcessor) doJobOnReceivedCrossNotarizedHeader(shardID uint32) { + if scbp.crossNotarizedHeadersNotifier.GetNumRegisteredHandlers() == 0 { + return + } + _, _, crossNotarizedHeaders, crossNotarizedHeadersHashes := scbp.computeLongestChainFromLastCrossNotarized(shardID) if len(crossNotarizedHeaders) > 0 { scbp.crossNotarizedHeadersNotifier.CallHandlers(shardID, crossNotarizedHeaders, crossNotarizedHeadersHashes) From feac147ae296dacb2f0e3af0ab43077f17945854 Mon Sep 17 00:00:00 2001 From: MariusC Date: Tue, 5 Nov 2024 16:58:40 +0200 Subject: [PATCH 2/3] FEAT: Extend test case 3 for incoming header to not request other headers --- .../tests/processBlock/incomingHeader_test.go | 38 +++++++++++++------ 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/cmd/sovereignnode/chainSimulator/tests/processBlock/incomingHeader_test.go b/cmd/sovereignnode/chainSimulator/tests/processBlock/incomingHeader_test.go index 331d6feef00..724362050d9 100644 --- a/cmd/sovereignnode/chainSimulator/tests/processBlock/incomingHeader_test.go +++ b/cmd/sovereignnode/chainSimulator/tests/processBlock/incomingHeader_test.go @@ -151,7 +151,7 @@ func TestSovereignChainSimulator_AddIncomingHeaderCase1(t *testing.T) { var prevSovHdr data.SovereignChainHeaderHandler var previousExtendedHeader data.HeaderHandler - for currIncomingHeaderRound := startRound - 5; currIncomingHeaderRound < startRound+1500; currIncomingHeaderRound++ { + for currIncomingHeaderRound := startRound - 5; currIncomingHeaderRound < startRound+200; currIncomingHeaderRound++ { // Handlers are notified on go routines; wait a bit so that pools are updated incomingHdr := addIncomingHeader(t, nodeHandler, &incomingHdrNonce, prevIncomingHeader) @@ -386,30 +386,46 @@ func TestSovereignChainSimulator_AddIncomingHeaderCase3(t *testing.T) { currentSovBlock := common.GetCurrentSovereignHeader(nodeHandler) require.Empty(t, currentSovBlock.GetExtendedShardHeaderHashes()) + prevSovBlock := currentSovBlock extendedHeaderHashes := make([][]byte, 0) // From now on, we generate 3 incoming headers per sovereign block - for i := 1; i < 100; i++ { + for i := 1; i < 300; i++ { incomingHdr := addIncomingHeader(t, nodeHandler, &incomingHdrNonce, prevHeader) extendedHeaderHashes = append(extendedHeaderHashes, getExtendedHeaderHash(t, nodeHandler, incomingHdr)) - //time.Sleep(time.Millisecond * 50) - if i%3 == 0 { + time.Sleep(time.Millisecond * 50) + err = cs.GenerateBlocks(1) require.Nil(t, err) - //currentSovBlock = common.GetCurrentSovereignHeader(nodeHandler) - //require.Len(t, extendedHeaderHashes, 3) - //require.Equal(t, extendedHeaderHashes, currentSovBlock.GetExtendedShardHeaderHashes()) - // - //lastCrossNotarizedRound += 3 - //extendedHeaderHashes = make([][]byte, 0) + currentSovBlock = common.GetCurrentSovereignHeader(nodeHandler) + + if currentSovBlock.IsStartOfEpochBlock() { + require.Empty(t, currentSovBlock.GetExtendedShardHeaderHashes()) + } else if prevSovBlock.IsStartOfEpochBlock() { + require.Len(t, currentSovBlock.GetExtendedShardHeaderHashes(), 6) + require.Equal(t, extendedHeaderHashes, currentSovBlock.GetExtendedShardHeaderHashes()) + + lastCrossNotarizedRound += 6 + extendedHeaderHashes = make([][]byte, 0) + } else { + require.Len(t, currentSovBlock.GetExtendedShardHeaderHashes(), 3) + require.Equal(t, extendedHeaderHashes, currentSovBlock.GetExtendedShardHeaderHashes()) + + lastCrossNotarizedRound += 3 + extendedHeaderHashes = make([][]byte, 0) + } + } - //checkLastCrossNotarizedRound(t, sovBlockTracker, lastCrossNotarizedRound) + checkLastCrossNotarizedRound(t, sovBlockTracker, lastCrossNotarizedRound) prevHeader = incomingHdr.Header + prevSovBlock = currentSovBlock } + require.Equal(t, uint32(4), nodeHandler.GetCoreComponents().EpochNotifier().CurrentEpoch()) + } func getExtendedHeader(t *testing.T, nodeHandler process.NodeHandler, incomingHdr *sovereign.IncomingHeader) data.HeaderHandler { From bedd1042379cbb86996cbfe6f11b29e9f3158e0e Mon Sep 17 00:00:00 2001 From: MariusC Date: Tue, 5 Nov 2024 17:18:33 +0200 Subject: [PATCH 3/3] FIX: Unit test --- process/track/sovereignChainBlockProcessor_test.go | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/process/track/sovereignChainBlockProcessor_test.go b/process/track/sovereignChainBlockProcessor_test.go index cfea5069ee9..7af589a0ccb 100644 --- a/process/track/sovereignChainBlockProcessor_test.go +++ b/process/track/sovereignChainBlockProcessor_test.go @@ -263,18 +263,30 @@ func TestSovereignChainBlockProcessor_DoJobOnReceivedCrossNotarizedHeaderShouldW } wasCalled := false + getNumRegisteredHandlersCalledCt := 0 blockProcessorArguments.CrossNotarizedHeadersNotifier = &mock.BlockNotifierHandlerStub{ CallHandlersCalled: func(shardID uint32, headers []data.HeaderHandler, headersHashes [][]byte) { wasCalled = true }, + GetNumRegisteredHandlersCalled: func() int { + defer func() { + getNumRegisteredHandlersCalledCt++ + }() + + return getNumRegisteredHandlersCalledCt + }, } bp, _ := track.NewBlockProcessor(blockProcessorArguments) scbp, _ := track.NewSovereignChainBlockProcessor(bp) scbp.DoJobOnReceivedCrossNotarizedHeader(core.SovereignChainShardId) + require.False(t, wasCalled) + require.Equal(t, 1, getNumRegisteredHandlersCalledCt) - assert.True(t, wasCalled) + scbp.DoJobOnReceivedCrossNotarizedHeader(core.SovereignChainShardId) + require.True(t, wasCalled) + require.Equal(t, 2, getNumRegisteredHandlersCalledCt) } func TestSovereignChainBlockProcessor_RequestHeadersShouldAddAndRequestForShardHeaders(t *testing.T) {