From 009f704377acf7b042849554bff197c4869d797a Mon Sep 17 00:00:00 2001 From: Leonard Lyubich Date: Wed, 24 Mar 2021 11:27:30 +0300 Subject: [PATCH] [#265] pkg/reputation: Implement PeerID and Trust types Signed-off-by: Leonard Lyubich --- pkg/reputation/peer.go | 29 ++++++++++ pkg/reputation/peer_test.go | 18 +++++++ pkg/reputation/test/generate.go | 22 ++++++++ pkg/reputation/trust.go | 95 +++++++++++++++++++++++++++++++++ pkg/reputation/trust_test.go | 41 ++++++++++++++ 5 files changed, 205 insertions(+) create mode 100644 pkg/reputation/peer.go create mode 100644 pkg/reputation/peer_test.go create mode 100644 pkg/reputation/test/generate.go create mode 100644 pkg/reputation/trust.go create mode 100644 pkg/reputation/trust_test.go diff --git a/pkg/reputation/peer.go b/pkg/reputation/peer.go new file mode 100644 index 00000000..ef1a314f --- /dev/null +++ b/pkg/reputation/peer.go @@ -0,0 +1,29 @@ +package reputation + +// PeerID represents peer ID compatible with NeoFS API v2. +type PeerID []byte + +// NewPeerID creates and returns blank PeerID. +func NewPeerID() *PeerID { + return PeerIDFromV2(nil) +} + +// PeerIDFromV2 converts bytes slice to PeerID. +func PeerIDFromV2(data []byte) *PeerID { + return (*PeerID)(&data) +} + +// SetBytes sets bytes of peer ID. +func (x *PeerID) SetBytes(v []byte) { + *x = v +} + +// Bytes returns bytes of peer ID. +func (x PeerID) Bytes() []byte { + return x +} + +// ToV2 converts PeerID to byte slice. +func (x PeerID) ToV2() []byte { + return x +} diff --git a/pkg/reputation/peer_test.go b/pkg/reputation/peer_test.go new file mode 100644 index 00000000..79c0da74 --- /dev/null +++ b/pkg/reputation/peer_test.go @@ -0,0 +1,18 @@ +package reputation_test + +import ( + "testing" + + "github.com/nspcc-dev/neofs-api-go/pkg/reputation" + "github.com/stretchr/testify/require" +) + +func TestPeerID(t *testing.T) { + peerID := reputation.NewPeerID() + + data := []byte{1, 2, 3} + peerID.SetBytes(data) + require.Equal(t, data, peerID.Bytes()) + + require.Equal(t, peerID, reputation.PeerIDFromV2(peerID.ToV2())) +} diff --git a/pkg/reputation/test/generate.go b/pkg/reputation/test/generate.go new file mode 100644 index 00000000..7d02c8b9 --- /dev/null +++ b/pkg/reputation/test/generate.go @@ -0,0 +1,22 @@ +package reputationtest + +import ( + "github.com/nspcc-dev/neofs-api-go/pkg/reputation" + crypto "github.com/nspcc-dev/neofs-crypto" + "github.com/nspcc-dev/neofs-crypto/test" +) + +func GeneratePeerID() *reputation.PeerID { + v := reputation.NewPeerID() + v.SetBytes(crypto.MarshalPublicKey(&test.DecodeKey(-1).PublicKey)) + + return v +} + +func GenerateTrust() *reputation.Trust { + v := reputation.NewTrust() + v.SetPeer(GeneratePeerID()) + v.SetValue(1.5) + + return v +} diff --git a/pkg/reputation/trust.go b/pkg/reputation/trust.go new file mode 100644 index 00000000..bfa5126e --- /dev/null +++ b/pkg/reputation/trust.go @@ -0,0 +1,95 @@ +package reputation + +import ( + "github.com/nspcc-dev/neofs-api-go/v2/reputation" +) + +// Trust represents peer's trust compatible with NeoFS API v2. +type Trust reputation.Trust + +// NewTrust creates and returns blank Trust. +func NewTrust() *Trust { + return TrustFromV2(new(reputation.Trust)) +} + +// TrustFromV2 converts NeoFS API v2 +// reputation.Trust message structure to Trust. +func TrustFromV2(t *reputation.Trust) *Trust { + return (*Trust)(t) +} + +// ToV2 converts Trust to NeoFS API v2 +// reputation.Trust message structure. +func (x *Trust) ToV2() *reputation.Trust { + return (*reputation.Trust)(x) +} + +// TrustsToV2 converts slice of Trust's to slice of +// NeoFS API v2 reputation.Trust message structures. +func TrustsToV2(xs []*Trust) (res []*reputation.Trust) { + if xs != nil { + res = make([]*reputation.Trust, 0, len(xs)) + + for i := range xs { + res = append(res, xs[i].ToV2()) + } + } + + return +} + +// SetPeer sets trusted peer ID. +func (x *Trust) SetPeer(id *PeerID) { + (*reputation.Trust)(x). + SetPeer(id.ToV2()) +} + +// Peer returns trusted peer ID. +func (x *Trust) Peer() *PeerID { + return PeerIDFromV2( + (*reputation.Trust)(x).GetPeer(), + ) +} + +// SetValue sets trust value. +func (x *Trust) SetValue(val float64) { + (*reputation.Trust)(x). + SetValue(val) +} + +// Value returns trust value. +func (x *Trust) Value() float64 { + return (*reputation.Trust)(x). + GetValue() +} + +// Marshal marshals Trust into a protobuf binary form. +// +// Buffer is allocated when the argument is empty. +// Otherwise, the first buffer is used. +func (x *Trust) Marshal(b ...[]byte) ([]byte, error) { + var buf []byte + if len(b) > 0 { + buf = b[0] + } + + return (*reputation.Trust)(x).StableMarshal(buf) +} + +// Unmarshal unmarshals protobuf binary representation of Trust. +func (x *Trust) Unmarshal(data []byte) error { + return (*reputation.Trust)(x). + Unmarshal(data) +} + +// MarshalJSON encodes Trust to protobuf JSON format. +func (x *Trust) MarshalJSON() ([]byte, error) { + return (*reputation.Trust)(x). + MarshalJSON() +} + +// UnmarshalJSON decodes Trust from protobuf JSON format. +func (x *Trust) UnmarshalJSON(data []byte) error { + return (*reputation.Trust)(x). + UnmarshalJSON(data) +} diff --git a/pkg/reputation/trust_test.go b/pkg/reputation/trust_test.go new file mode 100644 index 00000000..5a36c01c --- /dev/null +++ b/pkg/reputation/trust_test.go @@ -0,0 +1,41 @@ +package reputation_test + +import ( + "testing" + + "github.com/nspcc-dev/neofs-api-go/pkg/reputation" + reputationtest "github.com/nspcc-dev/neofs-api-go/pkg/reputation/test" + "github.com/stretchr/testify/require" +) + +func TestTrust(t *testing.T) { + trust := reputation.NewTrust() + + id := reputationtest.GeneratePeerID() + trust.SetPeer(id) + require.Equal(t, id, trust.Peer()) + + val := 1.5 + trust.SetValue(val) + require.Equal(t, val, trust.Value()) + + t.Run("binary encoding", func(t *testing.T) { + trust := reputationtest.GenerateTrust() + data, err := trust.Marshal() + require.NoError(t, err) + + trust2 := reputation.NewTrust() + require.NoError(t, trust2.Unmarshal(data)) + require.Equal(t, trust, trust2) + }) + + t.Run("JSON encoding", func(t *testing.T) { + trust := reputationtest.GenerateTrust() + data, err := trust.MarshalJSON() + require.NoError(t, err) + + trust2 := reputation.NewTrust() + require.NoError(t, trust2.UnmarshalJSON(data)) + require.Equal(t, trust, trust2) + }) +}