package nodeconf import ( "strings" "github.com/anyproto/go-chash" ) type NodeConf interface { // Id returns current nodeconf id Id() string // Configuration returns configuration struct Configuration() Configuration // NodeIds returns list of peerId for given spaceId NodeIds(spaceId string) []string // IsResponsible checks if current account responsible for given spaceId IsResponsible(spaceId string) bool // FilePeers returns list of filenodes FilePeers() []string // ConsensusPeers returns list of consensusnodes ConsensusPeers() []string // CoordinatorPeers returns list of coordinator nodes CoordinatorPeers() []string // Please see any-ns-node repo for details // Usually one network has only 1 naming node, but we support array of NNs NamingNodePeers() []string // Please see any-pp-node repo for details PaymentProcessingNodePeers() []string // PeerAddresses returns peer addresses by peer id PeerAddresses(peerId string) (addrs []string, ok bool) // CHash returns nodes consistent table CHash() chash.CHash // Partition returns partition number by spaceId Partition(spaceId string) (part int) // NodeTypes returns list of known nodeTypes by nodeId, if node not registered in configuration will return empty list NodeTypes(nodeId string) []NodeType } type nodeConf struct { id string accountId string filePeers []string consensusPeers []string coordinatorPeers []string namingNodePeers []string paymentProcessingNodePeers []string chash chash.CHash allMembers []Node c Configuration addrs map[string][]string } func (c *nodeConf) Id() string { return c.id } func (c *nodeConf) Configuration() Configuration { return c.c } func (c *nodeConf) NodeIds(spaceId string) []string { members := c.chash.GetMembers(ReplKey(spaceId)) res := make([]string, 0, len(members)) for _, m := range members { if m.Id() != c.accountId { res = append(res, m.Id()) } } return res } func (c *nodeConf) IsResponsible(spaceId string) bool { for _, m := range c.chash.GetMembers(ReplKey(spaceId)) { if m.Id() == c.accountId { return true } } return false } func (c *nodeConf) FilePeers() []string { return c.filePeers } func (c *nodeConf) ConsensusPeers() []string { return c.consensusPeers } func (c *nodeConf) CoordinatorPeers() []string { return c.coordinatorPeers } func (c *nodeConf) NamingNodePeers() []string { return c.namingNodePeers } func (c *nodeConf) PaymentProcessingNodePeers() []string { return c.paymentProcessingNodePeers } func (c *nodeConf) PeerAddresses(peerId string) (addrs []string, ok bool) { addrs, ok = c.addrs[peerId] if ok && len(addrs) == 0 { return nil, false } return } func (c *nodeConf) CHash() chash.CHash { return c.chash } func (c *nodeConf) Partition(spaceId string) (part int) { return c.chash.GetPartition(ReplKey(spaceId)) } func (c *nodeConf) NodeTypes(nodeId string) []NodeType { for _, m := range c.allMembers { if m.PeerId == nodeId { return m.Types } } return nil } func ReplKey(spaceId string) (replKey string) { if i := strings.LastIndex(spaceId, "."); i != -1 { return spaceId[i+1:] } return spaceId } func сonfigurationToNodeConf(c Configuration) (nc *nodeConf, err error) { nc = &nodeConf{ id: c.Id, c: c, // WARN: do not forget to set it later, Configuration does not feature it //accountId: s.accountId, addrs: map[string][]string{}, } if nc.chash, err = chash.New(chash.Config{ PartitionCount: PartitionCount, ReplicationFactor: ReplicationFactor, }); err != nil { return } members := make([]chash.Member, 0, len(c.Nodes)) for _, n := range c.Nodes { if n.HasType(NodeTypeTree) { members = append(members, n) } if n.HasType(NodeTypeConsensus) { nc.consensusPeers = append(nc.consensusPeers, n.PeerId) } if n.HasType(NodeTypeFile) { nc.filePeers = append(nc.filePeers, n.PeerId) } if n.HasType(NodeTypeCoordinator) { nc.coordinatorPeers = append(nc.coordinatorPeers, n.PeerId) } if n.HasType(NodeTypeNamingNode) { nc.namingNodePeers = append(nc.namingNodePeers, n.PeerId) } if n.HasType(NodeTypePaymentProcessingNode) { nc.paymentProcessingNodePeers = append(nc.paymentProcessingNodePeers, n.PeerId) } nc.allMembers = append(nc.allMembers, n) nc.addrs[n.PeerId] = n.Addresses } err = nc.chash.AddMembers(members...) return }