From 065db180a5c528b4b8ef704bb78b54c8a0520d6d Mon Sep 17 00:00:00 2001 From: miiu Date: Fri, 15 Nov 2024 10:39:02 +0200 Subject: [PATCH 1/8] heart beats in chain simulator --- cmd/node/config/external.toml | 4 +-- node/chainSimulator/chainSimulator_test.go | 6 +++++ node/chainSimulator/components/nodeFacade.go | 26 ++++++++++++++++++++ 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/cmd/node/config/external.toml b/cmd/node/config/external.toml index 6fbbbb195c6..73bc78bae55 100644 --- a/cmd/node/config/external.toml +++ b/cmd/node/config/external.toml @@ -12,8 +12,8 @@ Username = "" Password = "" # EnabledIndexes represents a slice of indexes that will be enabled for indexing. Full list is: - # ["rating", "transactions", "blocks", "validators", "miniblocks", "rounds", "accounts", "accountshistory", "receipts", "scresults", "accountsesdt", "accountsesdthistory", "epochinfo", "scdeploys", "tokens", "tags", "logs", "delegators", "operations", "esdts"] - EnabledIndexes = ["rating", "transactions", "blocks", "validators", "miniblocks", "rounds", "accounts", "accountshistory", "receipts", "scresults", "accountsesdt", "accountsesdthistory", "epochinfo", "scdeploys", "tokens", "tags", "logs", "delegators", "operations", "esdts"] + # ["rating", "transactions", "blocks", "validators", "miniblocks", "rounds", "accounts", "accountshistory", "receipts", "scresults", "accountsesdt", "accountsesdthistory", "epochinfo", "scdeploys", "tokens", "tags", "logs", "delegators", "operations", "esdts", "events"] + EnabledIndexes = ["rating", "transactions", "blocks", "validators", "miniblocks", "rounds", "accounts", "accountshistory", "receipts", "scresults", "accountsesdt", "accountsesdthistory", "epochinfo", "scdeploys", "tokens", "tags", "logs", "delegators", "operations", "esdts", "events"] # EventNotifierConnector defines settings needed to configure and launch the event notifier component # HTTP event notifier connector integration will be DEPRECATED in the following iterations diff --git a/node/chainSimulator/chainSimulator_test.go b/node/chainSimulator/chainSimulator_test.go index 18f54ccbfe9..fde143eb3e5 100644 --- a/node/chainSimulator/chainSimulator_test.go +++ b/node/chainSimulator/chainSimulator_test.go @@ -83,6 +83,12 @@ func TestChainSimulator_GenerateBlocksShouldWork(t *testing.T) { require.Nil(t, err) require.NotNil(t, chainSimulator) + time.Sleep(time.Second) + + heartBeats, err := chainSimulator.GetNodeHandler(0).GetFacadeHandler().GetHeartbeats() + require.Nil(t, err) + require.Equal(t, 1, len(heartBeats)) + defer chainSimulator.Close() time.Sleep(time.Second) diff --git a/node/chainSimulator/components/nodeFacade.go b/node/chainSimulator/components/nodeFacade.go index d62814fdf03..44dd39b2999 100644 --- a/node/chainSimulator/components/nodeFacade.go +++ b/node/chainSimulator/components/nodeFacade.go @@ -3,6 +3,7 @@ package components import ( "errors" "fmt" + "github.com/multiversx/mx-chain-go/factory/heartbeat" "strconv" "time" @@ -73,6 +74,30 @@ func (node *testOnlyProcessingNode) createFacade(configs config.Configs, apiInte flagsConfig := configs.FlagsConfig + heartBeatComponentsFactory, err := heartbeat.NewHeartbeatV2ComponentsFactory(heartbeat.ArgHeartbeatV2ComponentsFactory{ + Config: *configs.GeneralConfig, + Prefs: *configs.PreferencesConfig, + BaseVersion: "1", + AppVersion: "1", + BootstrapComponents: node.BootstrapComponentsHolder, + CoreComponents: node.CoreComponentsHolder, + DataComponents: node.DataComponentsHolder, + NetworkComponents: node.NetworkComponentsHolder, + CryptoComponents: node.CryptoComponentsHolder, + ProcessComponents: node.ProcessComponentsHolder, + StatusCoreComponents: node.StatusCoreComponents, + }) + + managedHeartbeatV2Components, err := heartbeat.NewManagedHeartbeatV2Components(heartBeatComponentsFactory) + if err != nil { + return err + } + + err = managedHeartbeatV2Components.Create() + if err != nil { + return err + } + nd, err := nodePack.NewNode( nodePack.WithStatusCoreComponents(node.StatusCoreComponents), nodePack.WithCoreComponents(node.CoreComponentsHolder), @@ -95,6 +120,7 @@ func (node *testOnlyProcessingNode) createFacade(configs config.Configs, apiInte nodePack.WithNodeStopChannel(node.CoreComponentsHolder.ChanStopNodeProcess()), nodePack.WithImportMode(configs.ImportDbConfig.IsImportDBMode), nodePack.WithESDTNFTStorageHandler(node.ProcessComponentsHolder.ESDTDataStorageHandlerForAPI()), + nodePack.WithHeartbeatV2Components(managedHeartbeatV2Components), ) if err != nil { return errors.New("error creating node: " + err.Error()) From 38d41ac23dc64a3d55670e3885577854d5568761 Mon Sep 17 00:00:00 2001 From: miiu Date: Fri, 15 Nov 2024 10:39:28 +0200 Subject: [PATCH 2/8] fix imports --- node/chainSimulator/components/nodeFacade.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node/chainSimulator/components/nodeFacade.go b/node/chainSimulator/components/nodeFacade.go index 44dd39b2999..14218befefa 100644 --- a/node/chainSimulator/components/nodeFacade.go +++ b/node/chainSimulator/components/nodeFacade.go @@ -3,7 +3,6 @@ package components import ( "errors" "fmt" - "github.com/multiversx/mx-chain-go/factory/heartbeat" "strconv" "time" @@ -14,6 +13,7 @@ import ( "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/facade" apiComp "github.com/multiversx/mx-chain-go/factory/api" + "github.com/multiversx/mx-chain-go/factory/heartbeat" nodePack "github.com/multiversx/mx-chain-go/node" "github.com/multiversx/mx-chain-go/node/metrics" "github.com/multiversx/mx-chain-go/process/mock" From c1bcc7e03d1420c5e42f27000ab54d883039cc60 Mon Sep 17 00:00:00 2001 From: miiu Date: Fri, 15 Nov 2024 11:47:47 +0200 Subject: [PATCH 3/8] index validators chain simulator --- .../components/statusComponents.go | 53 ++++++++++++++++--- .../components/testOnlyProcessingNode.go | 7 ++- 2 files changed, 52 insertions(+), 8 deletions(-) diff --git a/node/chainSimulator/components/statusComponents.go b/node/chainSimulator/components/statusComponents.go index be094472fc1..ab62c86581f 100644 --- a/node/chainSimulator/components/statusComponents.go +++ b/node/chainSimulator/components/statusComponents.go @@ -3,6 +3,12 @@ package components import ( "context" "fmt" + nodeData "github.com/multiversx/mx-chain-core-go/data" + outportCore "github.com/multiversx/mx-chain-core-go/data/outport" + "github.com/multiversx/mx-chain-go/epochStart" + "github.com/multiversx/mx-chain-go/epochStart/notifier" + "github.com/multiversx/mx-chain-go/factory" + "github.com/multiversx/mx-chain-go/sharding/nodesCoordinator" "sync" "time" @@ -17,7 +23,7 @@ import ( "github.com/multiversx/mx-chain-go/errors" "github.com/multiversx/mx-chain-go/integrationTests/mock" "github.com/multiversx/mx-chain-go/outport" - "github.com/multiversx/mx-chain-go/outport/factory" + outportFactory "github.com/multiversx/mx-chain-go/outport/factory" "github.com/multiversx/mx-chain-go/process" "github.com/multiversx/mx-chain-go/testscommon" ) @@ -32,10 +38,11 @@ type statusComponentsHolder struct { statusPollingIntervalSec int cancelFunc func() mutex sync.RWMutex + nodesCoordinator nodesCoordinator.NodesCoordinator } // CreateStatusComponents will create a new instance of status components holder -func CreateStatusComponents(shardID uint32, appStatusHandler core.AppStatusHandler, statusPollingIntervalSec int, external config.ExternalConfig, coreComponents process.CoreComponentsHolder) (*statusComponentsHolder, error) { +func CreateStatusComponents(shardID uint32, appStatusHandler core.AppStatusHandler, statusPollingIntervalSec int, external config.ExternalConfig, coreComponents factory.CoreComponentsHandler) (*statusComponentsHolder, error) { if check.IfNil(appStatusHandler) { return nil, core.ErrNilAppStatusHandler } @@ -51,12 +58,12 @@ func CreateStatusComponents(shardID uint32, appStatusHandler core.AppStatusHandl if err != nil { return nil, err } - instance.outportHandler, err = factory.CreateOutport(&factory.OutportFactoryArgs{ + instance.outportHandler, err = outportFactory.CreateOutport(&outportFactory.OutportFactoryArgs{ IsImportDB: false, ShardID: shardID, RetrialInterval: time.Second, HostDriversArgs: hostDriverArgs, - EventNotifierFactoryArgs: &factory.EventNotifierFactoryArgs{}, + EventNotifierFactoryArgs: &outportFactory.EventNotifierFactoryArgs{}, ElasticIndexerFactoryArgs: makeElasticIndexerArgs(external, coreComponents), }) if err != nil { @@ -65,13 +72,45 @@ func CreateStatusComponents(shardID uint32, appStatusHandler core.AppStatusHandl instance.softwareVersionChecker = &mock.SoftwareVersionCheckerMock{} instance.managedPeerMonitor = &testscommon.ManagedPeersMonitorStub{} + if shardID == core.MetachainShardId { + coreComponents.EpochStartNotifierWithConfirm().RegisterHandler(instance.epochStartEventHandler()) + } + instance.collectClosableComponents() return instance, nil } -func makeHostDriversArgs(external config.ExternalConfig) ([]factory.ArgsHostDriverFactory, error) { - argsHostDriverFactorySlice := make([]factory.ArgsHostDriverFactory, 0, len(external.HostDriversConfig)) +// SetNodesCoordinator will set the nodes coordinator +func (s *statusComponentsHolder) SetNodesCoordinator(nodesCoordinator nodesCoordinator.NodesCoordinator) { + s.mutex.Lock() + s.nodesCoordinator = nodesCoordinator + s.mutex.Unlock() +} + +func (s *statusComponentsHolder) epochStartEventHandler() epochStart.ActionHandler { + subscribeHandler := notifier.NewHandlerForEpochStart(func(hdr nodeData.HeaderHandler) { + currentEpoch := hdr.GetEpoch() + validatorsPubKeys, err := s.nodesCoordinator.GetAllEligibleValidatorsPublicKeys(currentEpoch) + if err != nil { + log.Warn("s.nodesCoordinator.GetAllEligibleValidatorPublicKeys for current epoch failed", + "epoch", currentEpoch, + "error", err.Error()) + } + + s.outportHandler.SaveValidatorsPubKeys(&outportCore.ValidatorsPubKeys{ + ShardID: hdr.GetShardID(), + ShardValidatorsPubKeys: outportCore.ConvertPubKeys(validatorsPubKeys), + Epoch: currentEpoch, + }) + + }, func(_ nodeData.HeaderHandler) {}, common.IndexerOrder) + + return subscribeHandler +} + +func makeHostDriversArgs(external config.ExternalConfig) ([]outportFactory.ArgsHostDriverFactory, error) { + argsHostDriverFactorySlice := make([]outportFactory.ArgsHostDriverFactory, 0, len(external.HostDriversConfig)) for idx := 0; idx < len(external.HostDriversConfig); idx++ { hostConfig := external.HostDriversConfig[idx] if !hostConfig.Enabled { @@ -83,7 +122,7 @@ func makeHostDriversArgs(external config.ExternalConfig) ([]factory.ArgsHostDriv return argsHostDriverFactorySlice, err } - argsHostDriverFactorySlice = append(argsHostDriverFactorySlice, factory.ArgsHostDriverFactory{ + argsHostDriverFactorySlice = append(argsHostDriverFactorySlice, outportFactory.ArgsHostDriverFactory{ Marshaller: marshaller, HostConfig: hostConfig, }) diff --git a/node/chainSimulator/components/testOnlyProcessingNode.go b/node/chainSimulator/components/testOnlyProcessingNode.go index 28256c4820f..6f90485993c 100644 --- a/node/chainSimulator/components/testOnlyProcessingNode.go +++ b/node/chainSimulator/components/testOnlyProcessingNode.go @@ -148,7 +148,8 @@ func NewTestOnlyProcessingNode(args ArgsTestOnlyProcessingNode) (*testOnlyProces } selfShardID := instance.GetShardCoordinator().SelfId() - instance.StatusComponentsHolder, err = CreateStatusComponents( + + statusComponentsH, err := CreateStatusComponents( selfShardID, instance.StatusCoreComponents.AppStatusHandler(), args.Configs.GeneralConfig.GeneralSettings.StatusPollingIntervalSec, @@ -159,6 +160,8 @@ func NewTestOnlyProcessingNode(args ArgsTestOnlyProcessingNode) (*testOnlyProces return nil, err } + instance.StatusComponentsHolder = statusComponentsH + err = instance.createBlockChain(selfShardID) if err != nil { return nil, err @@ -184,6 +187,8 @@ func NewTestOnlyProcessingNode(args ArgsTestOnlyProcessingNode) (*testOnlyProces return nil, err } + statusComponentsH.SetNodesCoordinator(instance.NodesCoordinator) + instance.DataComponentsHolder, err = CreateDataComponents(ArgsDataComponentsHolder{ Chain: instance.ChainHandler, StorageService: instance.StoreService, From 2c33cdf89e251c72591f767f44e08fe8e4536571 Mon Sep 17 00:00:00 2001 From: miiu Date: Fri, 15 Nov 2024 11:48:15 +0200 Subject: [PATCH 4/8] imports --- node/chainSimulator/components/statusComponents.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/node/chainSimulator/components/statusComponents.go b/node/chainSimulator/components/statusComponents.go index ab62c86581f..ab561e25c2c 100644 --- a/node/chainSimulator/components/statusComponents.go +++ b/node/chainSimulator/components/statusComponents.go @@ -3,28 +3,28 @@ package components import ( "context" "fmt" - nodeData "github.com/multiversx/mx-chain-core-go/data" - outportCore "github.com/multiversx/mx-chain-core-go/data/outport" - "github.com/multiversx/mx-chain-go/epochStart" - "github.com/multiversx/mx-chain-go/epochStart/notifier" - "github.com/multiversx/mx-chain-go/factory" - "github.com/multiversx/mx-chain-go/sharding/nodesCoordinator" "sync" "time" "github.com/multiversx/mx-chain-core-go/core" "github.com/multiversx/mx-chain-core-go/core/appStatusPolling" "github.com/multiversx/mx-chain-core-go/core/check" + nodeData "github.com/multiversx/mx-chain-core-go/data" + outportCore "github.com/multiversx/mx-chain-core-go/data/outport" factoryMarshalizer "github.com/multiversx/mx-chain-core-go/marshal/factory" indexerFactory "github.com/multiversx/mx-chain-es-indexer-go/process/factory" "github.com/multiversx/mx-chain-go/common" "github.com/multiversx/mx-chain-go/common/statistics" "github.com/multiversx/mx-chain-go/config" + "github.com/multiversx/mx-chain-go/epochStart" + "github.com/multiversx/mx-chain-go/epochStart/notifier" "github.com/multiversx/mx-chain-go/errors" + "github.com/multiversx/mx-chain-go/factory" "github.com/multiversx/mx-chain-go/integrationTests/mock" "github.com/multiversx/mx-chain-go/outport" outportFactory "github.com/multiversx/mx-chain-go/outport/factory" "github.com/multiversx/mx-chain-go/process" + "github.com/multiversx/mx-chain-go/sharding/nodesCoordinator" "github.com/multiversx/mx-chain-go/testscommon" ) From 860f20d5f8f2794a994b202f6ed262fcf854ccf2 Mon Sep 17 00:00:00 2001 From: miiu Date: Fri, 15 Nov 2024 12:26:04 +0200 Subject: [PATCH 5/8] fix linter --- node/chainSimulator/components/nodeFacade.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/node/chainSimulator/components/nodeFacade.go b/node/chainSimulator/components/nodeFacade.go index 14218befefa..4d0af7def23 100644 --- a/node/chainSimulator/components/nodeFacade.go +++ b/node/chainSimulator/components/nodeFacade.go @@ -87,6 +87,9 @@ func (node *testOnlyProcessingNode) createFacade(configs config.Configs, apiInte ProcessComponents: node.ProcessComponentsHolder, StatusCoreComponents: node.StatusCoreComponents, }) + if err != nil { + return err + } managedHeartbeatV2Components, err := heartbeat.NewManagedHeartbeatV2Components(heartBeatComponentsFactory) if err != nil { From a97147f97d05234653cd560e398c3896d569884d Mon Sep 17 00:00:00 2001 From: miiu Date: Tue, 19 Nov 2024 16:48:03 +0200 Subject: [PATCH 6/8] chain simulator heartbeat --- .../vm/esdtImprovements_test.go | 20 +++++-- node/chainSimulator/chainSimulator.go | 11 ++-- node/chainSimulator/chainSimulator_test.go | 12 ++--- .../components/heartbeat/heartBeat.go | 52 +++++++++++++++++++ .../components/heartbeat/monitor.go | 39 ++++++++++++++ node/chainSimulator/components/nodeFacade.go | 31 +++-------- .../components/testOnlyProcessingNode.go | 3 +- node/chainSimulator/process/interface.go | 7 +++ node/chainSimulator/process/processor.go | 38 +++++++++++++- node/chainSimulator/process/processor_test.go | 33 ++++++------ 10 files changed, 188 insertions(+), 58 deletions(-) create mode 100644 node/chainSimulator/components/heartbeat/heartBeat.go create mode 100644 node/chainSimulator/components/heartbeat/monitor.go diff --git a/integrationTests/chainSimulator/vm/esdtImprovements_test.go b/integrationTests/chainSimulator/vm/esdtImprovements_test.go index e0f23f1ce8c..8361feb4fee 100644 --- a/integrationTests/chainSimulator/vm/esdtImprovements_test.go +++ b/integrationTests/chainSimulator/vm/esdtImprovements_test.go @@ -3868,7 +3868,9 @@ func TestChainSimulator_CheckRolesWhichHasToBeSingular(t *testing.T) { } func TestChainSimulator_metaESDT_mergeMetaDataFromMultipleUpdates(t *testing.T) { - t.Parallel() + if testing.Short() { + t.Skip("this is not a short test") + } baseIssuingCost := "1000" cs, _ := getTestChainSimulatorWithDynamicNFTEnabled(t, baseIssuingCost) @@ -4237,7 +4239,9 @@ func transferSpecialRoleToAddr( } func TestChainSimulator_dynamicNFT_mergeMetaDataFromMultipleUpdates(t *testing.T) { - t.Parallel() + if testing.Short() { + t.Skip("this is not a short test") + } baseIssuingCost := "1000" cs, _ := getTestChainSimulatorWithDynamicNFTEnabled(t, baseIssuingCost) @@ -4385,7 +4389,9 @@ func TestChainSimulator_dynamicNFT_mergeMetaDataFromMultipleUpdates(t *testing.T } func TestChainSimulator_dynamicNFT_changeMetaDataForOneNFTShouldNotChangeOtherNonces(t *testing.T) { - t.Parallel() + if testing.Short() { + t.Skip("this is not a short test") + } baseIssuingCost := "1000" cs, _ := getTestChainSimulatorWithDynamicNFTEnabled(t, baseIssuingCost) @@ -4498,7 +4504,9 @@ func TestChainSimulator_dynamicNFT_changeMetaDataForOneNFTShouldNotChangeOtherNo } func TestChainSimulator_dynamicNFT_updateBeforeCreateOnSameAccountShouldOverwrite(t *testing.T) { - t.Parallel() + if testing.Short() { + t.Skip("this is not a short test") + } baseIssuingCost := "1000" cs, _ := getTestChainSimulatorWithDynamicNFTEnabled(t, baseIssuingCost) @@ -4595,7 +4603,9 @@ func TestChainSimulator_dynamicNFT_updateBeforeCreateOnSameAccountShouldOverwrit } func TestChainSimulator_dynamicNFT_updateBeforeCreateOnDifferentAccountsShouldMergeMetaDataWhenTransferred(t *testing.T) { - t.Parallel() + if testing.Short() { + t.Skip("this is not a short test") + } baseIssuingCost := "1000" cs, _ := getTestChainSimulatorWithDynamicNFTEnabled(t, baseIssuingCost) diff --git a/node/chainSimulator/chainSimulator.go b/node/chainSimulator/chainSimulator.go index 742d040c8c8..b8edc491eda 100644 --- a/node/chainSimulator/chainSimulator.go +++ b/node/chainSimulator/chainSimulator.go @@ -11,7 +11,9 @@ import ( "time" "github.com/multiversx/mx-chain-go/config" + "github.com/multiversx/mx-chain-go/factory" "github.com/multiversx/mx-chain-go/node/chainSimulator/components" + "github.com/multiversx/mx-chain-go/node/chainSimulator/components/heartbeat" "github.com/multiversx/mx-chain-go/node/chainSimulator/configs" "github.com/multiversx/mx-chain-go/node/chainSimulator/dtos" chainSimulatorErrors "github.com/multiversx/mx-chain-go/node/chainSimulator/errors" @@ -130,18 +132,20 @@ func (s *simulator) createChainHandlers(args ArgsBaseChainSimulator) error { return err } + monitor := heartbeat.NewHeartbeatMonitor() + for idx := -1; idx < int(args.NumOfShards); idx++ { shardIDStr := fmt.Sprintf("%d", idx) if idx == -1 { shardIDStr = "metachain" } - node, errCreate := s.createTestNode(*outputConfigs, args, shardIDStr) + node, errCreate := s.createTestNode(*outputConfigs, args, shardIDStr, monitor) if errCreate != nil { return errCreate } - chainHandler, errCreate := process.NewBlocksCreator(node) + chainHandler, errCreate := process.NewBlocksCreator(node, monitor) if errCreate != nil { return errCreate } @@ -195,7 +199,7 @@ func computeStartTimeBaseOnInitialRound(args ArgsChainSimulator) int64 { } func (s *simulator) createTestNode( - outputConfigs configs.ArgsConfigsSimulator, args ArgsBaseChainSimulator, shardIDStr string, + outputConfigs configs.ArgsConfigsSimulator, args ArgsBaseChainSimulator, shardIDStr string, monitor factory.HeartbeatV2Monitor, ) (process.NodeHandler, error) { argsTestOnlyProcessorNode := components.ArgsTestOnlyProcessingNode{ Configs: outputConfigs.Configs, @@ -214,6 +218,7 @@ func (s *simulator) createTestNode( MetaChainConsensusGroupSize: args.MetaChainConsensusGroupSize, RoundDurationInMillis: args.RoundDurationInMillis, VmQueryDelayAfterStartInMs: args.VmQueryDelayAfterStartInMs, + Monitor: monitor, } return components.NewTestOnlyProcessingNode(argsTestOnlyProcessorNode) diff --git a/node/chainSimulator/chainSimulator_test.go b/node/chainSimulator/chainSimulator_test.go index fde143eb3e5..2ba89205afe 100644 --- a/node/chainSimulator/chainSimulator_test.go +++ b/node/chainSimulator/chainSimulator_test.go @@ -82,19 +82,17 @@ func TestChainSimulator_GenerateBlocksShouldWork(t *testing.T) { }) require.Nil(t, err) require.NotNil(t, chainSimulator) - - time.Sleep(time.Second) - - heartBeats, err := chainSimulator.GetNodeHandler(0).GetFacadeHandler().GetHeartbeats() - require.Nil(t, err) - require.Equal(t, 1, len(heartBeats)) - defer chainSimulator.Close() time.Sleep(time.Second) err = chainSimulator.GenerateBlocks(50) require.Nil(t, err) + + heartBeats, err := chainSimulator.GetNodeHandler(0).GetFacadeHandler().GetHeartbeats() + require.Nil(t, err) + require.Equal(t, 4, len(heartBeats)) + } func TestChainSimulator_GenerateBlocksAndEpochChangeShouldWork(t *testing.T) { diff --git a/node/chainSimulator/components/heartbeat/heartBeat.go b/node/chainSimulator/components/heartbeat/heartBeat.go new file mode 100644 index 00000000000..ffdd53b6961 --- /dev/null +++ b/node/chainSimulator/components/heartbeat/heartBeat.go @@ -0,0 +1,52 @@ +package heartbeat + +import ( + "github.com/multiversx/mx-chain-core-go/core/check" + "github.com/multiversx/mx-chain-go/factory" + "github.com/multiversx/mx-chain-go/heartbeat" +) + +type heartBeatComponents struct { + monitor factory.HeartbeatV2Monitor +} + +// NewSyncedHeartbeatComponents will create a new instance of heartbeat components +func NewSyncedHeartbeatComponents(monitor factory.HeartbeatV2Monitor) (factory.HeartbeatV2ComponentsHandler, error) { + if check.IfNil(monitor) { + return nil, heartbeat.ErrNilHeartbeatMonitor + } + + return &heartBeatComponents{ + monitor: monitor, + }, nil +} + +// Create will do nothing +func (h *heartBeatComponents) Create() error { + return nil +} + +// Close will do nothing +func (h *heartBeatComponents) Close() error { + return nil +} + +// CheckSubcomponents will do nothing +func (h *heartBeatComponents) CheckSubcomponents() error { + return nil +} + +// String will return a string +func (h *heartBeatComponents) String() string { + return "heartBeat" +} + +// Monitor will return the monitor +func (h *heartBeatComponents) Monitor() factory.HeartbeatV2Monitor { + return h.monitor +} + +// IsInterfaceNil returns true if there is no value under the interface +func (h *heartBeatComponents) IsInterfaceNil() bool { + return h == nil +} diff --git a/node/chainSimulator/components/heartbeat/monitor.go b/node/chainSimulator/components/heartbeat/monitor.go new file mode 100644 index 00000000000..9fda1a369f8 --- /dev/null +++ b/node/chainSimulator/components/heartbeat/monitor.go @@ -0,0 +1,39 @@ +package heartbeat + +import ( + "sync" + + "github.com/multiversx/mx-chain-go/heartbeat/data" +) + +type heartbeatMonitor struct { + heartbeats []data.PubKeyHeartbeat + mutex sync.RWMutex +} + +// NewHeartbeatMonitor will create a new instance of heartbeat monitor +func NewHeartbeatMonitor() *heartbeatMonitor { + return &heartbeatMonitor{ + heartbeats: make([]data.PubKeyHeartbeat, 0), + } +} + +// GetHeartbeats will return the heartbeats +func (hm *heartbeatMonitor) GetHeartbeats() []data.PubKeyHeartbeat { + hm.mutex.RLock() + defer hm.mutex.RUnlock() + + return hm.heartbeats +} + +// SetHeartbeats will set the provided heartbeats +func (hm *heartbeatMonitor) SetHeartbeats(heartbeats []data.PubKeyHeartbeat) { + hm.mutex.Lock() + hm.heartbeats = heartbeats + hm.mutex.Unlock() +} + +// IsInterfaceNil returns true if there is no value under the interface +func (hm *heartbeatMonitor) IsInterfaceNil() bool { + return nil == hm +} diff --git a/node/chainSimulator/components/nodeFacade.go b/node/chainSimulator/components/nodeFacade.go index 4d0af7def23..f1bacb11b96 100644 --- a/node/chainSimulator/components/nodeFacade.go +++ b/node/chainSimulator/components/nodeFacade.go @@ -3,6 +3,8 @@ package components import ( "errors" "fmt" + "github.com/multiversx/mx-chain-go/factory" + heartbeat2 "github.com/multiversx/mx-chain-go/node/chainSimulator/components/heartbeat" "strconv" "time" @@ -13,13 +15,12 @@ import ( "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/facade" apiComp "github.com/multiversx/mx-chain-go/factory/api" - "github.com/multiversx/mx-chain-go/factory/heartbeat" nodePack "github.com/multiversx/mx-chain-go/node" "github.com/multiversx/mx-chain-go/node/metrics" "github.com/multiversx/mx-chain-go/process/mock" ) -func (node *testOnlyProcessingNode) createFacade(configs config.Configs, apiInterface APIConfigurator, vmQueryDelayAfterStartInMs uint64) error { +func (node *testOnlyProcessingNode) createFacade(configs config.Configs, apiInterface APIConfigurator, vmQueryDelayAfterStartInMs uint64, monitor factory.HeartbeatV2Monitor) error { log.Debug("creating api resolver structure") err := node.createMetrics(configs) @@ -74,32 +75,12 @@ func (node *testOnlyProcessingNode) createFacade(configs config.Configs, apiInte flagsConfig := configs.FlagsConfig - heartBeatComponentsFactory, err := heartbeat.NewHeartbeatV2ComponentsFactory(heartbeat.ArgHeartbeatV2ComponentsFactory{ - Config: *configs.GeneralConfig, - Prefs: *configs.PreferencesConfig, - BaseVersion: "1", - AppVersion: "1", - BootstrapComponents: node.BootstrapComponentsHolder, - CoreComponents: node.CoreComponentsHolder, - DataComponents: node.DataComponentsHolder, - NetworkComponents: node.NetworkComponentsHolder, - CryptoComponents: node.CryptoComponentsHolder, - ProcessComponents: node.ProcessComponentsHolder, - StatusCoreComponents: node.StatusCoreComponents, - }) + heartbeatComponents, err := heartbeat2.NewSyncedHeartbeatComponents(monitor) if err != nil { return err } - managedHeartbeatV2Components, err := heartbeat.NewManagedHeartbeatV2Components(heartBeatComponentsFactory) - if err != nil { - return err - } - - err = managedHeartbeatV2Components.Create() - if err != nil { - return err - } + node.closeHandler.AddComponent(heartbeatComponents) nd, err := nodePack.NewNode( nodePack.WithStatusCoreComponents(node.StatusCoreComponents), @@ -123,7 +104,7 @@ func (node *testOnlyProcessingNode) createFacade(configs config.Configs, apiInte nodePack.WithNodeStopChannel(node.CoreComponentsHolder.ChanStopNodeProcess()), nodePack.WithImportMode(configs.ImportDbConfig.IsImportDBMode), nodePack.WithESDTNFTStorageHandler(node.ProcessComponentsHolder.ESDTDataStorageHandlerForAPI()), - nodePack.WithHeartbeatV2Components(managedHeartbeatV2Components), + nodePack.WithHeartbeatV2Components(heartbeatComponents), ) if err != nil { return errors.New("error creating node: " + err.Error()) diff --git a/node/chainSimulator/components/testOnlyProcessingNode.go b/node/chainSimulator/components/testOnlyProcessingNode.go index 6f90485993c..8bc542f432c 100644 --- a/node/chainSimulator/components/testOnlyProcessingNode.go +++ b/node/chainSimulator/components/testOnlyProcessingNode.go @@ -37,6 +37,7 @@ type ArgsTestOnlyProcessingNode struct { ChanStopNodeProcess chan endProcess.ArgEndProcess SyncedBroadcastNetwork SyncedBroadcastNetworkHandler + Monitor factory.HeartbeatV2Monitor InitialRound int64 InitialNonce uint64 @@ -240,7 +241,7 @@ func NewTestOnlyProcessingNode(args ArgsTestOnlyProcessingNode) (*testOnlyProces return nil, err } - err = instance.createFacade(args.Configs, args.APIInterface, args.VmQueryDelayAfterStartInMs) + err = instance.createFacade(args.Configs, args.APIInterface, args.VmQueryDelayAfterStartInMs, args.Monitor) if err != nil { return nil, err } diff --git a/node/chainSimulator/process/interface.go b/node/chainSimulator/process/interface.go index 47f937fb97c..7ae2f07517e 100644 --- a/node/chainSimulator/process/interface.go +++ b/node/chainSimulator/process/interface.go @@ -5,6 +5,7 @@ import ( "github.com/multiversx/mx-chain-go/api/shared" "github.com/multiversx/mx-chain-go/consensus" "github.com/multiversx/mx-chain-go/factory" + "github.com/multiversx/mx-chain-go/heartbeat/data" "github.com/multiversx/mx-chain-go/node/chainSimulator/dtos" "github.com/multiversx/mx-chain-go/sharding" ) @@ -28,3 +29,9 @@ type NodeHandler interface { Close() error IsInterfaceNil() bool } + +// HeartbeatMonitorWithSet defines what a heartbeat monitor with set should be able to do +type HeartbeatMonitorWithSet interface { + SetHeartbeats(heartbeats []data.PubKeyHeartbeat) + IsInterfaceNil() bool +} diff --git a/node/chainSimulator/process/processor.go b/node/chainSimulator/process/processor.go index d8f225bfde8..1c9819e27f0 100644 --- a/node/chainSimulator/process/processor.go +++ b/node/chainSimulator/process/processor.go @@ -1,10 +1,13 @@ package process import ( + "time" + "github.com/multiversx/mx-chain-core-go/core/check" "github.com/multiversx/mx-chain-core-go/data" "github.com/multiversx/mx-chain-go/common" "github.com/multiversx/mx-chain-go/consensus/spos" + heartbeatData "github.com/multiversx/mx-chain-go/heartbeat/data" "github.com/multiversx/mx-chain-go/node/chainSimulator/configs" logger "github.com/multiversx/mx-chain-logger-go" ) @@ -17,16 +20,18 @@ type manualRoundHandler interface { type blocksCreator struct { nodeHandler NodeHandler + monitor HeartbeatMonitorWithSet } // NewBlocksCreator will create a new instance of blocksCreator -func NewBlocksCreator(nodeHandler NodeHandler) (*blocksCreator, error) { +func NewBlocksCreator(nodeHandler NodeHandler, monitor HeartbeatMonitorWithSet) (*blocksCreator, error) { if check.IfNil(nodeHandler) { return nil, ErrNilNodeHandler } return &blocksCreator{ nodeHandler: nodeHandler, + monitor: monitor, }, nil } @@ -123,6 +128,11 @@ func (creator *blocksCreator) CreateNewBlock() error { return err } + err = creator.setHeartBeat(header) + if err != nil { + return err + } + miniBlocks, transactions, err := bp.MarshalizedDataToBroadcast(header, block) if err != nil { return err @@ -141,6 +151,32 @@ func (creator *blocksCreator) CreateNewBlock() error { return creator.nodeHandler.GetBroadcastMessenger().BroadcastTransactions(transactions, blsKey.PubKey()) } +func (creator *blocksCreator) setHeartBeat(header data.HeaderHandler) error { + if !header.IsStartOfEpochBlock() { + return nil + } + + validators := creator.nodeHandler.GetProcessComponents().ValidatorsProvider().GetLatestValidators() + + var heartbeats []heartbeatData.PubKeyHeartbeat + for key, validator := range validators { + heartbeats = append(heartbeats, heartbeatData.PubKeyHeartbeat{ + PublicKey: key, + TimeStamp: time.Now(), + IsActive: true, + NumInstances: 1, + ComputedShardID: creator.nodeHandler.GetShardCoordinator().SelfId(), + ReceivedShardID: validator.ShardId, + }) + } + + if len(heartbeats) > 0 { + creator.monitor.SetHeartbeats(heartbeats) + } + + return nil +} + func (creator *blocksCreator) getPreviousHeaderData() (nonce, round uint64, prevHash, prevRandSeed []byte, epoch uint32) { currentHeader := creator.nodeHandler.GetChainHandler().GetCurrentBlockHeader() diff --git a/node/chainSimulator/process/processor_test.go b/node/chainSimulator/process/processor_test.go index 80ffd568134..84a93eea028 100644 --- a/node/chainSimulator/process/processor_test.go +++ b/node/chainSimulator/process/processor_test.go @@ -14,6 +14,7 @@ import ( mockConsensus "github.com/multiversx/mx-chain-go/consensus/mock" "github.com/multiversx/mx-chain-go/factory" "github.com/multiversx/mx-chain-go/integrationTests/mock" + "github.com/multiversx/mx-chain-go/node/chainSimulator/components/heartbeat" chainSimulatorProcess "github.com/multiversx/mx-chain-go/node/chainSimulator/process" "github.com/multiversx/mx-chain-go/process" "github.com/multiversx/mx-chain-go/sharding" @@ -35,14 +36,14 @@ func TestNewBlocksCreator(t *testing.T) { t.Run("nil node handler should error", func(t *testing.T) { t.Parallel() - creator, err := chainSimulatorProcess.NewBlocksCreator(nil) + creator, err := chainSimulatorProcess.NewBlocksCreator(nil, heartbeat.NewHeartbeatMonitor()) require.Equal(t, chainSimulatorProcess.ErrNilNodeHandler, err) require.Nil(t, creator) }) t.Run("should work", func(t *testing.T) { t.Parallel() - creator, err := chainSimulatorProcess.NewBlocksCreator(&chainSimulator.NodeHandlerMock{}) + creator, err := chainSimulatorProcess.NewBlocksCreator(&chainSimulator.NodeHandlerMock{}, heartbeat.NewHeartbeatMonitor()) require.NoError(t, err) require.NotNil(t, creator) }) @@ -51,10 +52,10 @@ func TestNewBlocksCreator(t *testing.T) { func TestBlocksCreator_IsInterfaceNil(t *testing.T) { t.Parallel() - creator, _ := chainSimulatorProcess.NewBlocksCreator(nil) + creator, _ := chainSimulatorProcess.NewBlocksCreator(nil, heartbeat.NewHeartbeatMonitor()) require.True(t, creator.IsInterfaceNil()) - creator, _ = chainSimulatorProcess.NewBlocksCreator(&chainSimulator.NodeHandlerMock{}) + creator, _ = chainSimulatorProcess.NewBlocksCreator(&chainSimulator.NodeHandlerMock{}, heartbeat.NewHeartbeatMonitor()) require.False(t, creator.IsInterfaceNil()) } @@ -86,7 +87,7 @@ func TestBlocksCreator_IncrementRound(t *testing.T) { } }, } - creator, err := chainSimulatorProcess.NewBlocksCreator(nodeHandler) + creator, err := chainSimulatorProcess.NewBlocksCreator(nodeHandler, heartbeat.NewHeartbeatMonitor()) require.NoError(t, err) creator.IncrementRound() @@ -119,7 +120,7 @@ func TestBlocksCreator_CreateNewBlock(t *testing.T) { } } - creator, err := chainSimulatorProcess.NewBlocksCreator(nodeHandler) + creator, err := chainSimulatorProcess.NewBlocksCreator(nodeHandler, heartbeat.NewHeartbeatMonitor()) require.NoError(t, err) err = creator.CreateNewBlock() @@ -227,7 +228,7 @@ func TestBlocksCreator_CreateNewBlock(t *testing.T) { }, } } - creator, err := chainSimulatorProcess.NewBlocksCreator(nodeHandler) + creator, err := chainSimulatorProcess.NewBlocksCreator(nodeHandler, heartbeat.NewHeartbeatMonitor()) require.NoError(t, err) err = creator.CreateNewBlock() @@ -246,7 +247,7 @@ func TestBlocksCreator_CreateNewBlock(t *testing.T) { }, } } - creator, err := chainSimulatorProcess.NewBlocksCreator(nodeHandler) + creator, err := chainSimulatorProcess.NewBlocksCreator(nodeHandler, heartbeat.NewHeartbeatMonitor()) require.NoError(t, err) err = creator.CreateNewBlock() @@ -267,7 +268,7 @@ func TestBlocksCreator_CreateNewBlock(t *testing.T) { }, } } - creator, err := chainSimulatorProcess.NewBlocksCreator(nodeHandler) + creator, err := chainSimulatorProcess.NewBlocksCreator(nodeHandler, heartbeat.NewHeartbeatMonitor()) require.NoError(t, err) err = creator.CreateNewBlock() @@ -319,7 +320,7 @@ func TestBlocksCreator_CreateNewBlock(t *testing.T) { }, } } - creator, err := chainSimulatorProcess.NewBlocksCreator(nodeHandler) + creator, err := chainSimulatorProcess.NewBlocksCreator(nodeHandler, heartbeat.NewHeartbeatMonitor()) require.NoError(t, err) err = creator.CreateNewBlock() @@ -340,7 +341,7 @@ func TestBlocksCreator_CreateNewBlock(t *testing.T) { }, } } - creator, err := chainSimulatorProcess.NewBlocksCreator(nodeHandler) + creator, err := chainSimulatorProcess.NewBlocksCreator(nodeHandler, heartbeat.NewHeartbeatMonitor()) require.NoError(t, err) err = creator.CreateNewBlock() @@ -361,7 +362,7 @@ func TestBlocksCreator_CreateNewBlock(t *testing.T) { }, } } - creator, err := chainSimulatorProcess.NewBlocksCreator(nodeHandler) + creator, err := chainSimulatorProcess.NewBlocksCreator(nodeHandler, heartbeat.NewHeartbeatMonitor()) require.NoError(t, err) err = creator.CreateNewBlock() @@ -382,7 +383,7 @@ func TestBlocksCreator_CreateNewBlock(t *testing.T) { }, } } - creator, err := chainSimulatorProcess.NewBlocksCreator(nodeHandler) + creator, err := chainSimulatorProcess.NewBlocksCreator(nodeHandler, heartbeat.NewHeartbeatMonitor()) require.NoError(t, err) err = creator.CreateNewBlock() @@ -521,7 +522,7 @@ func TestBlocksCreator_CreateNewBlock(t *testing.T) { }, } } - creator, err := chainSimulatorProcess.NewBlocksCreator(nodeHandler) + creator, err := chainSimulatorProcess.NewBlocksCreator(nodeHandler, heartbeat.NewHeartbeatMonitor()) require.NoError(t, err) err = creator.CreateNewBlock() @@ -530,7 +531,7 @@ func TestBlocksCreator_CreateNewBlock(t *testing.T) { t.Run("should work", func(t *testing.T) { t.Parallel() - creator, err := chainSimulatorProcess.NewBlocksCreator(getNodeHandler()) + creator, err := chainSimulatorProcess.NewBlocksCreator(getNodeHandler(), heartbeat.NewHeartbeatMonitor()) require.NoError(t, err) err = creator.CreateNewBlock() @@ -547,7 +548,7 @@ func testCreateNewBlock(t *testing.T, blockProcess process.BlockProcessor, expec NodesCoord: nc, } } - creator, err := chainSimulatorProcess.NewBlocksCreator(nodeHandler) + creator, err := chainSimulatorProcess.NewBlocksCreator(nodeHandler, heartbeat.NewHeartbeatMonitor()) require.NoError(t, err) err = creator.CreateNewBlock() From ba15dcb20411be069c88882f1cc00b03472c4705 Mon Sep 17 00:00:00 2001 From: miiu Date: Tue, 19 Nov 2024 16:50:05 +0200 Subject: [PATCH 7/8] fixes --- node/chainSimulator/components/testOnlyProcessingNode_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/node/chainSimulator/components/testOnlyProcessingNode_test.go b/node/chainSimulator/components/testOnlyProcessingNode_test.go index c363ca8019c..801c11585e9 100644 --- a/node/chainSimulator/components/testOnlyProcessingNode_test.go +++ b/node/chainSimulator/components/testOnlyProcessingNode_test.go @@ -2,6 +2,7 @@ package components import ( "errors" + "github.com/multiversx/mx-chain-go/node/chainSimulator/components/heartbeat" "math/big" "strings" "testing" @@ -44,6 +45,7 @@ func createMockArgsTestOnlyProcessingNode(t *testing.T) ArgsTestOnlyProcessingNo SyncedBroadcastNetwork: NewSyncedBroadcastNetwork(), ChanStopNodeProcess: make(chan endProcess.ArgEndProcess), APIInterface: api.NewNoApiInterface(), + Monitor: heartbeat.NewHeartbeatMonitor(), ShardIDStr: "0", RoundDurationInMillis: 6000, MinNodesMeta: 1, From 5e01a062b7d170b871aece1113ad83ea1bc9c7c1 Mon Sep 17 00:00:00 2001 From: miiu Date: Wed, 20 Nov 2024 10:27:07 +0200 Subject: [PATCH 8/8] fixes after review --- node/chainSimulator/components/nodeFacade.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/node/chainSimulator/components/nodeFacade.go b/node/chainSimulator/components/nodeFacade.go index f1bacb11b96..24bdc3d1ada 100644 --- a/node/chainSimulator/components/nodeFacade.go +++ b/node/chainSimulator/components/nodeFacade.go @@ -3,8 +3,6 @@ package components import ( "errors" "fmt" - "github.com/multiversx/mx-chain-go/factory" - heartbeat2 "github.com/multiversx/mx-chain-go/node/chainSimulator/components/heartbeat" "strconv" "time" @@ -14,8 +12,10 @@ import ( "github.com/multiversx/mx-chain-go/common/forking" "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/facade" + "github.com/multiversx/mx-chain-go/factory" apiComp "github.com/multiversx/mx-chain-go/factory/api" nodePack "github.com/multiversx/mx-chain-go/node" + simulatorHeartbeat "github.com/multiversx/mx-chain-go/node/chainSimulator/components/heartbeat" "github.com/multiversx/mx-chain-go/node/metrics" "github.com/multiversx/mx-chain-go/process/mock" ) @@ -75,7 +75,7 @@ func (node *testOnlyProcessingNode) createFacade(configs config.Configs, apiInte flagsConfig := configs.FlagsConfig - heartbeatComponents, err := heartbeat2.NewSyncedHeartbeatComponents(monitor) + heartbeatComponents, err := simulatorHeartbeat.NewSyncedHeartbeatComponents(monitor) if err != nil { return err }