Initial commit

Initial public review release v0.10.0
This commit is contained in:
alexvanin 2020-07-10 17:17:51 +03:00 committed by Stanislav Bogatyrev
commit dadfd90dcd
276 changed files with 46331 additions and 0 deletions

17
lib/ir/info.go Normal file
View file

@ -0,0 +1,17 @@
package ir
// Info is a structure that groups the information
// about inner ring.
type Info struct {
nodes []Node
}
// SetNodes is an IR node list setter.
func (s *Info) SetNodes(v []Node) {
s.nodes = v
}
// Nodes is an IR node list getter.
func (s Info) Nodes() []Node {
return s.nodes
}

25
lib/ir/info_test.go Normal file
View file

@ -0,0 +1,25 @@
package ir
import (
"testing"
"github.com/stretchr/testify/require"
)
func TestInfo(t *testing.T) {
s := Info{}
n1 := Node{}
n1.SetKey([]byte{1, 2, 3})
n2 := Node{}
n2.SetKey([]byte{4, 5, 6})
nodes := []Node{
n1,
n2,
}
s.SetNodes(nodes)
require.Equal(t, nodes, s.Nodes())
}

17
lib/ir/node.go Normal file
View file

@ -0,0 +1,17 @@
package ir
// Node is a structure that groups
// the information about IR node.
type Node struct {
key []byte
}
// SetKey is an IR node public key setter.
func (s *Node) SetKey(v []byte) {
s.key = v
}
// Key is an IR node public key getter.
func (s Node) Key() []byte {
return s.key
}

16
lib/ir/node_test.go Normal file
View file

@ -0,0 +1,16 @@
package ir
import (
"testing"
"github.com/stretchr/testify/require"
)
func TestNode(t *testing.T) {
s := Node{}
key := []byte{1, 2, 3}
s.SetKey(key)
require.Equal(t, key, s.Key())
}

94
lib/ir/storage.go Normal file
View file

@ -0,0 +1,94 @@
package ir
import (
"bytes"
crypto "github.com/nspcc-dev/neofs-crypto"
"github.com/nspcc-dev/neofs-node/internal"
"github.com/pkg/errors"
)
// Storage is an interface of the storage of info about NeoFS IR.
type Storage interface {
GetIRInfo(GetInfoParams) (*GetInfoResult, error)
}
// GetInfoParams is a structure that groups the parameters
// for IR info receiving operation.
type GetInfoParams struct {
}
// GetInfoResult is a structure that groups
// values returned by IR info receiving operation.
type GetInfoResult struct {
info Info
}
// ErrNilStorage is returned by functions that expect
// a non-nil Storage, but received nil.
const ErrNilStorage = internal.Error("inner ring storage is nil")
// SetInfo is an IR info setter.
func (s *GetInfoResult) SetInfo(v Info) {
s.info = v
}
// Info is an IR info getter.
func (s GetInfoResult) Info() Info {
return s.info
}
// BinaryKeyList returns the list of binary public key of IR nodes.
//
// If passed Storage is nil, ErrNilStorage returns.
func BinaryKeyList(storage Storage) ([][]byte, error) {
if storage == nil {
return nil, ErrNilStorage
}
// get IR info
getRes, err := storage.GetIRInfo(GetInfoParams{})
if err != nil {
return nil, errors.Wrap(
err,
"could not get information about IR",
)
}
nodes := getRes.Info().Nodes()
keys := make([][]byte, 0, len(nodes))
for i := range nodes {
keys = append(keys, nodes[i].Key())
}
return keys, nil
}
// IsInnerRingKey checks if the passed argument is the
// key of one of IR nodes.
//
// Uses BinaryKeyList function to receive the key list of IR nodes internally.
//
// If passed key slice is empty, crypto.ErrEmptyPublicKey returns immediately.
func IsInnerRingKey(storage Storage, key []byte) (bool, error) {
// check key emptiness
// TODO: summarize the void check to a full IR key-format check.
if len(key) == 0 {
return false, crypto.ErrEmptyPublicKey
}
irKeys, err := BinaryKeyList(storage)
if err != nil {
return false, err
}
for i := range irKeys {
if bytes.Equal(irKeys[i], key) {
return true, nil
}
}
return false, nil
}

101
lib/ir/storage_test.go Normal file
View file

@ -0,0 +1,101 @@
package ir
import (
"testing"
crypto "github.com/nspcc-dev/neofs-crypto"
"github.com/pkg/errors"
"github.com/stretchr/testify/require"
)
type testInfoReceiver struct {
keys [][]byte
err error
}
func (s testInfoReceiver) GetIRInfo(GetInfoParams) (*GetInfoResult, error) {
if s.err != nil {
return nil, s.err
}
nodes := make([]Node, 0, len(s.keys))
for i := range s.keys {
node := Node{}
node.SetKey(s.keys[i])
nodes = append(nodes, node)
}
info := Info{}
info.SetNodes(nodes)
res := new(GetInfoResult)
res.SetInfo(info)
return res, nil
}
func (s *testInfoReceiver) addKey(key []byte) {
s.keys = append(s.keys, key)
}
func TestGetInfoResult(t *testing.T) {
s := GetInfoResult{}
info := Info{}
n := Node{}
n.SetKey([]byte{1, 2, 3})
info.SetNodes([]Node{
n,
})
s.SetInfo(info)
require.Equal(t, info, s.Info())
}
func TestIsInnerRingKey(t *testing.T) {
var (
res bool
err error
s = new(testInfoReceiver)
)
// empty public key
res, err = IsInnerRingKey(nil, nil)
require.EqualError(t, err, crypto.ErrEmptyPublicKey.Error())
key := []byte{1, 2, 3}
// nil Storage
res, err = IsInnerRingKey(nil, key)
require.EqualError(t, err, ErrNilStorage.Error())
// force Storage to return an error
s.err = errors.New("some error")
// Storage error
res, err = IsInnerRingKey(s, key)
require.EqualError(t, errors.Cause(err), s.err.Error())
// reset Storage error
s.err = nil
// IR keys don't contain key
s.addKey(append(key, 1))
res, err = IsInnerRingKey(s, key)
require.NoError(t, err)
require.False(t, res)
// IR keys contain key
s.addKey(key)
res, err = IsInnerRingKey(s, key)
require.NoError(t, err)
require.True(t, res)
}