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..724362050d9 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+200; 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 }, }, }) @@ -354,29 +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 < 50; i++ { + for i := 1; i < 300; i++ { incomingHdr := addIncomingHeader(t, nodeHandler, &incomingHdrNonce, prevHeader) extendedHeaderHashes = append(extendedHeaderHashes, getExtendedHeaderHash(t, nodeHandler, incomingHdr)) 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) + 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) 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 { diff --git a/process/track/sovereignChainBlockProcessor.go b/process/track/sovereignChainBlockProcessor.go index 246e8aa342c..de2cdc229f6 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) diff --git a/process/track/sovereignChainBlockProcessor_test.go b/process/track/sovereignChainBlockProcessor_test.go index 89fab6b0fc2..99f1af149d2 100644 --- a/process/track/sovereignChainBlockProcessor_test.go +++ b/process/track/sovereignChainBlockProcessor_test.go @@ -264,18 +264,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) {