diff --git a/pkg/innerring/innerring.go b/pkg/innerring/innerring.go index 4289fafb..d7b91ec5 100644 --- a/pkg/innerring/innerring.go +++ b/pkg/innerring/innerring.go @@ -22,6 +22,7 @@ import ( "github.com/nspcc-dev/neofs-node/pkg/innerring/processors/netmap" nodevalidator "github.com/nspcc-dev/neofs-node/pkg/innerring/processors/netmap/nodevalidation" addrvalidator "github.com/nspcc-dev/neofs-node/pkg/innerring/processors/netmap/nodevalidation/maddress" + statevalidation "github.com/nspcc-dev/neofs-node/pkg/innerring/processors/netmap/nodevalidation/state" subnetvalidator "github.com/nspcc-dev/neofs-node/pkg/innerring/processors/netmap/nodevalidation/subnet" "github.com/nspcc-dev/neofs-node/pkg/innerring/processors/reputation" "github.com/nspcc-dev/neofs-node/pkg/innerring/processors/settlement" @@ -689,6 +690,8 @@ func New(ctx context.Context, log *zap.Logger, cfg *viper.Viper, errChan chan<- } } + var netMapCandidateStateValidator statevalidation.NetMapCandidateValidator + // create netmap processor server.netmapProcessor, err = netmap.New(&netmap.Params{ Log: log, @@ -711,6 +714,7 @@ func New(ctx context.Context, log *zap.Logger, cfg *viper.Viper, errChan chan<- ), AlphabetSyncHandler: alphaSync, NodeValidator: nodevalidator.New( + &netMapCandidateStateValidator, addrvalidator.New(), locodeValidator, subnetValidator, diff --git a/pkg/innerring/processors/netmap/nodevalidation/state/validator.go b/pkg/innerring/processors/netmap/nodevalidation/state/validator.go new file mode 100644 index 00000000..79093dde --- /dev/null +++ b/pkg/innerring/processors/netmap/nodevalidation/state/validator.go @@ -0,0 +1,41 @@ +/* +Package state collects functionality for verifying states of network map members. + +NetMapCandidateValidator type provides an interface for checking the network +map candidates. +*/ +package state + +import ( + "errors" + + "github.com/nspcc-dev/neofs-sdk-go/netmap" +) + +// NetMapCandidateValidator represents tool which checks state of nodes which +// are going to register in the NeoFS network (enter the network map). +// +// NetMapCandidateValidator can be instantiated using built-in var declaration +// and currently doesn't require any additional initialization. +// +// NetMapCandidateValidator implements +// github.com/nspcc-dev/neofs-node/pkg/innerring/processors/netmap.NodeValidator. +type NetMapCandidateValidator struct { +} + +// VerifyAndUpdate checks state of the network map candidate described by +// netmap.NodeInfo parameter. Returns no error if status is correct, otherwise +// returns an error describing a violation of the rules: +// +// status MUST be ONLINE +// +// VerifyAndUpdate does not mutate the parameter in a binary format. +// +// See also netmap.NodeInfo.IsOnline/SetOnline. +func (x *NetMapCandidateValidator) VerifyAndUpdate(node *netmap.NodeInfo) error { + if node.IsOnline() { + return nil + } + + return errors.New("invalid status: MUST be ONLINE") +} diff --git a/pkg/innerring/processors/netmap/nodevalidation/state/validator_test.go b/pkg/innerring/processors/netmap/nodevalidation/state/validator_test.go new file mode 100644 index 00000000..3d08a02d --- /dev/null +++ b/pkg/innerring/processors/netmap/nodevalidation/state/validator_test.go @@ -0,0 +1,54 @@ +package state_test + +import ( + "testing" + + "github.com/nspcc-dev/neofs-node/pkg/innerring/processors/netmap/nodevalidation/state" + "github.com/nspcc-dev/neofs-sdk-go/netmap" + "github.com/stretchr/testify/require" +) + +func TestValidator_VerifyAndUpdate(t *testing.T) { + var v state.NetMapCandidateValidator + + for _, testCase := range []struct { + name string + preparer func(*netmap.NodeInfo) // modifies zero instance + valid bool // is node valid after preparation + }{ + { + name: "UNDEFINED", + preparer: func(info *netmap.NodeInfo) {}, + valid: false, + }, + { + name: "ONLINE", + preparer: (*netmap.NodeInfo).SetOnline, + valid: true, + }, + { + name: "OFFLINE", + preparer: (*netmap.NodeInfo).SetOffline, + valid: false, + }, + } { + var node netmap.NodeInfo + + // prepare node + testCase.preparer(&node) + + // save binary representation for mutation check + binNode := node.Marshal() + + err := v.VerifyAndUpdate(&node) + + if testCase.valid { + require.NoError(t, err, testCase.name) + } else { + require.Error(t, err, testCase.name) + } + + // check mutation + require.Equal(t, binNode, node.Marshal(), testCase.name) + } +}