diff --git a/cmd/neofs-node/main.go b/cmd/neofs-node/main.go index ff88dad97..47b985514 100644 --- a/cmd/neofs-node/main.go +++ b/cmd/neofs-node/main.go @@ -5,7 +5,6 @@ import ( "flag" "log" - "github.com/nspcc-dev/neofs-node/pkg/services/control" "github.com/nspcc-dev/neofs-node/pkg/util/grace" "go.uber.org/zap" ) @@ -55,8 +54,6 @@ func bootUp(c *cfg) { serveGRPC(c) bootstrapNode(c) startWorkers(c) - - c.setNetmapStatus(control.NetmapStatus_ONLINE) } func wait(c *cfg) { diff --git a/cmd/neofs-node/netmap.go b/cmd/neofs-node/netmap.go index 10007b5a7..2e1d2acb2 100644 --- a/cmd/neofs-node/netmap.go +++ b/cmd/neofs-node/netmap.go @@ -1,6 +1,8 @@ package main import ( + "bytes" + "github.com/nspcc-dev/neofs-api-go/pkg/netmap" netmapGRPC "github.com/nspcc-dev/neofs-api-go/v2/netmap/grpc" crypto "github.com/nspcc-dev/neofs-crypto" @@ -72,6 +74,22 @@ func initNetmapService(c *cfg) { } }) } + + addNewEpochNotificationHandler(c, func(ev event.Event) { + e := ev.(netmapEvent.NewEpoch).EpochNumber() + + netStatus, err := c.netmapStatus(e) + if err != nil { + c.log.Error("could not update network status on new epoch", + zap.Uint64("epoch", e), + zap.String("error", err.Error()), + ) + + return + } + + c.setNetmapStatus(netStatus) + }) } func bootstrapNode(c *cfg) { @@ -105,20 +123,48 @@ func initState(c *cfg) { epoch, err := c.cfgNetmap.wrapper.Epoch() fatalOnErr(errors.Wrap(err, "could not initialize current epoch number")) - c.log.Info("initial epoch number", - zap.Uint64("value", epoch), + netStatus, err := c.netmapStatus(epoch) + fatalOnErr(errors.Wrap(err, "could not init network status")) + + c.setNetmapStatus(netStatus) + + c.log.Info("initial network state", + zap.Uint64("epoch", epoch), + zap.Stringer("status", netStatus), ) c.cfgNetmap.state.setCurrentEpoch(epoch) } +func (c *cfg) netmapStatus(epoch uint64) (control.NetmapStatus, error) { + // calculate current network state + nm, err := c.cfgNetmap.wrapper.GetNetMapByEpoch(epoch) + if err != nil { + return control.NetmapStatus_STATUS_UNDEFINED, err + } + + if c.inNetmap(nm) { + return control.NetmapStatus_ONLINE, nil + } + + return control.NetmapStatus_OFFLINE, nil +} + +func (c *cfg) inNetmap(nm *netmap.Netmap) bool { + for _, n := range nm.Nodes { + if bytes.Equal(n.PublicKey(), crypto.MarshalPublicKey(&c.key.PublicKey)) { + return true + } + } + + return false +} + func addNewEpochNotificationHandler(c *cfg, h event.Handler) { addNetmapNotificationHandler(c, newEpochNotification, h) } func goOffline(c *cfg) { - c.setNetmapStatus(control.NetmapStatus_OFFLINE) - err := c.cfgNetmap.wrapper.UpdatePeerState( crypto.MarshalPublicKey(&c.key.PublicKey), netmap.NodeStateOffline,