diff --git a/pkg/netmap/node_info.go b/pkg/netmap/node_info.go index 35f16179..3e62bbdd 100644 --- a/pkg/netmap/node_info.go +++ b/pkg/netmap/node_info.go @@ -332,15 +332,52 @@ func (i *NodeInfo) SetPublicKey(key []byte) { } // Address returns network endpoint address of the node. -func (i *NodeInfo) Address() string { - return (*netmap.NodeInfo)(i). - GetAddress() +// +// Deprecated: use IterateAddresses method. +func (i *NodeInfo) Address() (addr string) { + i.IterateAddresses(func(s string) bool { + addr = s + return true + }) + + return } // SetAddress sets network endpoint address of the node. +// +// Deprecated: use SetAddresses method. func (i *NodeInfo) SetAddress(addr string) { + i.SetAddresses(addr) +} + +// NumberOfAddresses returns number of network addresses of the node. +func (i *NodeInfo) NumberOfAddresses() int { + return (*netmap.NodeInfo)(i). + NumberOfAddresses() +} + +// IterateAddresses iterates over network addresses of the node. +// Breaks iteration on f's true return. +// +// Handler should not be nil. +func (i *NodeInfo) IterateAddresses(f func(string) bool) { (*netmap.NodeInfo)(i). - SetAddress(addr) + IterateAddresses(f) +} + +// IterateAllAddresses is a helper function to unconditionally +// iterate over all node addresses. +func IterateAllAddresses(i *NodeInfo, f func(string)) { + i.IterateAddresses(func(addr string) bool { + f(addr) + return false + }) +} + +// SetAddresses sets list of network addresses of the node. +func (i *NodeInfo) SetAddresses(v ...string) { + (*netmap.NodeInfo)(i). + SetAddresses(v...) } // Attributes returns list of the node attributes. diff --git a/pkg/netmap/node_info_test.go b/pkg/netmap/node_info_test.go index 5d09a593..ebcd3931 100644 --- a/pkg/netmap/node_info_test.go +++ b/pkg/netmap/node_info_test.go @@ -124,13 +124,21 @@ func TestNodeInfo_PublicKey(t *testing.T) { require.Equal(t, key, i.PublicKey()) } -func TestNodeInfo_Address(t *testing.T) { +func TestNodeInfo_IterateAddresses(t *testing.T) { i := new(NodeInfo) - a := "127.0.0.1:8080" - i.SetAddress(a) + as := []string{"127.0.0.1:8080", "127.0.0.1:8081"} - require.Equal(t, a, i.Address()) + i.SetAddresses(as...) + + as2 := make([]string, 0, i.NumberOfAddresses()) + + IterateAllAddresses(i, func(addr string) { + as2 = append(as2, addr) + }) + + require.Equal(t, as, as2) + require.EqualValues(t, len(as), i.NumberOfAddresses()) } func TestNodeInfo_State(t *testing.T) { @@ -178,7 +186,7 @@ func TestNodeAttributeEncoding(t *testing.T) { func TestNodeInfoEncoding(t *testing.T) { i := NewNodeInfo() i.SetPublicKey([]byte{1, 2, 3}) - i.SetAddress("192.168.0.1") + i.SetAddresses("192.168.0.1", "192.168.0.2") i.SetState(NodeStateOnline) i.SetAttributes(testNodeAttribute()) @@ -227,7 +235,8 @@ func TestNewNodeInfo(t *testing.T) { // check initial values require.Nil(t, ni.PublicKey()) - require.Empty(t, ni.Address()) + + require.Zero(t, ni.NumberOfAddresses()) require.Nil(t, ni.Attributes()) require.Zero(t, ni.State()) @@ -235,7 +244,7 @@ func TestNewNodeInfo(t *testing.T) { niV2 := ni.ToV2() require.Nil(t, niV2.GetPublicKey()) - require.Empty(t, niV2.GetAddress()) + require.Zero(t, niV2.NumberOfAddresses()) require.Nil(t, niV2.GetAttributes()) require.EqualValues(t, netmap.UnspecifiedState, niV2.GetState()) }) diff --git a/pkg/netmap/test/generate.go b/pkg/netmap/test/generate.go index 51a43c2d..a2a1394a 100644 --- a/pkg/netmap/test/generate.go +++ b/pkg/netmap/test/generate.go @@ -84,7 +84,7 @@ func NodeAttribute() *netmap.NodeAttribute { func NodeInfo() *netmap.NodeInfo { x := netmap.NewNodeInfo() - x.SetAddress("address") + x.SetAddresses("address 1", "address 2") x.SetPublicKey([]byte("public key")) x.SetState(netmap.NodeStateOnline) x.SetAttributes(NodeAttribute(), NodeAttribute()) diff --git a/v2/netmap/convert.go b/v2/netmap/convert.go index 3c644952..06bddbf1 100644 --- a/v2/netmap/convert.go +++ b/v2/netmap/convert.go @@ -342,7 +342,7 @@ func (ni *NodeInfo) ToGRPCMessage() grpc.Message { m = new(netmap.NodeInfo) m.SetPublicKey(ni.publicKey) - m.SetAddress(ni.address) + m.SetAddresses(ni.addresses) m.SetState(NodeStateToGRPCMessage(ni.state)) m.SetAttributes(AttributesToGRPC(ni.attributes)) } @@ -364,7 +364,7 @@ func (ni *NodeInfo) FromGRPCMessage(m grpc.Message) error { } ni.publicKey = v.GetPublicKey() - ni.address = v.GetAddress() + ni.addresses = v.GetAddresses() ni.state = NodeStateFromRPCMessage(v.GetState()) return nil diff --git a/v2/netmap/grpc/types.go b/v2/netmap/grpc/types.go index 4340d194..9ba148e5 100644 --- a/v2/netmap/grpc/types.go +++ b/v2/netmap/grpc/types.go @@ -134,9 +134,16 @@ func (m *NodeInfo_Attribute) SetParents(v []string) { } // SetAddress sets node network address. +// +// Deprecated: use SetAddresses. func (m *NodeInfo) SetAddress(v string) { + m.SetAddresses([]string{v}) +} + +// SetAddresses sets list of network addresses of the node. +func (m *NodeInfo) SetAddresses(v []string) { if m != nil { - m.Address = v + m.Addresses = v } } diff --git a/v2/netmap/grpc/types.pb.go b/v2/netmap/grpc/types.pb.go index ca9190e6..caee48bd 100644 Binary files a/v2/netmap/grpc/types.pb.go and b/v2/netmap/grpc/types.pb.go differ diff --git a/v2/netmap/marshal.go b/v2/netmap/marshal.go index 79da27a5..abdc7dff 100644 --- a/v2/netmap/marshal.go +++ b/v2/netmap/marshal.go @@ -367,7 +367,7 @@ func (ni *NodeInfo) StableMarshal(buf []byte) ([]byte, error) { offset += n - n, err = protoutil.StringMarshal(addressNodeInfoField, buf[offset:], ni.address) + n, err = protoutil.RepeatedStringMarshal(addressNodeInfoField, buf[offset:], ni.addresses) if err != nil { return nil, err } @@ -397,7 +397,8 @@ func (ni *NodeInfo) StableSize() (size int) { } size += protoutil.BytesSize(keyNodeInfoField, ni.publicKey) - size += protoutil.StringSize(addressNodeInfoField, ni.address) + size += protoutil.RepeatedStringSize(addressNodeInfoField, ni.addresses) + for i := range ni.attributes { size += protoutil.NestedStructureSize(attributesNodeInfoField, ni.attributes[i]) } diff --git a/v2/netmap/test/generate.go b/v2/netmap/test/generate.go index ce94338b..f9f316fa 100644 --- a/v2/netmap/test/generate.go +++ b/v2/netmap/test/generate.go @@ -135,7 +135,7 @@ func GenerateNodeInfo(empty bool) *netmap.NodeInfo { m := new(netmap.NodeInfo) if !empty { - m.SetAddress("node address") + m.SetAddresses("node address", "node address 2") m.SetPublicKey([]byte{1, 2, 3}) m.SetState(33) m.SetAttributes(GenerateAttributes(empty)) diff --git a/v2/netmap/types.go b/v2/netmap/types.go index e67e0a6e..858d8448 100644 --- a/v2/netmap/types.go +++ b/v2/netmap/types.go @@ -71,7 +71,7 @@ type Attribute struct { // NodeInfo of storage node. type NodeInfo struct { publicKey []byte - address string + addresses []string attributes []*Attribute state NodeState } @@ -386,17 +386,52 @@ func (ni *NodeInfo) SetPublicKey(v []byte) { } } -func (ni *NodeInfo) GetAddress() string { - if ni != nil { - return ni.address - } +// GetAddress returns node's network address. +// +// Deprecated: use IterateAddresses. +func (ni *NodeInfo) GetAddress() (addr string) { + ni.IterateAddresses(func(s string) bool { + addr = s + return true + }) - return "" + return } +// SetAddress sets node's network address. +// +// Deprecated: use SetAddresses. func (ni *NodeInfo) SetAddress(v string) { + ni.SetAddresses(v) +} + +// SetAddresses sets list of network addresses of the node. +func (ni *NodeInfo) SetAddresses(v ...string) { if ni != nil { - ni.address = v + ni.addresses = v + } +} + +// NumberOfAddresses returns number of network addresses of the node. +func (ni *NodeInfo) NumberOfAddresses() int { + if ni != nil { + return len(ni.addresses) + } + + return 0 +} + +// IterateAddresses iterates over network addresses of the node. +// Breaks iteration on f's true return. +// +// Handler should not be nil. +func (ni *NodeInfo) IterateAddresses(f func(string) bool) { + if ni != nil { + for i := range ni.addresses { + if f(ni.addresses[i]) { + break + } + } } }