2020-09-05 10:37:47 +00:00
|
|
|
package netmap
|
|
|
|
|
|
|
|
import (
|
|
|
|
"strconv"
|
|
|
|
|
|
|
|
"github.com/nspcc-dev/hrw"
|
|
|
|
"github.com/nspcc-dev/neofs-api-go/v2/netmap"
|
|
|
|
)
|
|
|
|
|
|
|
|
type (
|
|
|
|
// Node is a wrapper over NodeInfo.
|
|
|
|
Node struct {
|
|
|
|
ID uint64
|
|
|
|
Index int
|
|
|
|
Capacity uint64
|
|
|
|
Price uint64
|
|
|
|
AttrMap map[string]string
|
|
|
|
|
|
|
|
InfoV2 *netmap.NodeInfo
|
|
|
|
}
|
|
|
|
|
|
|
|
// Nodes represents slice of graph leafs.
|
|
|
|
Nodes []*Node
|
|
|
|
)
|
|
|
|
|
2020-11-05 11:24:52 +00:00
|
|
|
// NodeState is an enumeration of various states of the NeoFS node.
|
|
|
|
type NodeState uint32
|
|
|
|
|
|
|
|
const (
|
|
|
|
_ NodeState = iota
|
|
|
|
|
|
|
|
// NodeStateOffline is network unavailable state.
|
|
|
|
NodeStateOffline
|
|
|
|
|
|
|
|
// NodeStateOnline is an active state in the network.
|
|
|
|
NodeStateOnline
|
|
|
|
)
|
|
|
|
|
2020-09-05 10:37:47 +00:00
|
|
|
// Enumeration of well-known attributes.
|
|
|
|
const (
|
|
|
|
CapacityAttr = "Capacity"
|
|
|
|
PriceAttr = "Price"
|
|
|
|
)
|
|
|
|
|
|
|
|
var _ hrw.Hasher = (*Node)(nil)
|
|
|
|
|
|
|
|
// Hash is a function from hrw.Hasher interface. It is implemented
|
|
|
|
// to support weighted hrw therefore sort function sorts nodes
|
|
|
|
// based on their `N` value.
|
|
|
|
func (n Node) Hash() uint64 {
|
|
|
|
return n.ID
|
|
|
|
}
|
|
|
|
|
2020-09-17 10:11:40 +00:00
|
|
|
// NetworkAddress returns network address
|
|
|
|
// of the node in a string format.
|
|
|
|
func (n Node) NetworkAddress() string {
|
|
|
|
return n.InfoV2.GetAddress()
|
|
|
|
}
|
|
|
|
|
2020-09-21 12:56:21 +00:00
|
|
|
// PublicKey returns public key of the node in bytes.
|
|
|
|
func (n Node) PublicKey() []byte {
|
|
|
|
return n.InfoV2.GetPublicKey()
|
|
|
|
}
|
|
|
|
|
2020-09-05 10:37:47 +00:00
|
|
|
// NodesFromV2 converts slice of v2 netmap.NodeInfo to a generic node slice.
|
|
|
|
func NodesFromV2(infos []netmap.NodeInfo) Nodes {
|
|
|
|
nodes := make(Nodes, len(infos))
|
|
|
|
for i := range infos {
|
|
|
|
nodes[i] = newNodeV2(i, &infos[i])
|
|
|
|
}
|
|
|
|
return nodes
|
|
|
|
}
|
|
|
|
|
|
|
|
func newNodeV2(index int, ni *netmap.NodeInfo) *Node {
|
|
|
|
n := &Node{
|
|
|
|
ID: hrw.Hash(ni.GetPublicKey()),
|
|
|
|
Index: index,
|
|
|
|
AttrMap: make(map[string]string, len(ni.GetAttributes())),
|
|
|
|
InfoV2: ni,
|
|
|
|
}
|
|
|
|
for _, attr := range ni.GetAttributes() {
|
|
|
|
switch attr.GetKey() {
|
|
|
|
case CapacityAttr:
|
|
|
|
n.Capacity, _ = strconv.ParseUint(attr.GetValue(), 10, 64)
|
|
|
|
case PriceAttr:
|
|
|
|
n.Price, _ = strconv.ParseUint(attr.GetValue(), 10, 64)
|
|
|
|
}
|
|
|
|
n.AttrMap[attr.GetKey()] = attr.GetValue()
|
|
|
|
}
|
|
|
|
return n
|
|
|
|
}
|
|
|
|
|
|
|
|
// Weights returns slice of nodes weights W.
|
|
|
|
func (n Nodes) Weights(wf weightFunc) []float64 {
|
|
|
|
w := make([]float64, 0, len(n))
|
|
|
|
for i := range n {
|
|
|
|
w = append(w, wf(n[i]))
|
|
|
|
}
|
|
|
|
return w
|
|
|
|
}
|
|
|
|
|
|
|
|
// Attribute returns value of attribute k.
|
|
|
|
func (n *Node) Attribute(k string) string {
|
|
|
|
return n.AttrMap[k]
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetBucketWeight computes weight for a Bucket.
|
|
|
|
func GetBucketWeight(ns Nodes, a aggregator, wf weightFunc) float64 {
|
|
|
|
for i := range ns {
|
|
|
|
a.Add(wf(ns[i]))
|
|
|
|
}
|
|
|
|
return a.Compute()
|
|
|
|
}
|
2020-11-05 11:24:52 +00:00
|
|
|
|
|
|
|
// NodeStateFromV2 converts v2 NodeState to NodeState.
|
|
|
|
func NodeStateFromV2(s netmap.NodeState) NodeState {
|
|
|
|
switch s {
|
|
|
|
default:
|
|
|
|
return 0
|
|
|
|
case netmap.Online:
|
|
|
|
return NodeStateOnline
|
|
|
|
case netmap.Offline:
|
|
|
|
return NodeStateOffline
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// ToV2 converts NodeState to v2 NodeState.
|
|
|
|
func (s NodeState) ToV2() netmap.NodeState {
|
|
|
|
switch s {
|
|
|
|
default:
|
|
|
|
return netmap.UnspecifiedState
|
|
|
|
case NodeStateOffline:
|
|
|
|
return netmap.Offline
|
|
|
|
case NodeStateOnline:
|
|
|
|
return netmap.Online
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s NodeState) String() string {
|
|
|
|
switch s {
|
|
|
|
default:
|
|
|
|
return "UNSPECIFIED"
|
|
|
|
case NodeStateOffline:
|
|
|
|
return "OFFLINE"
|
|
|
|
case NodeStateOnline:
|
|
|
|
return "ONLINE"
|
|
|
|
}
|
|
|
|
}
|