[#339] netmap: Support protocol changes related to NetworkInfo

Recompile NeoFS API protobuf files. Implement `NetworkParameter` and
`NetworkConfig` types. Expand `NetworkInfo` type with MillisecondsPerBlock
and `NetworkConfig`.

Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
This commit is contained in:
Leonard Lyubich 2021-09-28 11:10:20 +03:00 committed by Alex Vanin
parent 520a065dd2
commit 010b1b0118
11 changed files with 682 additions and 7 deletions

View file

@ -19,7 +19,9 @@ func NewNetworkInfoFromV2(iV2 *netmap.NetworkInfo) *NetworkInfo {
//
// Defaults:
// - curEpoch: 0;
// - magicNum: 0.
// - magicNum: 0;
// - msPerBlock: 0;
// - network config: nil.
func NewNetworkInfo() *NetworkInfo {
return NewNetworkInfoFromV2(new(netmap.NetworkInfo))
}
@ -55,6 +57,32 @@ func (i *NetworkInfo) SetMagicNumber(epoch uint64) {
SetMagicNumber(epoch)
}
// MsPerBlock returns MillisecondsPerBlock network parameter.
func (i *NetworkInfo) MsPerBlock() int64 {
return (*netmap.NetworkInfo)(i).
GetMsPerBlock()
}
// SetMsPerBlock sets MillisecondsPerBlock network parameter.
func (i *NetworkInfo) SetMsPerBlock(v int64) {
(*netmap.NetworkInfo)(i).
SetMsPerBlock(v)
}
// NetworkConfig returns NeoFS network configuration.
func (i *NetworkInfo) NetworkConfig() *NetworkConfig {
return NewNetworkConfigFromV2(
(*netmap.NetworkInfo)(i).
GetNetworkConfig(),
)
}
// SetNetworkConfig sets NeoFS network configuration.
func (i *NetworkInfo) SetNetworkConfig(v *NetworkConfig) {
(*netmap.NetworkInfo)(i).
SetNetworkConfig(v.ToV2())
}
// Marshal marshals NetworkInfo into a protobuf binary form.
//
// Buffer is allocated when the argument is empty.
@ -86,3 +114,112 @@ func (i *NetworkInfo) UnmarshalJSON(data []byte) error {
return (*netmap.NetworkInfo)(i).
UnmarshalJSON(data)
}
// NetworkParameter represents v2-compatible NeoFS network parameter.
type NetworkParameter netmap.NetworkParameter
// NewNetworkParameterFromV2 wraps v2 NetworkParameter message to NetworkParameter.
//
// Nil netmap.NetworkParameter converts to nil.
func NewNetworkParameterFromV2(pv2 *netmap.NetworkParameter) *NetworkParameter {
return (*NetworkParameter)(pv2)
}
// NewNetworkParameter creates and initializes blank NetworkParameter.
//
// Defaults:
// - key: nil;
// - value: nil.
func NewNetworkParameter() *NetworkParameter {
return NewNetworkParameterFromV2(new(netmap.NetworkParameter))
}
// ToV2 converts NetworkParameter to v2 NetworkParameter.
//
// Nil NetworkParameter converts to nil.
func (x *NetworkParameter) ToV2() *netmap.NetworkParameter {
return (*netmap.NetworkParameter)(x)
}
// Key returns key to network parameter.
func (x *NetworkParameter) Key() []byte {
return (*netmap.NetworkParameter)(x).
GetKey()
}
// SetKey sets key to the network parameter.
func (x *NetworkParameter) SetKey(key []byte) {
(*netmap.NetworkParameter)(x).
SetKey(key)
}
// Value returns value of the network parameter.
func (x *NetworkParameter) Value() []byte {
return (*netmap.NetworkParameter)(x).
GetValue()
}
// SetValue sets value of the network parameter.
func (x *NetworkParameter) SetValue(val []byte) {
(*netmap.NetworkParameter)(x).
SetValue(val)
}
// NetworkConfig represents v2-compatible NeoFS network configuration.
type NetworkConfig netmap.NetworkConfig
// NewNetworkConfigFromV2 wraps v2 NetworkConfig message to NetworkConfig.
//
// Nil netmap.NetworkConfig converts to nil.
func NewNetworkConfigFromV2(cv2 *netmap.NetworkConfig) *NetworkConfig {
return (*NetworkConfig)(cv2)
}
// NewNetworkConfig creates and initializes blank NetworkConfig.
//
// Defaults:
// - parameters num: 0.
func NewNetworkConfig() *NetworkConfig {
return NewNetworkConfigFromV2(new(netmap.NetworkConfig))
}
// ToV2 converts NetworkConfig to v2 NetworkConfig.
//
// Nil NetworkConfig converts to nil.
func (x *NetworkConfig) ToV2() *netmap.NetworkConfig {
return (*netmap.NetworkConfig)(x)
}
// NumberOfParameters returns number of network parameters.
func (x *NetworkConfig) NumberOfParameters() int {
return (*netmap.NetworkConfig)(x).NumberOfParameters()
}
// IterateAddresses iterates over network parameters.
// Breaks iteration on f's true return.
//
// Handler should not be nil.
func (x *NetworkConfig) IterateParameters(f func(*NetworkParameter) bool) {
(*netmap.NetworkConfig)(x).
IterateParameters(func(p *netmap.NetworkParameter) bool {
return f(NewNetworkParameterFromV2(p))
})
}
// Value returns value of the network parameter.
func (x *NetworkConfig) SetParameters(ps ...*NetworkParameter) {
var psV2 []*netmap.NetworkParameter
if ps != nil {
ln := len(ps)
psV2 = make([]*netmap.NetworkParameter, 0, ln)
for i := 0; i < ln; i++ {
psV2 = append(psV2, ps[i].ToV2())
}
}
(*netmap.NetworkConfig)(x).
SetParameters(psV2...)
}

View file

@ -1,11 +1,124 @@
package netmap
package netmap_test
import (
"testing"
. "github.com/nspcc-dev/neofs-api-go/pkg/netmap"
netmaptest "github.com/nspcc-dev/neofs-api-go/pkg/netmap/test"
"github.com/stretchr/testify/require"
)
func TestNetworkParameter_Key(t *testing.T) {
i := NewNetworkParameter()
k := []byte("key")
i.SetKey(k)
require.Equal(t, k, i.Key())
require.Equal(t, k, i.ToV2().GetKey())
}
func TestNetworkParameter_Value(t *testing.T) {
i := NewNetworkParameter()
v := []byte("value")
i.SetValue(v)
require.Equal(t, v, i.Value())
require.Equal(t, v, i.ToV2().GetValue())
}
func TestNewNetworkParameterFromV2(t *testing.T) {
t.Run("nil", func(t *testing.T) {
require.Nil(t, NewNetworkParameterFromV2(nil))
})
}
func TestNetworkParameter_ToV2(t *testing.T) {
t.Run("nil", func(t *testing.T) {
var x *NetworkParameter
require.Nil(t, x.ToV2())
})
}
func TestNewNetworkParameter(t *testing.T) {
x := NewNetworkParameter()
// check initial values
require.Nil(t, x.Key())
require.Nil(t, x.Value())
// convert to v2 message
xV2 := x.ToV2()
require.Nil(t, xV2.GetKey())
require.Nil(t, xV2.GetValue())
}
func TestNetworkConfig_SetParameters(t *testing.T) {
x := NewNetworkConfig()
require.Zero(t, x.NumberOfParameters())
called := 0
x.IterateParameters(func(p *NetworkParameter) bool {
called++
return false
})
require.Zero(t, called)
pps := []*NetworkParameter{
netmaptest.NetworkParameter(),
netmaptest.NetworkParameter(),
}
x.SetParameters(pps...)
require.EqualValues(t, len(pps), x.NumberOfParameters())
var dst []*NetworkParameter
x.IterateParameters(func(p *NetworkParameter) bool {
dst = append(dst, p)
called++
return false
})
require.Equal(t, pps, dst)
require.Equal(t, len(pps), called)
}
func TestNewNetworkConfigFromV2(t *testing.T) {
t.Run("nil", func(t *testing.T) {
require.Nil(t, NewNetworkConfigFromV2(nil))
})
}
func TestNetworkConfig_ToV2(t *testing.T) {
t.Run("nil", func(t *testing.T) {
var x *NetworkConfig
require.Nil(t, x.ToV2())
})
}
func TestNewNetworkConfig(t *testing.T) {
x := NewNetworkConfig()
// check initial values
require.Zero(t, x.NumberOfParameters())
// convert to v2 message
xV2 := x.ToV2()
require.Zero(t, xV2.NumberOfParameters())
}
func TestNetworkInfo_CurrentEpoch(t *testing.T) {
i := NewNetworkInfo()
e := uint64(13)
@ -26,10 +139,29 @@ func TestNetworkInfo_MagicNumber(t *testing.T) {
require.Equal(t, m, i.ToV2().GetMagicNumber())
}
func TestNetworkInfoEncoding(t *testing.T) {
func TestNetworkInfo_MsPerBlock(t *testing.T) {
i := NewNetworkInfo()
i.SetCurrentEpoch(13)
i.SetMagicNumber(666)
const ms = 987
i.SetMsPerBlock(ms)
require.EqualValues(t, ms, i.MsPerBlock())
require.EqualValues(t, ms, i.ToV2().GetMsPerBlock())
}
func TestNetworkInfo_Config(t *testing.T) {
i := NewNetworkInfo()
c := netmaptest.NetworkConfig()
i.SetNetworkConfig(c)
require.Equal(t, c, i.NetworkConfig())
}
func TestNetworkInfoEncoding(t *testing.T) {
i := netmaptest.NetworkInfo()
t.Run("binary", func(t *testing.T) {
data, err := i.Marshal()
@ -72,10 +204,12 @@ func TestNewNetworkInfo(t *testing.T) {
// check initial values
require.Zero(t, ni.CurrentEpoch())
require.Zero(t, ni.MagicNumber())
require.Zero(t, ni.MsPerBlock())
// convert to v2 message
niV2 := ni.ToV2()
require.Zero(t, niV2.GetCurrentEpoch())
require.Zero(t, niV2.GetMagicNumber())
require.Zero(t, niV2.GetMsPerBlock())
}

View file

@ -59,12 +59,36 @@ func PlacementPolicy() *netmap.PlacementPolicy {
return x
}
// NetworkParameter returns random netmap.NetworkParameter.
func NetworkParameter() *netmap.NetworkParameter {
x := netmap.NewNetworkParameter()
x.SetKey([]byte("key"))
x.SetValue([]byte("value"))
return x
}
// NetworkConfig returns random netmap.NetworkConfig.
func NetworkConfig() *netmap.NetworkConfig {
x := netmap.NewNetworkConfig()
x.SetParameters(
NetworkParameter(),
NetworkParameter(),
)
return x
}
// NetworkInfo returns random netmap.NetworkInfo.
func NetworkInfo() *netmap.NetworkInfo {
x := netmap.NewNetworkInfo()
x.SetCurrentEpoch(21)
x.SetMagicNumber(32)
x.SetMsPerBlock(43)
x.SetNetworkConfig(NetworkConfig())
return x
}

View file

@ -9,7 +9,7 @@ import (
// Version represents v2-compatible version.
type Version refs.Version
const sdkMjr, sdkMnr = 2, 9
const sdkMjr, sdkMnr = 2, 10
// NewVersionFromV2 wraps v2 Version message to Version.
//

View file

@ -514,6 +514,89 @@ func (l *LocalNodeInfoResponse) FromGRPCMessage(m grpc.Message) error {
return l.ResponseHeaders.FromMessage(v)
}
func (x *NetworkParameter) ToGRPCMessage() grpc.Message {
var m *netmap.NetworkConfig_Parameter
if x != nil {
m = new(netmap.NetworkConfig_Parameter)
m.SetKey(x.k)
m.SetValue(x.v)
}
return m
}
func (x *NetworkParameter) FromGRPCMessage(m grpc.Message) error {
v, ok := m.(*netmap.NetworkConfig_Parameter)
if !ok {
return message.NewUnexpectedMessageType(m, v)
}
x.k = v.GetKey()
x.v = v.GetValue()
return nil
}
func (x *NetworkConfig) ToGRPCMessage() grpc.Message {
var m *netmap.NetworkConfig
if x != nil {
m = new(netmap.NetworkConfig)
var ps []*netmap.NetworkConfig_Parameter
if ln := len(x.ps); ln > 0 {
ps = make([]*netmap.NetworkConfig_Parameter, 0, ln)
for i := 0; i < ln; i++ {
ps = append(ps, x.ps[i].ToGRPCMessage().(*netmap.NetworkConfig_Parameter))
}
}
m.SetParameters(ps)
}
return m
}
func (x *NetworkConfig) FromGRPCMessage(m grpc.Message) error {
v, ok := m.(*netmap.NetworkConfig)
if !ok {
return message.NewUnexpectedMessageType(m, v)
}
var (
ps []*NetworkParameter
psV2 = v.GetParameters()
)
if psV2 != nil {
ln := len(psV2)
ps = make([]*NetworkParameter, 0, ln)
for i := 0; i < ln; i++ {
var p *NetworkParameter
if psV2[i] != nil {
p = new(NetworkParameter)
if err := p.FromGRPCMessage(psV2[i]); err != nil {
return err
}
}
ps = append(ps, p)
}
}
x.ps = ps
return nil
}
func (i *NetworkInfo) ToGRPCMessage() grpc.Message {
var m *netmap.NetworkInfo
@ -522,6 +605,8 @@ func (i *NetworkInfo) ToGRPCMessage() grpc.Message {
m.SetMagicNumber(i.magicNum)
m.SetCurrentEpoch(i.curEpoch)
m.SetMsPerBlock(i.msPerBlock)
m.SetNetworkConfig(i.netCfg.ToGRPCMessage().(*netmap.NetworkConfig))
}
return m
@ -533,8 +618,25 @@ func (i *NetworkInfo) FromGRPCMessage(m grpc.Message) error {
return message.NewUnexpectedMessageType(m, v)
}
var err error
netCfg := v.GetNetworkConfig()
if netCfg == nil {
i.netCfg = nil
} else {
if i.netCfg == nil {
i.netCfg = new(NetworkConfig)
}
err = i.netCfg.FromGRPCMessage(netCfg)
if err != nil {
return err
}
}
i.magicNum = v.GetMagicNumber()
i.curEpoch = v.GetCurrentEpoch()
i.msPerBlock = v.GetMsPerBlock()
return nil
}

View file

@ -182,6 +182,20 @@ func (x *NetworkInfo) SetMagicNumber(v uint64) {
}
}
// SetMsPerBlock sets MillisecondsPerBlock network parameter.
func (x *NetworkInfo) SetMsPerBlock(v int64) {
if x != nil {
x.MsPerBlock = v
}
}
// SetNetworkConfig sets NeoFS network configuration.
func (x *NetworkInfo) SetNetworkConfig(v *NetworkConfig) {
if x != nil {
x.NetworkConfig = v
}
}
// FromString parses Clause from a string representation,
// It is a reverse action to String().
//
@ -220,3 +234,24 @@ func (x *NodeInfo_State) FromString(s string) bool {
return ok
}
// SetKey sets parameter key.
func (x *NetworkConfig_Parameter) SetKey(v []byte) {
if x != nil {
x.Key = v
}
}
// SetValue sets parameter value.
func (x *NetworkConfig_Parameter) SetValue(v []byte) {
if x != nil {
x.Value = v
}
}
// SetParameters sets NeoFS network parameters.
func (x *NetworkConfig) SetParameters(v []*NetworkConfig_Parameter) {
if x != nil {
x.Parameters = v
}
}

Binary file not shown.

View file

@ -468,10 +468,101 @@ func (l *LocalNodeInfoResponseBody) Unmarshal(data []byte) error {
return message.Unmarshal(l, data, new(netmap.LocalNodeInfoResponse_Body))
}
const (
_ = iota
netPrmKeyFNum
netPrmValFNum
)
func (x *NetworkParameter) StableMarshal(buf []byte) ([]byte, error) {
if x == nil {
return []byte{}, nil
}
if buf == nil {
buf = make([]byte, x.StableSize())
}
var (
offset, n int
err error
)
n, err = protoutil.BytesMarshal(netPrmKeyFNum, buf[offset:], x.k)
if err != nil {
return nil, err
}
offset += n
_, err = protoutil.BytesMarshal(netPrmValFNum, buf[offset:], x.v)
if err != nil {
return nil, err
}
return buf, nil
}
func (x *NetworkParameter) StableSize() (size int) {
if x == nil {
return 0
}
size += protoutil.BytesSize(netPrmKeyFNum, x.k)
size += protoutil.BytesSize(netPrmValFNum, x.v)
return size
}
const (
_ = iota
netCfgPrmsFNum
)
func (x *NetworkConfig) StableMarshal(buf []byte) ([]byte, error) {
if x == nil {
return []byte{}, nil
}
if buf == nil {
buf = make([]byte, x.StableSize())
}
var (
offset, n int
err error
)
for i := range x.ps {
n, err = protoutil.NestedStructureMarshal(netCfgPrmsFNum, buf[offset:], x.ps[i])
if err != nil {
return nil, err
}
offset += n
}
return buf, nil
}
func (x *NetworkConfig) StableSize() (size int) {
if x == nil {
return 0
}
for i := range x.ps {
size += protoutil.NestedStructureSize(netCfgPrmsFNum, x.ps[i])
}
return size
}
const (
_ = iota
netInfoCurEpochFNum
netInfoMagicNumFNum
netInfoMSPerBlockFNum
netInfoCfgFNum
)
func (i *NetworkInfo) StableMarshal(buf []byte) ([]byte, error) {
@ -495,7 +586,21 @@ func (i *NetworkInfo) StableMarshal(buf []byte) ([]byte, error) {
offset += n
_, err = protoutil.UInt64Marshal(netInfoMagicNumFNum, buf[offset:], i.magicNum)
n, err = protoutil.UInt64Marshal(netInfoMagicNumFNum, buf[offset:], i.magicNum)
if err != nil {
return nil, err
}
offset += n
n, err = protoutil.Int64Marshal(netInfoMSPerBlockFNum, buf[offset:], i.msPerBlock)
if err != nil {
return nil, err
}
offset += n
_, err = protoutil.NestedStructureMarshal(netInfoCfgFNum, buf[offset:], i.netCfg)
if err != nil {
return nil, err
}
@ -510,6 +615,8 @@ func (i *NetworkInfo) StableSize() (size int) {
size += protoutil.UInt64Size(netInfoCurEpochFNum, i.curEpoch)
size += protoutil.UInt64Size(netInfoMagicNumFNum, i.magicNum)
size += protoutil.Int64Size(netInfoMSPerBlockFNum, i.msPerBlock)
size += protoutil.NestedStructureSize(netInfoCfgFNum, i.netCfg)
return size
}

View file

@ -18,6 +18,8 @@ func TestMessageConvert(t *testing.T) {
func(empty bool) message.Message { return netmaptest.GenerateNodeInfo(empty) },
func(empty bool) message.Message { return netmaptest.GenerateLocalNodeInfoRequest(empty) },
func(empty bool) message.Message { return netmaptest.GenerateLocalNodeInfoResponseBody(empty) },
func(empty bool) message.Message { return netmaptest.GenerateNetworkParameter(empty) },
func(empty bool) message.Message { return netmaptest.GenerateNetworkConfig(empty) },
func(empty bool) message.Message { return netmaptest.GenerateNetworkInfo(empty) },
func(empty bool) message.Message { return netmaptest.GenerateNetworkInfoRequest(empty) },
func(empty bool) message.Message { return netmaptest.GenerateNetworkInfoResponseBody(empty) },

View file

@ -188,12 +188,38 @@ func GenerateLocalNodeInfoResponse(empty bool) *netmap.LocalNodeInfoResponse {
return m
}
func GenerateNetworkParameter(empty bool) *netmap.NetworkParameter {
m := new(netmap.NetworkParameter)
if !empty {
m.SetKey([]byte("key"))
m.SetValue([]byte("value"))
}
return m
}
func GenerateNetworkConfig(empty bool) *netmap.NetworkConfig {
m := new(netmap.NetworkConfig)
if !empty {
m.SetParameters(
GenerateNetworkParameter(empty),
GenerateNetworkParameter(empty),
)
}
return m
}
func GenerateNetworkInfo(empty bool) *netmap.NetworkInfo {
m := new(netmap.NetworkInfo)
if !empty {
m.SetMagicNumber(228)
m.SetCurrentEpoch(666)
m.SetMsPerBlock(5678)
m.SetNetworkConfig(GenerateNetworkConfig(empty))
}
return m

View file

@ -517,10 +517,86 @@ func (l *LocalNodeInfoResponse) SetBody(body *LocalNodeInfoResponseBody) {
}
}
// NetworkParameter represents NeoFS network parameter.
type NetworkParameter struct {
k, v []byte
}
// GetKey returns parameter key.
func (x *NetworkParameter) GetKey() []byte {
if x != nil {
return x.k
}
return nil
}
// SetKey sets parameter key.
func (x *NetworkParameter) SetKey(k []byte) {
if x != nil {
x.k = k
}
}
// GetValue returns parameter value.
func (x *NetworkParameter) GetValue() []byte {
if x != nil {
return x.v
}
return nil
}
// SetValue sets parameter value.
func (x *NetworkParameter) SetValue(v []byte) {
if x != nil {
x.v = v
}
}
// NetworkConfig represents NeoFS network configuration.
type NetworkConfig struct {
ps []*NetworkParameter
}
// NumberOfParameters returns number of network parameters.
func (x *NetworkConfig) NumberOfParameters() int {
if x != nil {
return len(x.ps)
}
return 0
}
// IterateParameters iterates over network parameters.
// Breaks iteration on f's true return.
//
// Handler must not be nil.
func (x *NetworkConfig) IterateParameters(f func(*NetworkParameter) bool) {
if x != nil {
for i := range x.ps {
if f(x.ps[i]) {
break
}
}
}
}
// SetParameters sets list of network parameters.
func (x *NetworkConfig) SetParameters(v ...*NetworkParameter) {
if x != nil {
x.ps = v
}
}
// NetworkInfo groups information about
// NeoFS network.
type NetworkInfo struct {
curEpoch, magicNum uint64
msPerBlock int64
netCfg *NetworkConfig
}
// GetCurrentEpoch returns number of the current epoch.
@ -555,6 +631,38 @@ func (i *NetworkInfo) SetMagicNumber(magic uint64) {
}
}
// GetMsPerBlock returns MillisecondsPerBlock network parameter.
func (i *NetworkInfo) GetMsPerBlock() int64 {
if i != nil {
return i.msPerBlock
}
return 0
}
// SetMsPerBlock sets MillisecondsPerBlock network parameter.
func (i *NetworkInfo) SetMsPerBlock(v int64) {
if i != nil {
i.msPerBlock = v
}
}
// GetNetworkConfig returns NeoFS network configuration.
func (i *NetworkInfo) GetNetworkConfig() *NetworkConfig {
if i != nil {
return i.netCfg
}
return nil
}
// SetNetworkConfig sets NeoFS network configuration.
func (i *NetworkInfo) SetNetworkConfig(v *NetworkConfig) {
if i != nil {
i.netCfg = v
}
}
// NetworkInfoRequestBody is a structure of NetworkInfo request body.
type NetworkInfoRequestBody struct{}