2021-11-08 08:41:39 +00:00
|
|
|
package reputation
|
|
|
|
|
|
|
|
import (
|
|
|
|
"crypto/ecdsa"
|
2022-04-05 11:13:34 +00:00
|
|
|
"errors"
|
|
|
|
"fmt"
|
2021-11-08 08:41:39 +00:00
|
|
|
|
|
|
|
"github.com/nspcc-dev/neofs-api-go/v2/refs"
|
|
|
|
"github.com/nspcc-dev/neofs-api-go/v2/reputation"
|
2022-04-05 11:13:34 +00:00
|
|
|
neofscrypto "github.com/nspcc-dev/neofs-sdk-go/crypto"
|
|
|
|
neofsecdsa "github.com/nspcc-dev/neofs-sdk-go/crypto/ecdsa"
|
2021-11-08 08:41:39 +00:00
|
|
|
"github.com/nspcc-dev/neofs-sdk-go/version"
|
|
|
|
)
|
|
|
|
|
|
|
|
// Trust represents peer's trust compatible with NeoFS API v2.
|
|
|
|
type Trust reputation.Trust
|
|
|
|
|
|
|
|
// NewTrust creates and returns blank Trust.
|
|
|
|
//
|
|
|
|
// Defaults:
|
|
|
|
// - value: 0;
|
|
|
|
// - PeerID: nil.
|
|
|
|
func NewTrust() *Trust {
|
|
|
|
return TrustFromV2(new(reputation.Trust))
|
|
|
|
}
|
|
|
|
|
|
|
|
// TrustFromV2 converts NeoFS API v2
|
|
|
|
// reputation.Trust message structure to Trust.
|
|
|
|
//
|
|
|
|
// Nil reputation.Trust converts to nil.
|
|
|
|
func TrustFromV2(t *reputation.Trust) *Trust {
|
|
|
|
return (*Trust)(t)
|
|
|
|
}
|
|
|
|
|
|
|
|
// ToV2 converts Trust to NeoFS API v2
|
|
|
|
// reputation.Trust message structure.
|
|
|
|
//
|
|
|
|
// Nil Trust converts to nil.
|
|
|
|
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.
|
2022-03-11 08:56:54 +00:00
|
|
|
func TrustsToV2(xs []Trust) (res []reputation.Trust) {
|
2021-11-08 08:41:39 +00:00
|
|
|
if xs != nil {
|
2022-03-11 08:56:54 +00:00
|
|
|
res = make([]reputation.Trust, len(xs))
|
2021-11-08 08:41:39 +00:00
|
|
|
|
|
|
|
for i := range xs {
|
2022-03-11 08:56:54 +00:00
|
|
|
res[i] = *xs[i].ToV2()
|
2021-11-08 08:41:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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.
|
|
|
|
func (x *Trust) Marshal() ([]byte, error) {
|
|
|
|
return (*reputation.Trust)(x).StableMarshal(nil)
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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)
|
|
|
|
}
|
|
|
|
|
|
|
|
// PeerToPeerTrust represents directed peer-to-peer trust
|
|
|
|
// compatible with NeoFS API v2.
|
|
|
|
type PeerToPeerTrust reputation.PeerToPeerTrust
|
|
|
|
|
|
|
|
// NewPeerToPeerTrust creates and returns blank PeerToPeerTrust.
|
|
|
|
//
|
|
|
|
// Defaults:
|
|
|
|
// - trusting: nil;
|
|
|
|
// - trust: nil.
|
|
|
|
func NewPeerToPeerTrust() *PeerToPeerTrust {
|
|
|
|
return PeerToPeerTrustFromV2(new(reputation.PeerToPeerTrust))
|
|
|
|
}
|
|
|
|
|
|
|
|
// PeerToPeerTrustFromV2 converts NeoFS API v2
|
|
|
|
// reputation.PeerToPeerTrust message structure to PeerToPeerTrust.
|
|
|
|
//
|
|
|
|
// Nil reputation.PeerToPeerTrust converts to nil.
|
|
|
|
func PeerToPeerTrustFromV2(t *reputation.PeerToPeerTrust) *PeerToPeerTrust {
|
|
|
|
return (*PeerToPeerTrust)(t)
|
|
|
|
}
|
|
|
|
|
|
|
|
// ToV2 converts PeerToPeerTrust to NeoFS API v2
|
|
|
|
// reputation.PeerToPeerTrust message structure.
|
|
|
|
//
|
|
|
|
// Nil PeerToPeerTrust converts to nil.
|
|
|
|
func (x *PeerToPeerTrust) ToV2() *reputation.PeerToPeerTrust {
|
|
|
|
return (*reputation.PeerToPeerTrust)(x)
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetTrustingPeer sets trusting peer ID.
|
|
|
|
func (x *PeerToPeerTrust) SetTrustingPeer(id *PeerID) {
|
|
|
|
(*reputation.PeerToPeerTrust)(x).SetTrustingPeer(id.ToV2())
|
|
|
|
}
|
|
|
|
|
|
|
|
// TrustingPeer returns trusting peer ID.
|
|
|
|
func (x *PeerToPeerTrust) TrustingPeer() *PeerID {
|
|
|
|
return PeerIDFromV2(
|
|
|
|
(*reputation.PeerToPeerTrust)(x).
|
|
|
|
GetTrustingPeer(),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetTrust sets trust value of the trusting peer to the trusted one.
|
|
|
|
func (x *PeerToPeerTrust) SetTrust(t *Trust) {
|
|
|
|
(*reputation.PeerToPeerTrust)(x).SetTrust(t.ToV2())
|
|
|
|
}
|
|
|
|
|
|
|
|
// Trust returns trust value of the trusting peer to the trusted one.
|
|
|
|
func (x *PeerToPeerTrust) Trust() *Trust {
|
|
|
|
return TrustFromV2(
|
|
|
|
(*reputation.PeerToPeerTrust)(x).GetTrust())
|
|
|
|
}
|
|
|
|
|
|
|
|
// Marshal marshals PeerToPeerTrust into a protobuf binary form.
|
|
|
|
func (x *PeerToPeerTrust) Marshal() ([]byte, error) {
|
|
|
|
return (*reputation.PeerToPeerTrust)(x).StableMarshal(nil)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Unmarshal unmarshals protobuf binary representation of PeerToPeerTrust.
|
|
|
|
func (x *PeerToPeerTrust) Unmarshal(data []byte) error {
|
|
|
|
return (*reputation.PeerToPeerTrust)(x).Unmarshal(data)
|
|
|
|
}
|
|
|
|
|
|
|
|
// MarshalJSON encodes PeerToPeerTrust to protobuf JSON format.
|
|
|
|
func (x *PeerToPeerTrust) MarshalJSON() ([]byte, error) {
|
|
|
|
return (*reputation.PeerToPeerTrust)(x).MarshalJSON()
|
|
|
|
}
|
|
|
|
|
|
|
|
// UnmarshalJSON decodes PeerToPeerTrust from protobuf JSON format.
|
|
|
|
func (x *PeerToPeerTrust) UnmarshalJSON(data []byte) error {
|
|
|
|
return (*reputation.PeerToPeerTrust)(x).UnmarshalJSON(data)
|
|
|
|
}
|
|
|
|
|
|
|
|
// GlobalTrust represents peer's global trust compatible with NeoFS API v2.
|
|
|
|
type GlobalTrust reputation.GlobalTrust
|
|
|
|
|
|
|
|
// NewGlobalTrust creates and returns blank GlobalTrust.
|
|
|
|
//
|
|
|
|
// Defaults:
|
|
|
|
// - version: version.Current();
|
|
|
|
// - manager: nil;
|
|
|
|
// - trust: nil.
|
|
|
|
func NewGlobalTrust() *GlobalTrust {
|
|
|
|
gt := GlobalTrustFromV2(new(reputation.GlobalTrust))
|
2022-03-23 15:35:44 +00:00
|
|
|
ver := version.Current()
|
|
|
|
gt.SetVersion(&ver)
|
2021-11-08 08:41:39 +00:00
|
|
|
|
|
|
|
return gt
|
|
|
|
}
|
|
|
|
|
|
|
|
// GlobalTrustFromV2 converts NeoFS API v2
|
|
|
|
// reputation.GlobalTrust message structure to GlobalTrust.
|
|
|
|
//
|
|
|
|
// Nil reputation.GlobalTrust converts to nil.
|
|
|
|
func GlobalTrustFromV2(t *reputation.GlobalTrust) *GlobalTrust {
|
|
|
|
return (*GlobalTrust)(t)
|
|
|
|
}
|
|
|
|
|
|
|
|
// ToV2 converts GlobalTrust to NeoFS API v2
|
|
|
|
// reputation.GlobalTrust message structure.
|
|
|
|
//
|
|
|
|
// Nil GlobalTrust converts to nil.
|
|
|
|
func (x *GlobalTrust) ToV2() *reputation.GlobalTrust {
|
|
|
|
return (*reputation.GlobalTrust)(x)
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetVersion sets GlobalTrust's protocol version.
|
|
|
|
func (x *GlobalTrust) SetVersion(version *version.Version) {
|
2022-03-23 15:35:44 +00:00
|
|
|
var verV2 refs.Version
|
|
|
|
version.WriteToV2(&verV2)
|
|
|
|
(*reputation.GlobalTrust)(x).SetVersion(&verV2)
|
2021-11-08 08:41:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Version returns GlobalTrust's protocol version.
|
|
|
|
func (x *GlobalTrust) Version() *version.Version {
|
2022-03-23 15:35:44 +00:00
|
|
|
var ver version.Version
|
|
|
|
if verV2 := (*reputation.GlobalTrust)(x).GetVersion(); verV2 != nil {
|
|
|
|
ver.ReadFromV2(*verV2)
|
|
|
|
}
|
|
|
|
return &ver
|
2021-11-08 08:41:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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 {
|
2022-04-05 11:13:34 +00:00
|
|
|
if key == nil {
|
|
|
|
return errors.New("nil private key")
|
|
|
|
}
|
|
|
|
|
|
|
|
m := (*reputation.GlobalTrust)(x)
|
2021-11-08 08:41:39 +00:00
|
|
|
|
2022-04-05 11:13:34 +00:00
|
|
|
data, err := m.GetBody().StableMarshal(nil)
|
2022-02-24 11:45:52 +00:00
|
|
|
if err != nil {
|
2022-04-05 11:13:34 +00:00
|
|
|
return fmt.Errorf("marshal body: %w", err)
|
2022-02-24 11:45:52 +00:00
|
|
|
}
|
|
|
|
|
2022-04-05 11:13:34 +00:00
|
|
|
var sig neofscrypto.Signature
|
|
|
|
var signer neofsecdsa.Signer
|
|
|
|
|
|
|
|
signer.SetKey(*key)
|
|
|
|
|
|
|
|
err = sig.Calculate(signer, data)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("calculate signature: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
var sigv2 refs.Signature
|
|
|
|
|
|
|
|
sig.WriteToV2(&sigv2)
|
|
|
|
|
|
|
|
m.SetSignature(&sigv2)
|
|
|
|
|
2022-02-24 11:45:52 +00:00
|
|
|
return nil
|
2021-11-08 08:41:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// VerifySignature verifies global trust signature.
|
|
|
|
func (x *GlobalTrust) VerifySignature() error {
|
2022-04-05 11:13:34 +00:00
|
|
|
m := (*reputation.GlobalTrust)(x)
|
2021-11-08 08:41:39 +00:00
|
|
|
|
2022-04-05 11:13:34 +00:00
|
|
|
sigV2 := m.GetSignature()
|
2021-11-08 08:41:39 +00:00
|
|
|
if sigV2 == nil {
|
2022-04-05 11:13:34 +00:00
|
|
|
return errors.New("missing signature")
|
2021-11-08 08:41:39 +00:00
|
|
|
}
|
|
|
|
|
2022-04-05 11:13:34 +00:00
|
|
|
data, err := m.GetBody().StableMarshal(nil)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("marshal body: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
var sig neofscrypto.Signature
|
|
|
|
sig.ReadFromV2(*sigV2)
|
|
|
|
|
|
|
|
if !sig.Verify(data) {
|
|
|
|
return errors.New("wrong signature")
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
2021-11-08 08:41:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Marshal marshals GlobalTrust into a protobuf binary form.
|
|
|
|
func (x *GlobalTrust) Marshal() ([]byte, error) {
|
|
|
|
return (*reputation.GlobalTrust)(x).StableMarshal(nil)
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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)
|
|
|
|
}
|