forked from TrueCloudLab/frostfs-api-go
[#265] pkg/reputation: Implement GlobalTrust type
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
This commit is contained in:
parent
05a351d344
commit
771f395d9d
3 changed files with 242 additions and 0 deletions
|
@ -1,9 +1,12 @@
|
||||||
package reputationtest
|
package reputationtest
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/pkg/reputation"
|
"github.com/nspcc-dev/neofs-api-go/pkg/reputation"
|
||||||
crypto "github.com/nspcc-dev/neofs-crypto"
|
crypto "github.com/nspcc-dev/neofs-crypto"
|
||||||
"github.com/nspcc-dev/neofs-crypto/test"
|
"github.com/nspcc-dev/neofs-crypto/test"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func GeneratePeerID() *reputation.PeerID {
|
func GeneratePeerID() *reputation.PeerID {
|
||||||
|
@ -24,3 +27,19 @@ func GenerateTrust() *reputation.Trust {
|
||||||
|
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GenerateGlobalTrust() *reputation.GlobalTrust {
|
||||||
|
v := reputation.NewGlobalTrust()
|
||||||
|
v.SetManager(GeneratePeerID())
|
||||||
|
v.SetTrust(GenerateTrust())
|
||||||
|
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
func GenerateSignedGlobalTrust(t testing.TB) *reputation.GlobalTrust {
|
||||||
|
gt := GenerateGlobalTrust()
|
||||||
|
|
||||||
|
require.NoError(t, gt.Sign(test.DecodeKey(0)))
|
||||||
|
|
||||||
|
return gt
|
||||||
|
}
|
||||||
|
|
|
@ -1,7 +1,13 @@
|
||||||
package reputation
|
package reputation
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/ecdsa"
|
||||||
|
|
||||||
|
"github.com/nspcc-dev/neofs-api-go/pkg"
|
||||||
|
"github.com/nspcc-dev/neofs-api-go/util/signature"
|
||||||
|
"github.com/nspcc-dev/neofs-api-go/v2/refs"
|
||||||
"github.com/nspcc-dev/neofs-api-go/v2/reputation"
|
"github.com/nspcc-dev/neofs-api-go/v2/reputation"
|
||||||
|
signatureV2 "github.com/nspcc-dev/neofs-api-go/v2/signature"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Trust represents peer's trust compatible with NeoFS API v2.
|
// Trust represents peer's trust compatible with NeoFS API v2.
|
||||||
|
@ -93,3 +99,156 @@ func (x *Trust) UnmarshalJSON(data []byte) error {
|
||||||
return (*reputation.Trust)(x).
|
return (*reputation.Trust)(x).
|
||||||
UnmarshalJSON(data)
|
UnmarshalJSON(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GlobalTrust represents peer's global trust compatible with NeoFS API v2.
|
||||||
|
type GlobalTrust reputation.GlobalTrust
|
||||||
|
|
||||||
|
// NewGlobalTrust creates and returns blank GlobalTrust.
|
||||||
|
//
|
||||||
|
// Version is initialized to current library version.
|
||||||
|
func NewGlobalTrust() *GlobalTrust {
|
||||||
|
gt := GlobalTrustFromV2(new(reputation.GlobalTrust))
|
||||||
|
gt.SetVersion(pkg.SDKVersion())
|
||||||
|
|
||||||
|
return gt
|
||||||
|
}
|
||||||
|
|
||||||
|
// GlobalTrustFromV2 converts NeoFS API v2
|
||||||
|
// reputation.GlobalTrust message structure to GlobalTrust.
|
||||||
|
func GlobalTrustFromV2(t *reputation.GlobalTrust) *GlobalTrust {
|
||||||
|
return (*GlobalTrust)(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToV2 converts GlobalTrust to NeoFS API v2
|
||||||
|
// reputation.GlobalTrust message structure.
|
||||||
|
func (x *GlobalTrust) ToV2() *reputation.GlobalTrust {
|
||||||
|
return (*reputation.GlobalTrust)(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetVersion sets GlobalTrust's protocol version.
|
||||||
|
func (x *GlobalTrust) SetVersion(version *pkg.Version) {
|
||||||
|
(*reputation.GlobalTrust)(x).
|
||||||
|
SetVersion(version.ToV2())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Version returns GlobalTrust's protocol version.
|
||||||
|
func (x *GlobalTrust) Version() *pkg.Version {
|
||||||
|
return pkg.NewVersionFromV2(
|
||||||
|
(*reputation.GlobalTrust)(x).
|
||||||
|
GetVersion(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *GlobalTrust) setBodyField(setter func(*reputation.GlobalTrustBody)) {
|
||||||
|
if x != nil {
|
||||||
|
v2 := (*reputation.GlobalTrust)(x)
|
||||||
|
|
||||||
|
body := v2.GetBody()
|
||||||
|
if body == nil {
|
||||||
|
body = new(reputation.GlobalTrustBody)
|
||||||
|
v2.SetBody(body)
|
||||||
|
}
|
||||||
|
|
||||||
|
setter(body)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetManager sets node manager ID.
|
||||||
|
func (x *GlobalTrust) SetManager(id *PeerID) {
|
||||||
|
x.setBodyField(func(body *reputation.GlobalTrustBody) {
|
||||||
|
body.SetManager(id.ToV2())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Manager returns node manager ID.
|
||||||
|
func (x *GlobalTrust) Manager() *PeerID {
|
||||||
|
return PeerIDFromV2(
|
||||||
|
(*reputation.GlobalTrust)(x).
|
||||||
|
GetBody().
|
||||||
|
GetManager(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetTrust sets global trust value.
|
||||||
|
func (x *GlobalTrust) SetTrust(trust *Trust) {
|
||||||
|
x.setBodyField(func(body *reputation.GlobalTrustBody) {
|
||||||
|
body.SetTrust(trust.ToV2())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trust returns global trust value.
|
||||||
|
func (x *GlobalTrust) Trust() *Trust {
|
||||||
|
return TrustFromV2(
|
||||||
|
(*reputation.GlobalTrust)(x).
|
||||||
|
GetBody().
|
||||||
|
GetTrust(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sign signs global trust value with key.
|
||||||
|
func (x *GlobalTrust) Sign(key *ecdsa.PrivateKey) error {
|
||||||
|
v2 := (*reputation.GlobalTrust)(x)
|
||||||
|
|
||||||
|
sigV2 := v2.GetSignature()
|
||||||
|
if sigV2 == nil {
|
||||||
|
sigV2 = new(refs.Signature)
|
||||||
|
v2.SetSignature(sigV2)
|
||||||
|
}
|
||||||
|
|
||||||
|
return signature.SignDataWithHandler(
|
||||||
|
key,
|
||||||
|
signatureV2.StableMarshalerWrapper{SM: v2.GetBody()},
|
||||||
|
func(key, sig []byte) {
|
||||||
|
sigV2.SetKey(key)
|
||||||
|
sigV2.SetSign(sig)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// VerifySignature verifies global trust signature.
|
||||||
|
func (x *GlobalTrust) VerifySignature() error {
|
||||||
|
v2 := (*reputation.GlobalTrust)(x)
|
||||||
|
|
||||||
|
sigV2 := v2.GetSignature()
|
||||||
|
if sigV2 == nil {
|
||||||
|
sigV2 = new(refs.Signature)
|
||||||
|
}
|
||||||
|
|
||||||
|
return signature.VerifyDataWithSource(
|
||||||
|
signatureV2.StableMarshalerWrapper{SM: v2.GetBody()},
|
||||||
|
func() ([]byte, []byte) {
|
||||||
|
return sigV2.GetKey(), sigV2.GetSign()
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Marshal marshals GlobalTrust into a protobuf binary form.
|
||||||
|
//
|
||||||
|
// Buffer is allocated when the argument is empty.
|
||||||
|
// Otherwise, the first buffer is used.
|
||||||
|
func (x *GlobalTrust) Marshal(b ...[]byte) ([]byte, error) {
|
||||||
|
var buf []byte
|
||||||
|
if len(b) > 0 {
|
||||||
|
buf = b[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
return (*reputation.GlobalTrust)(x).StableMarshal(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unmarshal unmarshals protobuf binary representation of GlobalTrust.
|
||||||
|
func (x *GlobalTrust) Unmarshal(data []byte) error {
|
||||||
|
return (*reputation.GlobalTrust)(x).
|
||||||
|
Unmarshal(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSON encodes GlobalTrust to protobuf JSON format.
|
||||||
|
func (x *GlobalTrust) MarshalJSON() ([]byte, error) {
|
||||||
|
return (*reputation.GlobalTrust)(x).
|
||||||
|
MarshalJSON()
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON decodes GlobalTrust from protobuf JSON format.
|
||||||
|
func (x *GlobalTrust) UnmarshalJSON(data []byte) error {
|
||||||
|
return (*reputation.GlobalTrust)(x).
|
||||||
|
UnmarshalJSON(data)
|
||||||
|
}
|
||||||
|
|
|
@ -3,8 +3,10 @@ package reputation_test
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/nspcc-dev/neofs-api-go/pkg"
|
||||||
"github.com/nspcc-dev/neofs-api-go/pkg/reputation"
|
"github.com/nspcc-dev/neofs-api-go/pkg/reputation"
|
||||||
reputationtest "github.com/nspcc-dev/neofs-api-go/pkg/reputation/test"
|
reputationtest "github.com/nspcc-dev/neofs-api-go/pkg/reputation/test"
|
||||||
|
reputationtestV2 "github.com/nspcc-dev/neofs-api-go/v2/reputation/test"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -39,3 +41,65 @@ func TestTrust(t *testing.T) {
|
||||||
require.Equal(t, trust, trust2)
|
require.Equal(t, trust, trust2)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGlobalTrust(t *testing.T) {
|
||||||
|
t.Run("v2", func(t *testing.T) {
|
||||||
|
gtV2 := reputationtestV2.GenerateGlobalTrust(false)
|
||||||
|
|
||||||
|
gt := reputation.GlobalTrustFromV2(gtV2)
|
||||||
|
|
||||||
|
require.Equal(t, gtV2, gt.ToV2())
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("getters+setters", func(t *testing.T) {
|
||||||
|
gt := reputation.NewGlobalTrust()
|
||||||
|
|
||||||
|
require.Equal(t, pkg.SDKVersion(), gt.Version())
|
||||||
|
require.Nil(t, gt.Manager())
|
||||||
|
require.Nil(t, gt.Trust())
|
||||||
|
|
||||||
|
version := pkg.NewVersion()
|
||||||
|
version.SetMajor(13)
|
||||||
|
version.SetMinor(31)
|
||||||
|
gt.SetVersion(version)
|
||||||
|
require.Equal(t, version, gt.Version())
|
||||||
|
|
||||||
|
mngr := reputationtest.GeneratePeerID()
|
||||||
|
gt.SetManager(mngr)
|
||||||
|
require.Equal(t, mngr, gt.Manager())
|
||||||
|
|
||||||
|
trust := reputationtest.GenerateTrust()
|
||||||
|
gt.SetTrust(trust)
|
||||||
|
require.Equal(t, trust, gt.Trust())
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("sign+verify", func(t *testing.T) {
|
||||||
|
gt := reputationtest.GenerateSignedGlobalTrust(t)
|
||||||
|
|
||||||
|
err := gt.VerifySignature()
|
||||||
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("encoding", func(t *testing.T) {
|
||||||
|
t.Run("binary", func(t *testing.T) {
|
||||||
|
gt := reputationtest.GenerateSignedGlobalTrust(t)
|
||||||
|
|
||||||
|
data, err := gt.Marshal()
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
gt2 := reputation.NewGlobalTrust()
|
||||||
|
require.NoError(t, gt2.Unmarshal(data))
|
||||||
|
require.Equal(t, gt, gt2)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("JSON", func(t *testing.T) {
|
||||||
|
gt := reputationtest.GenerateSignedGlobalTrust(t)
|
||||||
|
data, err := gt.MarshalJSON()
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
gt2 := reputation.NewGlobalTrust()
|
||||||
|
require.NoError(t, gt2.UnmarshalJSON(data))
|
||||||
|
require.Equal(t, gt, gt2)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue