2020-10-08 13:17:50 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2021-01-15 10:02:59 +00:00
|
|
|
"bytes"
|
2023-04-05 13:58:32 +00:00
|
|
|
"context"
|
2021-08-24 07:43:21 +00:00
|
|
|
"errors"
|
2021-09-20 16:13:17 +00:00
|
|
|
"fmt"
|
2023-11-30 17:51:23 +00:00
|
|
|
"net"
|
2023-05-19 15:06:20 +00:00
|
|
|
"sync/atomic"
|
2021-01-15 10:02:59 +00:00
|
|
|
|
2023-03-07 13:38:26 +00:00
|
|
|
netmapGRPC "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/netmap/grpc"
|
2023-04-12 14:35:10 +00:00
|
|
|
"git.frostfs.info/TrueCloudLab/frostfs-node/internal/logs"
|
2023-03-07 13:38:26 +00:00
|
|
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/netmap"
|
|
|
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/metrics"
|
|
|
|
nmClient "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/netmap"
|
|
|
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/event"
|
|
|
|
netmapEvent "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/event/netmap"
|
|
|
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/network"
|
|
|
|
netmapTransportGRPC "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/network/transport/netmap/grpc"
|
|
|
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control"
|
|
|
|
netmapService "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/netmap"
|
|
|
|
netmapSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap"
|
|
|
|
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/version"
|
2020-10-21 16:26:38 +00:00
|
|
|
"go.uber.org/zap"
|
2023-11-30 17:51:23 +00:00
|
|
|
"google.golang.org/grpc"
|
2020-10-08 13:17:50 +00:00
|
|
|
)
|
|
|
|
|
2020-10-21 15:12:31 +00:00
|
|
|
// primary solution of local network state dump.
|
|
|
|
type networkState struct {
|
|
|
|
epoch *atomic.Uint64
|
2021-06-11 10:55:11 +00:00
|
|
|
|
2023-05-19 15:06:20 +00:00
|
|
|
controlNetStatus atomic.Int32 // control.NetmapStatus
|
2021-06-11 10:55:11 +00:00
|
|
|
|
2024-04-27 11:17:22 +00:00
|
|
|
nodeInfo atomic.Value // netmapSDK.NodeInfo
|
2021-12-28 10:39:42 +00:00
|
|
|
|
2022-07-19 15:16:42 +00:00
|
|
|
metrics *metrics.NodeMetrics
|
2020-10-21 15:12:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func newNetworkState() *networkState {
|
2023-05-19 15:06:20 +00:00
|
|
|
ns := &networkState{
|
|
|
|
epoch: new(atomic.Uint64),
|
2020-10-21 15:12:31 +00:00
|
|
|
}
|
2023-05-19 15:06:20 +00:00
|
|
|
ns.controlNetStatus.Store(int32(control.NetmapStatus_STATUS_UNDEFINED))
|
|
|
|
return ns
|
2020-10-21 15:12:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (s *networkState) CurrentEpoch() uint64 {
|
|
|
|
return s.epoch.Load()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *networkState) setCurrentEpoch(v uint64) {
|
|
|
|
s.epoch.Store(v)
|
2021-12-28 10:39:42 +00:00
|
|
|
if s.metrics != nil {
|
|
|
|
s.metrics.SetEpoch(v)
|
|
|
|
}
|
2020-10-21 15:12:31 +00:00
|
|
|
}
|
|
|
|
|
2021-06-11 10:55:11 +00:00
|
|
|
func (s *networkState) setNodeInfo(ni *netmapSDK.NodeInfo) {
|
2022-06-08 23:18:26 +00:00
|
|
|
ctrlNetSt := control.NetmapStatus_STATUS_UNDEFINED
|
2021-06-11 10:55:11 +00:00
|
|
|
|
2022-06-08 23:18:26 +00:00
|
|
|
if ni != nil {
|
|
|
|
s.nodeInfo.Store(*ni)
|
2021-06-11 10:55:11 +00:00
|
|
|
|
2022-06-08 23:18:26 +00:00
|
|
|
switch {
|
|
|
|
case ni.IsOnline():
|
|
|
|
ctrlNetSt = control.NetmapStatus_ONLINE
|
|
|
|
case ni.IsOffline():
|
|
|
|
ctrlNetSt = control.NetmapStatus_OFFLINE
|
2022-10-14 08:33:52 +00:00
|
|
|
case ni.IsMaintenance():
|
|
|
|
ctrlNetSt = control.NetmapStatus_MAINTENANCE
|
2022-06-08 23:18:26 +00:00
|
|
|
}
|
|
|
|
} else {
|
2021-06-11 10:55:11 +00:00
|
|
|
ctrlNetSt = control.NetmapStatus_OFFLINE
|
2022-10-10 20:04:00 +00:00
|
|
|
|
|
|
|
niRaw := s.nodeInfo.Load()
|
|
|
|
if niRaw != nil {
|
|
|
|
niOld := niRaw.(netmapSDK.NodeInfo)
|
|
|
|
|
|
|
|
// nil ni means that the node is not included
|
|
|
|
// in the netmap
|
|
|
|
niOld.SetOffline()
|
|
|
|
|
|
|
|
s.nodeInfo.Store(niOld)
|
|
|
|
}
|
2021-06-11 10:55:11 +00:00
|
|
|
}
|
|
|
|
|
2022-10-28 07:08:49 +00:00
|
|
|
s.setControlNetmapStatus(ctrlNetSt)
|
|
|
|
}
|
|
|
|
|
|
|
|
// sets the current node state to the given value. Subsequent cfg.bootstrap
|
|
|
|
// calls will process this value to decide what status node should set in the
|
|
|
|
// network.
|
|
|
|
func (s *networkState) setControlNetmapStatus(st control.NetmapStatus) {
|
2023-05-19 15:06:20 +00:00
|
|
|
s.controlNetStatus.Store(int32(st))
|
2021-06-11 10:55:11 +00:00
|
|
|
}
|
|
|
|
|
2022-10-10 19:10:49 +00:00
|
|
|
func (s *networkState) controlNetmapStatus() (res control.NetmapStatus) {
|
2023-05-19 15:06:20 +00:00
|
|
|
return control.NetmapStatus(s.controlNetStatus.Load())
|
2021-06-11 10:55:11 +00:00
|
|
|
}
|
2020-10-08 13:17:50 +00:00
|
|
|
|
2022-06-08 23:18:26 +00:00
|
|
|
func (s *networkState) getNodeInfo() (res netmapSDK.NodeInfo, ok bool) {
|
|
|
|
v := s.nodeInfo.Load()
|
|
|
|
if v != nil {
|
|
|
|
res, ok = v.(netmapSDK.NodeInfo)
|
|
|
|
if !ok {
|
|
|
|
panic(fmt.Sprintf("unexpected value in atomic node info state: %T", v))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return
|
2021-06-11 10:55:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func nodeKeyFromNetmap(c *cfg) []byte {
|
2022-06-08 23:18:26 +00:00
|
|
|
ni, ok := c.cfgNetmap.state.getNodeInfo()
|
|
|
|
if ok {
|
|
|
|
return ni.PublicKey()
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
2021-06-11 10:55:11 +00:00
|
|
|
}
|
|
|
|
|
2021-06-22 16:00:00 +00:00
|
|
|
func (c *cfg) iterateNetworkAddresses(f func(string) bool) {
|
2022-06-08 23:18:26 +00:00
|
|
|
ni, ok := c.cfgNetmap.state.getNodeInfo()
|
|
|
|
if ok {
|
|
|
|
ni.IterateNetworkEndpoints(f)
|
|
|
|
}
|
2021-06-22 16:00:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (c *cfg) addressNum() int {
|
2022-06-08 23:18:26 +00:00
|
|
|
ni, ok := c.cfgNetmap.state.getNodeInfo()
|
|
|
|
if ok {
|
|
|
|
return ni.NumberOfNetworkEndpoints()
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0
|
2021-06-11 10:55:11 +00:00
|
|
|
}
|
|
|
|
|
2023-04-05 13:58:32 +00:00
|
|
|
func initNetmapService(ctx context.Context, c *cfg) {
|
2021-06-23 09:50:40 +00:00
|
|
|
network.WriteToNodeInfo(c.localAddr, &c.cfgNodeInfo.localInfo)
|
2021-05-31 08:55:38 +00:00
|
|
|
c.cfgNodeInfo.localInfo.SetPublicKey(c.key.PublicKey().Bytes())
|
2022-06-08 23:18:26 +00:00
|
|
|
parseAttributes(c)
|
|
|
|
c.cfgNodeInfo.localInfo.SetOffline()
|
2020-10-08 13:17:50 +00:00
|
|
|
|
2021-02-19 08:01:37 +00:00
|
|
|
if c.cfgMorph.client == nil {
|
2023-04-05 13:58:32 +00:00
|
|
|
initMorphComponents(ctx, c)
|
2021-02-19 08:01:37 +00:00
|
|
|
}
|
|
|
|
|
2021-10-20 14:28:37 +00:00
|
|
|
initNetmapState(c)
|
|
|
|
|
2024-06-18 09:40:03 +00:00
|
|
|
svc := netmapService.NewSignService(
|
|
|
|
&c.key.PrivateKey,
|
|
|
|
netmapService.NewExecutionService(
|
|
|
|
c,
|
|
|
|
c.apiVersion,
|
|
|
|
&netInfo{
|
|
|
|
netState: c.cfgNetmap.state,
|
|
|
|
magic: c.cfgMorph.client,
|
|
|
|
morphClientNetMap: c.cfgNetmap.wrapper,
|
|
|
|
msPerBlockRdr: c.cfgMorph.client.MsPerBlock,
|
|
|
|
},
|
|
|
|
c.respSvc,
|
2020-10-08 13:17:50 +00:00
|
|
|
),
|
|
|
|
)
|
2024-06-18 09:40:03 +00:00
|
|
|
svc = netmapService.NewAuditService(svc, c.log, c.audit)
|
|
|
|
server := netmapTransportGRPC.New(svc)
|
2020-10-21 15:12:31 +00:00
|
|
|
|
2023-11-30 17:51:23 +00:00
|
|
|
c.cfgGRPC.performAndSave(func(_ string, _ net.Listener, s *grpc.Server) {
|
|
|
|
netmapGRPC.RegisterNetmapServiceServer(s, server)
|
|
|
|
})
|
2021-06-22 17:25:18 +00:00
|
|
|
|
2023-03-24 10:50:47 +00:00
|
|
|
addNewEpochNotificationHandlers(c)
|
|
|
|
}
|
|
|
|
|
|
|
|
func addNewEpochNotificationHandlers(c *cfg) {
|
2020-10-21 15:12:31 +00:00
|
|
|
addNewEpochNotificationHandler(c, func(ev event.Event) {
|
|
|
|
c.cfgNetmap.state.setCurrentEpoch(ev.(netmapEvent.NewEpoch).EpochNumber())
|
|
|
|
})
|
2020-10-30 12:57:49 +00:00
|
|
|
|
2021-04-15 10:24:43 +00:00
|
|
|
addNewEpochAsyncNotificationHandler(c, func(ev event.Event) {
|
2021-01-15 10:02:59 +00:00
|
|
|
e := ev.(netmapEvent.NewEpoch).EpochNumber()
|
|
|
|
|
2024-04-27 12:06:19 +00:00
|
|
|
c.updateContractNodeInfo(e)
|
2021-01-15 10:02:59 +00:00
|
|
|
|
2024-04-27 12:06:19 +00:00
|
|
|
if !c.needBootstrap() || c.cfgNetmap.reBoostrapTurnedOff.Load() { // fixes #470
|
2021-01-15 10:02:59 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2024-04-27 12:06:19 +00:00
|
|
|
if err := c.bootstrap(); err != nil {
|
|
|
|
c.log.Warn(logs.FrostFSNodeCantSendRebootstrapTx, zap.Error(err))
|
|
|
|
}
|
2021-01-15 10:02:59 +00:00
|
|
|
})
|
2021-09-30 19:11:20 +00:00
|
|
|
|
|
|
|
if c.cfgMorph.notaryEnabled {
|
2024-03-11 14:11:49 +00:00
|
|
|
addNewEpochAsyncNotificationHandler(c, func(_ event.Event) {
|
2021-09-30 19:11:20 +00:00
|
|
|
_, err := makeNotaryDeposit(c)
|
|
|
|
if err != nil {
|
2023-04-12 14:35:10 +00:00
|
|
|
c.log.Error(logs.FrostFSNodeCouldNotMakeNotaryDeposit,
|
2021-09-30 19:11:20 +00:00
|
|
|
zap.String("error", err.Error()),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
2020-10-08 13:17:50 +00:00
|
|
|
}
|
|
|
|
|
2021-10-20 14:28:37 +00:00
|
|
|
// bootstrapNode adds current node to the Network map.
|
|
|
|
// Must be called after initNetmapService.
|
2020-10-08 13:17:50 +00:00
|
|
|
func bootstrapNode(c *cfg) {
|
2021-08-24 07:43:21 +00:00
|
|
|
if c.needBootstrap() {
|
2023-06-13 09:11:59 +00:00
|
|
|
if c.IsMaintenance() {
|
|
|
|
c.log.Info(logs.FrostFSNodeNodeIsUnderMaintenanceSkipInitialBootstrap)
|
|
|
|
return
|
|
|
|
}
|
2022-10-28 07:02:55 +00:00
|
|
|
err := c.bootstrap()
|
2021-08-24 07:43:21 +00:00
|
|
|
fatalOnErrDetails("bootstrap error", err)
|
|
|
|
}
|
2020-10-08 13:17:50 +00:00
|
|
|
}
|
2020-10-21 09:26:16 +00:00
|
|
|
|
|
|
|
func addNetmapNotificationHandler(c *cfg, sTyp string, h event.Handler) {
|
|
|
|
typ := event.TypeFromString(sTyp)
|
|
|
|
|
|
|
|
if c.cfgNetmap.subscribers == nil {
|
|
|
|
c.cfgNetmap.subscribers = make(map[event.Type][]event.Handler, 1)
|
|
|
|
}
|
|
|
|
|
|
|
|
c.cfgNetmap.subscribers[typ] = append(c.cfgNetmap.subscribers[typ], h)
|
|
|
|
}
|
|
|
|
|
2021-08-12 15:24:17 +00:00
|
|
|
func setNetmapNotificationParser(c *cfg, sTyp string, p event.NotificationParser) {
|
2020-10-21 09:26:16 +00:00
|
|
|
typ := event.TypeFromString(sTyp)
|
|
|
|
|
|
|
|
if c.cfgNetmap.parsers == nil {
|
2021-08-12 15:24:17 +00:00
|
|
|
c.cfgNetmap.parsers = make(map[event.Type]event.NotificationParser, 1)
|
2020-10-21 09:26:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
c.cfgNetmap.parsers[typ] = p
|
|
|
|
}
|
|
|
|
|
2021-10-20 14:28:37 +00:00
|
|
|
// initNetmapState inits current Network map state.
|
|
|
|
// Must be called after Morph components initialization.
|
|
|
|
func initNetmapState(c *cfg) {
|
2020-10-21 16:26:38 +00:00
|
|
|
epoch, err := c.cfgNetmap.wrapper.Epoch()
|
2021-05-31 05:11:23 +00:00
|
|
|
fatalOnErrDetails("could not initialize current epoch number", err)
|
2020-10-21 16:26:38 +00:00
|
|
|
|
2023-07-14 13:22:38 +00:00
|
|
|
var ni *netmapSDK.NodeInfo
|
2023-10-05 08:30:41 +00:00
|
|
|
ni, err = c.netmapInitLocalNodeState(epoch)
|
2021-05-31 05:11:23 +00:00
|
|
|
fatalOnErrDetails("could not init network state", err)
|
2021-01-15 10:02:59 +00:00
|
|
|
|
2023-06-13 09:08:56 +00:00
|
|
|
stateWord := nodeState(ni)
|
2022-06-08 23:18:26 +00:00
|
|
|
|
2023-06-13 09:08:56 +00:00
|
|
|
c.log.Info(logs.FrostFSNodeInitialNetworkState,
|
|
|
|
zap.Uint64("epoch", epoch),
|
|
|
|
zap.String("state", stateWord),
|
|
|
|
)
|
|
|
|
|
2023-06-13 09:11:59 +00:00
|
|
|
if ni != nil && ni.IsMaintenance() {
|
|
|
|
c.isMaintenance.Store(true)
|
|
|
|
}
|
|
|
|
|
2023-06-13 09:08:56 +00:00
|
|
|
c.cfgNetmap.state.setCurrentEpoch(epoch)
|
|
|
|
c.cfgNetmap.startEpoch = epoch
|
2024-04-27 11:20:06 +00:00
|
|
|
c.setContractNodeInfo(ni)
|
2023-06-13 09:08:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func nodeState(ni *netmapSDK.NodeInfo) string {
|
2022-06-08 23:18:26 +00:00
|
|
|
if ni != nil {
|
|
|
|
switch {
|
|
|
|
case ni.IsOnline():
|
2023-06-13 09:08:56 +00:00
|
|
|
return "online"
|
2022-06-08 23:18:26 +00:00
|
|
|
case ni.IsOffline():
|
2023-06-13 09:08:56 +00:00
|
|
|
return "offline"
|
2023-06-13 09:06:04 +00:00
|
|
|
case ni.IsMaintenance():
|
2023-06-13 09:08:56 +00:00
|
|
|
return "maintenance"
|
2022-06-08 23:18:26 +00:00
|
|
|
}
|
|
|
|
}
|
2023-06-13 09:08:56 +00:00
|
|
|
return "undefined"
|
|
|
|
}
|
2022-06-08 23:18:26 +00:00
|
|
|
|
2023-10-05 08:30:41 +00:00
|
|
|
func (c *cfg) netmapInitLocalNodeState(epoch uint64) (*netmapSDK.NodeInfo, error) {
|
2023-06-13 09:08:56 +00:00
|
|
|
nmNodes, err := c.cfgNetmap.wrapper.GetCandidates()
|
|
|
|
if err != nil {
|
2023-10-05 08:30:41 +00:00
|
|
|
return nil, err
|
2023-06-13 09:08:56 +00:00
|
|
|
}
|
2020-10-21 16:26:38 +00:00
|
|
|
|
2023-06-13 09:08:56 +00:00
|
|
|
var candidate *netmapSDK.NodeInfo
|
|
|
|
for i := range nmNodes {
|
|
|
|
if bytes.Equal(nmNodes[i].PublicKey(), c.binPublicKey) {
|
|
|
|
candidate = &nmNodes[i]
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
node, err := c.netmapLocalNodeState(epoch)
|
|
|
|
if err != nil {
|
2023-10-05 08:30:41 +00:00
|
|
|
return nil, err
|
2023-06-13 09:08:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if candidate == nil {
|
2023-10-05 08:30:41 +00:00
|
|
|
return node, nil
|
2023-06-13 09:08:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nmState := nodeState(node)
|
|
|
|
candidateState := nodeState(candidate)
|
|
|
|
if nmState != candidateState {
|
|
|
|
// This happens when the node was switched to maintenance without epoch tick.
|
|
|
|
// We expect it to continue staying in maintenance.
|
2023-08-09 12:53:13 +00:00
|
|
|
c.log.Info(logs.CandidateStatusPriority,
|
2023-06-13 09:08:56 +00:00
|
|
|
zap.String("netmap", nmState),
|
|
|
|
zap.String("candidate", candidateState))
|
|
|
|
}
|
2023-10-05 08:30:41 +00:00
|
|
|
return candidate, nil
|
2020-10-21 16:26:38 +00:00
|
|
|
}
|
|
|
|
|
2021-02-19 08:01:37 +00:00
|
|
|
func (c *cfg) netmapLocalNodeState(epoch uint64) (*netmapSDK.NodeInfo, error) {
|
2021-01-15 10:02:59 +00:00
|
|
|
// calculate current network state
|
|
|
|
nm, err := c.cfgNetmap.wrapper.GetNetMapByEpoch(epoch)
|
|
|
|
if err != nil {
|
2021-01-25 08:23:06 +00:00
|
|
|
return nil, err
|
2021-01-15 10:02:59 +00:00
|
|
|
}
|
|
|
|
|
2022-09-17 12:37:01 +00:00
|
|
|
c.netMap.Store(*nm)
|
|
|
|
|
2022-06-08 23:18:26 +00:00
|
|
|
nmNodes := nm.Nodes()
|
|
|
|
for i := range nmNodes {
|
2022-06-16 21:45:32 +00:00
|
|
|
if bytes.Equal(nmNodes[i].PublicKey(), c.binPublicKey) {
|
2022-06-08 23:18:26 +00:00
|
|
|
return &nmNodes[i], nil
|
2021-01-15 10:02:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-06-08 23:18:26 +00:00
|
|
|
return nil, nil
|
2021-01-15 10:02:59 +00:00
|
|
|
}
|
|
|
|
|
2022-10-17 12:03:55 +00:00
|
|
|
// addNewEpochNotificationHandler adds handler that will be executed synchronously.
|
2020-10-21 09:26:16 +00:00
|
|
|
func addNewEpochNotificationHandler(c *cfg, h event.Handler) {
|
|
|
|
addNetmapNotificationHandler(c, newEpochNotification, h)
|
|
|
|
}
|
2021-01-11 11:57:01 +00:00
|
|
|
|
2022-10-17 12:03:55 +00:00
|
|
|
// addNewEpochAsyncNotificationHandler adds handler that will be executed asynchronously via netmap workerPool.
|
2021-04-13 12:53:58 +00:00
|
|
|
func addNewEpochAsyncNotificationHandler(c *cfg, h event.Handler) {
|
|
|
|
addNetmapNotificationHandler(
|
|
|
|
c,
|
|
|
|
newEpochNotification,
|
|
|
|
event.WorkerPoolHandler(
|
|
|
|
c.cfgNetmap.workerPool,
|
|
|
|
h,
|
|
|
|
c.log,
|
|
|
|
),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2021-08-24 07:43:21 +00:00
|
|
|
var errRelayBootstrap = errors.New("setting netmap status is forbidden in relay mode")
|
|
|
|
|
2021-01-15 11:53:41 +00:00
|
|
|
func (c *cfg) SetNetmapStatus(st control.NetmapStatus) error {
|
2022-09-19 12:41:04 +00:00
|
|
|
switch st {
|
|
|
|
default:
|
|
|
|
return fmt.Errorf("unsupported status %v", st)
|
|
|
|
case control.NetmapStatus_MAINTENANCE:
|
2022-10-18 15:42:14 +00:00
|
|
|
return c.setMaintenanceStatus(false)
|
2022-09-19 12:41:04 +00:00
|
|
|
case control.NetmapStatus_ONLINE, control.NetmapStatus_OFFLINE:
|
2021-11-09 15:54:03 +00:00
|
|
|
}
|
|
|
|
|
2022-10-04 13:01:16 +00:00
|
|
|
c.stopMaintenance()
|
2021-11-09 15:54:03 +00:00
|
|
|
|
2021-08-24 07:43:21 +00:00
|
|
|
if !c.needBootstrap() {
|
|
|
|
return errRelayBootstrap
|
|
|
|
}
|
|
|
|
|
2021-01-15 11:53:41 +00:00
|
|
|
if st == control.NetmapStatus_ONLINE {
|
2021-04-21 13:26:04 +00:00
|
|
|
c.cfgNetmap.reBoostrapTurnedOff.Store(false)
|
2022-10-28 07:02:55 +00:00
|
|
|
return bootstrapOnline(c)
|
2021-01-15 11:53:41 +00:00
|
|
|
}
|
|
|
|
|
2021-04-21 13:26:04 +00:00
|
|
|
c.cfgNetmap.reBoostrapTurnedOff.Store(true)
|
|
|
|
|
2022-09-19 16:59:23 +00:00
|
|
|
return c.updateNetMapState(func(*nmClient.UpdatePeerPrm) {})
|
|
|
|
}
|
2021-11-10 11:05:51 +00:00
|
|
|
|
2024-06-20 13:03:58 +00:00
|
|
|
func (c *cfg) GetNetmapStatus() (control.NetmapStatus, uint64, error) {
|
|
|
|
epoch, err := c.netMapSource.Epoch()
|
|
|
|
if err != nil {
|
|
|
|
return control.NetmapStatus_STATUS_UNDEFINED, 0, fmt.Errorf("failed to get current epoch: %w", err)
|
|
|
|
}
|
|
|
|
st := c.NetmapStatus()
|
|
|
|
return st, epoch, nil
|
|
|
|
}
|
|
|
|
|
2022-10-18 15:42:14 +00:00
|
|
|
func (c *cfg) ForceMaintenance() error {
|
|
|
|
return c.setMaintenanceStatus(true)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *cfg) setMaintenanceStatus(force bool) error {
|
|
|
|
netSettings, err := c.cfgNetmap.wrapper.ReadNetworkConfiguration()
|
|
|
|
if err != nil {
|
|
|
|
err = fmt.Errorf("read network settings to check maintenance allowance: %w", err)
|
|
|
|
} else if !netSettings.MaintenanceModeAllowed {
|
|
|
|
err = errors.New("maintenance mode is not allowed by the network")
|
|
|
|
}
|
|
|
|
|
|
|
|
if err == nil || force {
|
|
|
|
c.startMaintenance()
|
|
|
|
|
|
|
|
if err == nil {
|
|
|
|
err = c.updateNetMapState((*nmClient.UpdatePeerPrm).SetMaintenance)
|
|
|
|
}
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("local maintenance is started, but state is not updated in the network: %w", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2022-09-19 16:59:23 +00:00
|
|
|
// calls UpdatePeerState operation of Netmap contract's client for the local node.
|
|
|
|
// State setter is used to specify node state to switch to.
|
|
|
|
func (c *cfg) updateNetMapState(stateSetter func(*nmClient.UpdatePeerPrm)) error {
|
|
|
|
var prm nmClient.UpdatePeerPrm
|
2021-11-10 11:05:51 +00:00
|
|
|
prm.SetKey(c.key.PublicKey().Bytes())
|
2022-09-19 16:59:23 +00:00
|
|
|
stateSetter(&prm)
|
2021-11-10 11:05:51 +00:00
|
|
|
|
2023-11-08 09:05:03 +00:00
|
|
|
_, err := c.cfgNetmap.wrapper.UpdatePeerState(prm)
|
|
|
|
return err
|
2021-01-15 11:53:41 +00:00
|
|
|
}
|
2021-02-19 08:01:37 +00:00
|
|
|
|
|
|
|
type netInfo struct {
|
|
|
|
netState netmap.State
|
|
|
|
|
|
|
|
magic interface {
|
2021-08-26 08:17:31 +00:00
|
|
|
MagicNumber() (uint64, error)
|
2021-02-19 08:01:37 +00:00
|
|
|
}
|
2021-09-20 16:13:17 +00:00
|
|
|
|
2022-06-08 23:18:26 +00:00
|
|
|
morphClientNetMap *nmClient.Client
|
2021-09-20 16:13:17 +00:00
|
|
|
|
|
|
|
msPerBlockRdr func() (int64, error)
|
2021-02-19 08:01:37 +00:00
|
|
|
}
|
|
|
|
|
2022-06-08 23:18:26 +00:00
|
|
|
func (n *netInfo) Dump(ver version.Version) (*netmapSDK.NetworkInfo, error) {
|
2021-08-26 08:17:31 +00:00
|
|
|
magic, err := n.magic.MagicNumber()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2022-06-08 23:18:26 +00:00
|
|
|
var ni netmapSDK.NetworkInfo
|
2021-02-19 08:01:37 +00:00
|
|
|
ni.SetCurrentEpoch(n.netState.CurrentEpoch())
|
2021-08-26 08:17:31 +00:00
|
|
|
ni.SetMagicNumber(magic)
|
2021-02-19 08:01:37 +00:00
|
|
|
|
2022-06-08 23:18:26 +00:00
|
|
|
netInfoMorph, err := n.morphClientNetMap.ReadNetworkConfiguration()
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("read network configuration using netmap contract client: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if mjr := ver.Major(); mjr > 2 || mjr == 2 && ver.Minor() > 9 {
|
2021-09-20 16:13:17 +00:00
|
|
|
msPerBlock, err := n.msPerBlockRdr()
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("ms per block: %w", err)
|
|
|
|
}
|
|
|
|
|
2022-06-08 23:18:26 +00:00
|
|
|
ni.SetMsPerBlock(msPerBlock)
|
2021-09-20 16:13:17 +00:00
|
|
|
|
2022-06-08 23:18:26 +00:00
|
|
|
ni.SetMaxObjectSize(netInfoMorph.MaxObjectSize)
|
|
|
|
ni.SetEpochDuration(netInfoMorph.EpochDuration)
|
|
|
|
ni.SetContainerFee(netInfoMorph.ContainerFee)
|
|
|
|
ni.SetNamedContainerFee(netInfoMorph.ContainerAliasFee)
|
|
|
|
ni.SetIRCandidateFee(netInfoMorph.IRCandidateFee)
|
|
|
|
ni.SetWithdrawalFee(netInfoMorph.WithdrawalFee)
|
|
|
|
|
2022-09-19 15:31:56 +00:00
|
|
|
if netInfoMorph.HomomorphicHashingDisabled {
|
|
|
|
ni.DisableHomomorphicHashing()
|
|
|
|
}
|
|
|
|
|
2022-09-19 15:43:53 +00:00
|
|
|
if netInfoMorph.MaintenanceModeAllowed {
|
|
|
|
ni.AllowMaintenanceMode()
|
|
|
|
}
|
|
|
|
|
2022-06-08 23:18:26 +00:00
|
|
|
for i := range netInfoMorph.Raw {
|
|
|
|
ni.SetRawNetworkParameter(netInfoMorph.Raw[i].Name, netInfoMorph.Raw[i].Value)
|
2021-09-20 16:13:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-06-08 23:18:26 +00:00
|
|
|
return &ni, nil
|
2021-02-19 08:01:37 +00:00
|
|
|
}
|