forked from TrueCloudLab/frostfs-sdk-go
[#56] *: Drop reputation system
Signed-off-by: Pavel Karpy <p.karpy@yadro.com>
This commit is contained in:
parent
c8e620ad24
commit
5c6228434d
11 changed files with 0 additions and 1146 deletions
|
@ -82,9 +82,6 @@ var (
|
||||||
errorMissingAnnouncements = errors.New("missing announcements")
|
errorMissingAnnouncements = errors.New("missing announcements")
|
||||||
errorZeroRangeLength = errors.New("zero range length")
|
errorZeroRangeLength = errors.New("zero range length")
|
||||||
errorMissingRanges = errors.New("missing ranges")
|
errorMissingRanges = errors.New("missing ranges")
|
||||||
errorZeroEpoch = errors.New("zero epoch")
|
|
||||||
errorMissingTrusts = errors.New("missing trusts")
|
|
||||||
errorTrustNotSet = errors.New("current trust value not set")
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// groups all the details required to send a single request and process a response to it.
|
// groups all the details required to send a single request and process a response to it.
|
||||||
|
|
|
@ -1,196 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
v2reputation "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/reputation"
|
|
||||||
rpcapi "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc"
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/reputation"
|
|
||||||
)
|
|
||||||
|
|
||||||
// PrmAnnounceLocalTrust groups parameters of AnnounceLocalTrust operation.
|
|
||||||
type PrmAnnounceLocalTrust struct {
|
|
||||||
prmCommonMeta
|
|
||||||
|
|
||||||
epoch uint64
|
|
||||||
|
|
||||||
trusts []reputation.Trust
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetEpoch sets number of FrostFS epoch in which the trust was assessed.
|
|
||||||
// Required parameter, must not be zero.
|
|
||||||
func (x *PrmAnnounceLocalTrust) SetEpoch(epoch uint64) {
|
|
||||||
x.epoch = epoch
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetValues sets values describing trust of the client to the FrostFS network participants.
|
|
||||||
// Required parameter. Must not be empty.
|
|
||||||
//
|
|
||||||
// Must not be mutated before the end of the operation.
|
|
||||||
func (x *PrmAnnounceLocalTrust) SetValues(trusts []reputation.Trust) {
|
|
||||||
x.trusts = trusts
|
|
||||||
}
|
|
||||||
|
|
||||||
// ResAnnounceLocalTrust groups results of AnnounceLocalTrust operation.
|
|
||||||
type ResAnnounceLocalTrust struct {
|
|
||||||
statusRes
|
|
||||||
}
|
|
||||||
|
|
||||||
// AnnounceLocalTrust sends client's trust values to the FrostFS network participants.
|
|
||||||
//
|
|
||||||
// Exactly one return value is non-nil. By default, server status is returned in res structure.
|
|
||||||
// Any client's internal or transport errors are returned as `error`.
|
|
||||||
// If PrmInit.ResolveFrostFSFailures has been called, unsuccessful
|
|
||||||
// FrostFS status codes are returned as `error`, otherwise, are included
|
|
||||||
// in the returned result structure.
|
|
||||||
//
|
|
||||||
// Returns an error if parameters are set incorrectly (see PrmAnnounceLocalTrust docs).
|
|
||||||
// Context is required and must not be nil. It is used for network communication.
|
|
||||||
//
|
|
||||||
// Return statuses:
|
|
||||||
// - global (see Client docs).
|
|
||||||
func (c *Client) AnnounceLocalTrust(ctx context.Context, prm PrmAnnounceLocalTrust) (*ResAnnounceLocalTrust, error) {
|
|
||||||
// check parameters
|
|
||||||
switch {
|
|
||||||
case prm.epoch == 0:
|
|
||||||
return nil, errorZeroEpoch
|
|
||||||
case len(prm.trusts) == 0:
|
|
||||||
return nil, errorMissingTrusts
|
|
||||||
}
|
|
||||||
|
|
||||||
// form request body
|
|
||||||
reqBody := new(v2reputation.AnnounceLocalTrustRequestBody)
|
|
||||||
reqBody.SetEpoch(prm.epoch)
|
|
||||||
|
|
||||||
trusts := make([]v2reputation.Trust, len(prm.trusts))
|
|
||||||
|
|
||||||
for i := range prm.trusts {
|
|
||||||
prm.trusts[i].WriteToV2(&trusts[i])
|
|
||||||
}
|
|
||||||
|
|
||||||
reqBody.SetTrusts(trusts)
|
|
||||||
|
|
||||||
// form request
|
|
||||||
var req v2reputation.AnnounceLocalTrustRequest
|
|
||||||
|
|
||||||
req.SetBody(reqBody)
|
|
||||||
|
|
||||||
// init call context
|
|
||||||
|
|
||||||
var (
|
|
||||||
cc contextCall
|
|
||||||
res ResAnnounceLocalTrust
|
|
||||||
)
|
|
||||||
|
|
||||||
c.initCallContext(&cc)
|
|
||||||
cc.meta = prm.prmCommonMeta
|
|
||||||
cc.req = &req
|
|
||||||
cc.statusRes = &res
|
|
||||||
cc.call = func() (responseV2, error) {
|
|
||||||
return rpcapi.AnnounceLocalTrust(&c.c, &req, client.WithContext(ctx))
|
|
||||||
}
|
|
||||||
|
|
||||||
// process call
|
|
||||||
if !cc.processCall() {
|
|
||||||
return nil, cc.err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// PrmAnnounceIntermediateTrust groups parameters of AnnounceIntermediateTrust operation.
|
|
||||||
type PrmAnnounceIntermediateTrust struct {
|
|
||||||
prmCommonMeta
|
|
||||||
|
|
||||||
epoch uint64
|
|
||||||
|
|
||||||
iter uint32
|
|
||||||
|
|
||||||
trustSet bool
|
|
||||||
trust reputation.PeerToPeerTrust
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetEpoch sets number of FrostFS epoch with which client's calculation algorithm is initialized.
|
|
||||||
// Required parameter, must not be zero.
|
|
||||||
func (x *PrmAnnounceIntermediateTrust) SetEpoch(epoch uint64) {
|
|
||||||
x.epoch = epoch
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetIteration sets current sequence number of the client's calculation algorithm.
|
|
||||||
// By default, corresponds to initial (zero) iteration.
|
|
||||||
func (x *PrmAnnounceIntermediateTrust) SetIteration(iter uint32) {
|
|
||||||
x.iter = iter
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetCurrentValue sets current global trust value computed at the specified iteration
|
|
||||||
// of the client's calculation algorithm. Required parameter.
|
|
||||||
func (x *PrmAnnounceIntermediateTrust) SetCurrentValue(trust reputation.PeerToPeerTrust) {
|
|
||||||
x.trust = trust
|
|
||||||
x.trustSet = true
|
|
||||||
}
|
|
||||||
|
|
||||||
// ResAnnounceIntermediateTrust groups results of AnnounceIntermediateTrust operation.
|
|
||||||
type ResAnnounceIntermediateTrust struct {
|
|
||||||
statusRes
|
|
||||||
}
|
|
||||||
|
|
||||||
// AnnounceIntermediateTrust sends global trust values calculated for the specified FrostFS network participants
|
|
||||||
// at some stage of client's calculation algorithm.
|
|
||||||
//
|
|
||||||
// Exactly one return value is non-nil. By default, server status is returned in res structure.
|
|
||||||
// Any client's internal or transport errors are returned as `error`.
|
|
||||||
// If PrmInit.ResolveFrostFSFailures has been called, unsuccessful
|
|
||||||
// FrostFS status codes are returned as `error`, otherwise, are included
|
|
||||||
// in the returned result structure.
|
|
||||||
//
|
|
||||||
// Returns an error if parameters are set incorrectly (see PrmAnnounceIntermediateTrust docs).
|
|
||||||
// Context is required and must not be nil. It is used for network communication.
|
|
||||||
//
|
|
||||||
// Return statuses:
|
|
||||||
// - global (see Client docs).
|
|
||||||
func (c *Client) AnnounceIntermediateTrust(ctx context.Context, prm PrmAnnounceIntermediateTrust) (*ResAnnounceIntermediateTrust, error) {
|
|
||||||
// check parameters
|
|
||||||
switch {
|
|
||||||
case prm.epoch == 0:
|
|
||||||
return nil, errorZeroEpoch
|
|
||||||
case !prm.trustSet:
|
|
||||||
return nil, errorTrustNotSet
|
|
||||||
}
|
|
||||||
|
|
||||||
var trust v2reputation.PeerToPeerTrust
|
|
||||||
prm.trust.WriteToV2(&trust)
|
|
||||||
|
|
||||||
// form request body
|
|
||||||
reqBody := new(v2reputation.AnnounceIntermediateResultRequestBody)
|
|
||||||
reqBody.SetEpoch(prm.epoch)
|
|
||||||
reqBody.SetIteration(prm.iter)
|
|
||||||
reqBody.SetTrust(&trust)
|
|
||||||
|
|
||||||
// form request
|
|
||||||
var req v2reputation.AnnounceIntermediateResultRequest
|
|
||||||
|
|
||||||
req.SetBody(reqBody)
|
|
||||||
|
|
||||||
// init call context
|
|
||||||
|
|
||||||
var (
|
|
||||||
cc contextCall
|
|
||||||
res ResAnnounceIntermediateTrust
|
|
||||||
)
|
|
||||||
|
|
||||||
c.initCallContext(&cc)
|
|
||||||
cc.meta = prm.prmCommonMeta
|
|
||||||
cc.req = &req
|
|
||||||
cc.statusRes = &res
|
|
||||||
cc.call = func() (responseV2, error) {
|
|
||||||
return rpcapi.AnnounceIntermediateResult(&c.c, &req, client.WithContext(ctx))
|
|
||||||
}
|
|
||||||
|
|
||||||
// process call
|
|
||||||
if !cc.processCall() {
|
|
||||||
return nil, cc.err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &res, nil
|
|
||||||
}
|
|
|
@ -5,7 +5,6 @@ import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/netmap"
|
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/netmap"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||||
|
@ -55,21 +54,11 @@ func (x *NetworkInfo) readFromV2(m netmap.NetworkInfo, checkFieldPresence bool)
|
||||||
err = fmt.Errorf("empty attribute value %s", name)
|
err = fmt.Errorf("empty attribute value %s", name)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
case configEigenTrustAlpha:
|
|
||||||
var num uint64
|
|
||||||
|
|
||||||
num, err = decodeConfigValueUint64(prm.GetValue())
|
|
||||||
if err == nil {
|
|
||||||
if alpha := math.Float64frombits(num); alpha < 0 && alpha > 1 {
|
|
||||||
err = fmt.Errorf("EigenTrust alpha value %0.2f is out of range [0, 1]", alpha)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case
|
case
|
||||||
configAuditFee,
|
configAuditFee,
|
||||||
configStoragePrice,
|
configStoragePrice,
|
||||||
configContainerFee,
|
configContainerFee,
|
||||||
configNamedContainerFee,
|
configNamedContainerFee,
|
||||||
configEigenTrustNumberOfIterations,
|
|
||||||
configEpochDuration,
|
configEpochDuration,
|
||||||
configIRCandidateFee,
|
configIRCandidateFee,
|
||||||
configMaxObjSize,
|
configMaxObjSize,
|
||||||
|
@ -238,12 +227,10 @@ func (x *NetworkInfo) IterateRawNetworkParameters(f func(name string, value []by
|
||||||
default:
|
default:
|
||||||
f(name, prm.GetValue())
|
f(name, prm.GetValue())
|
||||||
case
|
case
|
||||||
configEigenTrustAlpha,
|
|
||||||
configAuditFee,
|
configAuditFee,
|
||||||
configStoragePrice,
|
configStoragePrice,
|
||||||
configContainerFee,
|
configContainerFee,
|
||||||
configNamedContainerFee,
|
configNamedContainerFee,
|
||||||
configEigenTrustNumberOfIterations,
|
|
||||||
configEpochDuration,
|
configEpochDuration,
|
||||||
configIRCandidateFee,
|
configIRCandidateFee,
|
||||||
configMaxObjSize,
|
configMaxObjSize,
|
||||||
|
@ -394,51 +381,6 @@ func (x NetworkInfo) NamedContainerFee() uint64 {
|
||||||
return x.configUint64(configNamedContainerFee)
|
return x.configUint64(configNamedContainerFee)
|
||||||
}
|
}
|
||||||
|
|
||||||
const configEigenTrustAlpha = "EigenTrustAlpha"
|
|
||||||
|
|
||||||
// SetEigenTrustAlpha sets alpha parameter for EigenTrust algorithm used in
|
|
||||||
// reputation system of the storage nodes. Value MUST be in range [0, 1].
|
|
||||||
//
|
|
||||||
// See also EigenTrustAlpha.
|
|
||||||
func (x *NetworkInfo) SetEigenTrustAlpha(alpha float64) {
|
|
||||||
if alpha < 0 || alpha > 1 {
|
|
||||||
panic(fmt.Sprintf("EigenTrust alpha parameter MUST be in range [0, 1], got %.2f", alpha))
|
|
||||||
}
|
|
||||||
|
|
||||||
x.setConfigUint64(configEigenTrustAlpha, math.Float64bits(alpha))
|
|
||||||
}
|
|
||||||
|
|
||||||
// EigenTrustAlpha returns EigenTrust parameter set using SetEigenTrustAlpha.
|
|
||||||
//
|
|
||||||
// Zero NetworkInfo has zero alpha parameter.
|
|
||||||
func (x NetworkInfo) EigenTrustAlpha() float64 {
|
|
||||||
alpha := math.Float64frombits(x.configUint64(configEigenTrustAlpha))
|
|
||||||
if alpha < 0 || alpha > 1 {
|
|
||||||
panic(fmt.Sprintf("unexpected invalid %s parameter value %.2f", configEigenTrustAlpha, alpha))
|
|
||||||
}
|
|
||||||
|
|
||||||
return alpha
|
|
||||||
}
|
|
||||||
|
|
||||||
const configEigenTrustNumberOfIterations = "EigenTrustIterations"
|
|
||||||
|
|
||||||
// SetNumberOfEigenTrustIterations sets number of iterations of the EigenTrust
|
|
||||||
// algorithm to perform. The algorithm is used by the storage nodes for
|
|
||||||
// calculating the reputation values.
|
|
||||||
//
|
|
||||||
// See also NumberOfEigenTrustIterations.
|
|
||||||
func (x *NetworkInfo) SetNumberOfEigenTrustIterations(num uint64) {
|
|
||||||
x.setConfigUint64(configEigenTrustNumberOfIterations, num)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NumberOfEigenTrustIterations returns number of EigenTrust iterations set
|
|
||||||
// using SetNumberOfEigenTrustIterations.
|
|
||||||
//
|
|
||||||
// Zero NetworkInfo has zero iteration number.
|
|
||||||
func (x NetworkInfo) NumberOfEigenTrustIterations() uint64 {
|
|
||||||
return x.configUint64(configEigenTrustNumberOfIterations)
|
|
||||||
}
|
|
||||||
|
|
||||||
const configEpochDuration = "EpochDuration"
|
const configEpochDuration = "EpochDuration"
|
||||||
|
|
||||||
// SetEpochDuration sets FrostFS epoch duration measured in number of blocks of
|
// SetEpochDuration sets FrostFS epoch duration measured in number of blocks of
|
||||||
|
|
|
@ -2,7 +2,6 @@ package netmap_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"math"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/netmap"
|
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/netmap"
|
||||||
|
@ -148,32 +147,6 @@ func TestNetworkInfo_NamedContainerFee(t *testing.T) {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNetworkInfo_EigenTrustAlpha(t *testing.T) {
|
|
||||||
testConfigValue(t,
|
|
||||||
func(x NetworkInfo) interface{} { return x.EigenTrustAlpha() },
|
|
||||||
func(info *NetworkInfo, val interface{}) { info.SetEigenTrustAlpha(val.(float64)) },
|
|
||||||
0.1, 0.2,
|
|
||||||
"EigenTrustAlpha", func(val interface{}) []byte {
|
|
||||||
data := make([]byte, 8)
|
|
||||||
binary.LittleEndian.PutUint64(data, math.Float64bits(val.(float64)))
|
|
||||||
return data
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNetworkInfo_NumberOfEigenTrustIterations(t *testing.T) {
|
|
||||||
testConfigValue(t,
|
|
||||||
func(x NetworkInfo) interface{} { return x.NumberOfEigenTrustIterations() },
|
|
||||||
func(info *NetworkInfo, val interface{}) { info.SetNumberOfEigenTrustIterations(val.(uint64)) },
|
|
||||||
uint64(1), uint64(2),
|
|
||||||
"EigenTrustIterations", func(val interface{}) []byte {
|
|
||||||
data := make([]byte, 8)
|
|
||||||
binary.LittleEndian.PutUint64(data, val.(uint64))
|
|
||||||
return data
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNetworkInfo_IRCandidateFee(t *testing.T) {
|
func TestNetworkInfo_IRCandidateFee(t *testing.T) {
|
||||||
testConfigValue(t,
|
testConfigValue(t,
|
||||||
func(x NetworkInfo) interface{} { return x.IRCandidateFee() },
|
func(x NetworkInfo) interface{} { return x.IRCandidateFee() },
|
||||||
|
|
|
@ -59,8 +59,6 @@ func NetworkInfo() (x netmap.NetworkInfo) {
|
||||||
x.SetAuditFee(1)
|
x.SetAuditFee(1)
|
||||||
x.SetStoragePrice(2)
|
x.SetStoragePrice(2)
|
||||||
x.SetContainerFee(3)
|
x.SetContainerFee(3)
|
||||||
x.SetEigenTrustAlpha(0.4)
|
|
||||||
x.SetNumberOfEigenTrustIterations(5)
|
|
||||||
x.SetEpochDuration(6)
|
x.SetEpochDuration(6)
|
||||||
x.SetIRCandidateFee(7)
|
x.SetIRCandidateFee(7)
|
||||||
x.SetMaxObjectSize(8)
|
x.SetMaxObjectSize(8)
|
||||||
|
|
|
@ -1,35 +0,0 @@
|
||||||
/*
|
|
||||||
Package reputation collects functionality related to the FrostFS reputation system.
|
|
||||||
|
|
||||||
The functionality is based on the system described in the FrostFS specification.
|
|
||||||
|
|
||||||
Trust type represents simple instances of trust values. PeerToPeerTrust extends
|
|
||||||
Trust to support the direction of trust, i.e. from whom to whom. GlobalTrust
|
|
||||||
is designed as a global measure of trust in a network member. See the docs
|
|
||||||
for each type for details.
|
|
||||||
|
|
||||||
Instances can be also used to process FrostFS API V2 protocol messages
|
|
||||||
(see neo.fs.v2.reputation package in https://git.frostfs.info/TrueCloudLab/frostfs-api).
|
|
||||||
|
|
||||||
On client side:
|
|
||||||
|
|
||||||
import "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/reputation"
|
|
||||||
|
|
||||||
var msg reputation.GlobalTrust
|
|
||||||
trust.WriteToV2(&msg)
|
|
||||||
|
|
||||||
// send trust
|
|
||||||
|
|
||||||
On server side:
|
|
||||||
|
|
||||||
// recv msg
|
|
||||||
|
|
||||||
var trust reputation.GlobalTrust
|
|
||||||
trust.ReadFromV2(msg)
|
|
||||||
|
|
||||||
// process trust
|
|
||||||
|
|
||||||
Using package types in an application is recommended to potentially work with
|
|
||||||
different protocol versions with which these types are compatible.
|
|
||||||
*/
|
|
||||||
package reputation
|
|
|
@ -1,103 +0,0 @@
|
||||||
package reputation
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/reputation"
|
|
||||||
"github.com/mr-tron/base58"
|
|
||||||
)
|
|
||||||
|
|
||||||
// PeerID represents unique identifier of the peer participating in the FrostFS
|
|
||||||
// reputation system.
|
|
||||||
//
|
|
||||||
// ID is mutually compatible with git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/reputation.PeerID
|
|
||||||
// message. See ReadFromV2 / WriteToV2 methods.
|
|
||||||
//
|
|
||||||
// Instances can be created using built-in var declaration.
|
|
||||||
type PeerID struct {
|
|
||||||
m reputation.PeerID
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReadFromV2 reads PeerID from the reputation.PeerID message. Returns an
|
|
||||||
// error if the message is malformed according to the FrostFS API V2 protocol.
|
|
||||||
//
|
|
||||||
// See also WriteToV2.
|
|
||||||
func (x *PeerID) ReadFromV2(m reputation.PeerID) error {
|
|
||||||
val := m.GetPublicKey()
|
|
||||||
if len(val) == 0 {
|
|
||||||
return errors.New("missing ID bytes")
|
|
||||||
}
|
|
||||||
|
|
||||||
x.m = m
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// WriteToV2 writes PeerID to the reputation.PeerID message.
|
|
||||||
// The message must not be nil.
|
|
||||||
//
|
|
||||||
// See also ReadFromV2.
|
|
||||||
func (x PeerID) WriteToV2(m *reputation.PeerID) {
|
|
||||||
*m = x.m
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetPublicKey sets PeerID as a binary-encoded public key which authenticates
|
|
||||||
// the participant of the FrostFS reputation system.
|
|
||||||
//
|
|
||||||
// Argument MUST NOT be mutated, make a copy first.
|
|
||||||
//
|
|
||||||
// See also CompareKey.
|
|
||||||
func (x *PeerID) SetPublicKey(key []byte) {
|
|
||||||
x.m.SetPublicKey(key)
|
|
||||||
}
|
|
||||||
|
|
||||||
// PublicKey return public key set using SetPublicKey.
|
|
||||||
//
|
|
||||||
// Zero PeerID has zero key which is incorrect according to FrostFS API
|
|
||||||
// protocol.
|
|
||||||
//
|
|
||||||
// Return value MUST NOT be mutated, make a copy first.
|
|
||||||
func (x PeerID) PublicKey() []byte {
|
|
||||||
return x.m.GetPublicKey()
|
|
||||||
}
|
|
||||||
|
|
||||||
// ComparePeerKey checks if the given PeerID corresponds to the party
|
|
||||||
// authenticated by the given binary public key.
|
|
||||||
func ComparePeerKey(peer PeerID, key []byte) bool {
|
|
||||||
return bytes.Equal(peer.PublicKey(), key)
|
|
||||||
}
|
|
||||||
|
|
||||||
// EncodeToString encodes ID into FrostFS API protocol string.
|
|
||||||
//
|
|
||||||
// Zero PeerID is base58 encoding of PeerIDSize zeros.
|
|
||||||
//
|
|
||||||
// See also DecodeString.
|
|
||||||
func (x PeerID) EncodeToString() string {
|
|
||||||
return base58.Encode(x.m.GetPublicKey())
|
|
||||||
}
|
|
||||||
|
|
||||||
// DecodeString decodes string into PeerID according to FrostFS API protocol.
|
|
||||||
// Returns an error if s is malformed.
|
|
||||||
//
|
|
||||||
// See also DecodeString.
|
|
||||||
func (x *PeerID) DecodeString(s string) error {
|
|
||||||
data, err := base58.Decode(s)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("decode base58: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
x.m.SetPublicKey(data)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// String implements fmt.Stringer.
|
|
||||||
//
|
|
||||||
// String is designed to be human-readable, and its format MAY differ between
|
|
||||||
// SDK versions. String MAY return same result as EncodeToString. String MUST NOT
|
|
||||||
// be used to encode ID into FrostFS protocol string.
|
|
||||||
func (x PeerID) String() string {
|
|
||||||
return x.EncodeToString()
|
|
||||||
}
|
|
|
@ -1,40 +0,0 @@
|
||||||
package reputation_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
v2reputation "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/reputation"
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/reputation"
|
|
||||||
reputationtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/reputation/test"
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestPeerID_PublicKey(t *testing.T) {
|
|
||||||
var val reputation.PeerID
|
|
||||||
|
|
||||||
require.Zero(t, val.PublicKey())
|
|
||||||
|
|
||||||
key := []byte{3, 2, 1}
|
|
||||||
|
|
||||||
val.SetPublicKey(key)
|
|
||||||
|
|
||||||
var m v2reputation.PeerID
|
|
||||||
val.WriteToV2(&m)
|
|
||||||
|
|
||||||
require.Equal(t, key, m.GetPublicKey())
|
|
||||||
|
|
||||||
var val2 reputation.PeerID
|
|
||||||
require.NoError(t, val2.ReadFromV2(m))
|
|
||||||
|
|
||||||
require.Equal(t, key, val.PublicKey())
|
|
||||||
|
|
||||||
require.True(t, reputation.ComparePeerKey(val, key))
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPeerID_EncodeToString(t *testing.T) {
|
|
||||||
val := reputationtest.PeerID()
|
|
||||||
var val2 reputation.PeerID
|
|
||||||
|
|
||||||
require.NoError(t, val2.DecodeString(val.EncodeToString()))
|
|
||||||
require.Equal(t, val, val2)
|
|
||||||
}
|
|
|
@ -1,58 +0,0 @@
|
||||||
package reputationtest
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
frostfsecdsa "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/crypto/ecdsa"
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/reputation"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
|
||||||
)
|
|
||||||
|
|
||||||
func PeerID() (v reputation.PeerID) {
|
|
||||||
p, err := keys.NewPrivateKey()
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
v.SetPublicKey(p.PublicKey().Bytes())
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func Trust() (v reputation.Trust) {
|
|
||||||
v.SetPeer(PeerID())
|
|
||||||
v.SetValue(0.5)
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func PeerToPeerTrust() (v reputation.PeerToPeerTrust) {
|
|
||||||
v.SetTrustingPeer(PeerID())
|
|
||||||
v.SetTrust(Trust())
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func GlobalTrust() (v reputation.GlobalTrust) {
|
|
||||||
v.Init()
|
|
||||||
v.SetManager(PeerID())
|
|
||||||
v.SetTrust(Trust())
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func SignedGlobalTrust() reputation.GlobalTrust {
|
|
||||||
gt := GlobalTrust()
|
|
||||||
|
|
||||||
p, err := keys.NewPrivateKey()
|
|
||||||
if err != nil {
|
|
||||||
panic(fmt.Sprintf("unexpected error from key creator: %v", err))
|
|
||||||
}
|
|
||||||
|
|
||||||
err = gt.Sign(frostfsecdsa.Signer(p.PrivateKey))
|
|
||||||
if err != nil {
|
|
||||||
panic(fmt.Sprintf("unexpected error from GlobalTrust.Sign: %v", err))
|
|
||||||
}
|
|
||||||
|
|
||||||
return gt
|
|
||||||
}
|
|
|
@ -1,416 +0,0 @@
|
||||||
package reputation
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs"
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/reputation"
|
|
||||||
frostfscrypto "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/crypto"
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/version"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Trust represents quantitative assessment of the trust of a participant in the
|
|
||||||
// FrostFS reputation system.
|
|
||||||
//
|
|
||||||
// Trust is mutually compatible with git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/reputation.Trust
|
|
||||||
// message. See ReadFromV2 / WriteToV2 methods.
|
|
||||||
//
|
|
||||||
// Instances can be created using built-in var declaration.
|
|
||||||
type Trust struct {
|
|
||||||
m reputation.Trust
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReadFromV2 reads Trust from the reputation.Trust message. Returns an
|
|
||||||
// error if the message is malformed according to the FrostFS API V2 protocol.
|
|
||||||
//
|
|
||||||
// See also WriteToV2.
|
|
||||||
func (x *Trust) ReadFromV2(m reputation.Trust) error {
|
|
||||||
if val := m.GetValue(); val < 0 || val > 1 {
|
|
||||||
return fmt.Errorf("invalid trust value %v", val)
|
|
||||||
}
|
|
||||||
|
|
||||||
peerV2 := m.GetPeer()
|
|
||||||
if peerV2 == nil {
|
|
||||||
return errors.New("missing peer field")
|
|
||||||
}
|
|
||||||
|
|
||||||
var peer PeerID
|
|
||||||
|
|
||||||
err := peer.ReadFromV2(*peerV2)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("invalid peer field: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
x.m = m
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// WriteToV2 writes Trust to the reputation.Trust message.
|
|
||||||
// The message must not be nil.
|
|
||||||
//
|
|
||||||
// See also ReadFromV2.
|
|
||||||
func (x Trust) WriteToV2(m *reputation.Trust) {
|
|
||||||
*m = x.m
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetPeer specifies identifier of the participant of the FrostFS reputation system
|
|
||||||
// to which the Trust relates.
|
|
||||||
//
|
|
||||||
// See also Peer.
|
|
||||||
func (x *Trust) SetPeer(id PeerID) {
|
|
||||||
var m reputation.PeerID
|
|
||||||
id.WriteToV2(&m)
|
|
||||||
|
|
||||||
x.m.SetPeer(&m)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Peer returns peer identifier set using SetPeer.
|
|
||||||
//
|
|
||||||
// Zero Trust returns zero PeerID which is incorrect according to the FrostFS API
|
|
||||||
// protocol.
|
|
||||||
func (x Trust) Peer() (res PeerID) {
|
|
||||||
m := x.m.GetPeer()
|
|
||||||
if m != nil {
|
|
||||||
err := res.ReadFromV2(*m)
|
|
||||||
if err != nil {
|
|
||||||
panic(fmt.Sprintf("unexpected error from ReadFromV2: %v", err))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetValue sets the Trust value. Value MUST be in range [0;1].
|
|
||||||
//
|
|
||||||
// See also Value.
|
|
||||||
func (x *Trust) SetValue(val float64) {
|
|
||||||
if val < 0 || val > 1 {
|
|
||||||
panic(fmt.Sprintf("trust value is out-of-range %v", val))
|
|
||||||
}
|
|
||||||
|
|
||||||
x.m.SetValue(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Value returns value set using SetValue.
|
|
||||||
//
|
|
||||||
// Zero Trust has zero value.
|
|
||||||
func (x Trust) Value() float64 {
|
|
||||||
return x.m.GetValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
// PeerToPeerTrust represents trust of one participant of the FrostFS reputation
|
|
||||||
// system to another one.
|
|
||||||
//
|
|
||||||
// Trust is mutually compatible with git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/reputation.PeerToPeerTrust
|
|
||||||
// message. See ReadFromV2 / WriteToV2 methods.
|
|
||||||
//
|
|
||||||
// Instances can be created using built-in var declaration.
|
|
||||||
type PeerToPeerTrust struct {
|
|
||||||
m reputation.PeerToPeerTrust
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReadFromV2 reads PeerToPeerTrust from the reputation.PeerToPeerTrust message.
|
|
||||||
// Returns an error if the message is malformed according to the FrostFS API V2
|
|
||||||
// protocol.
|
|
||||||
//
|
|
||||||
// See also WriteToV2.
|
|
||||||
func (x *PeerToPeerTrust) ReadFromV2(m reputation.PeerToPeerTrust) error {
|
|
||||||
trustingV2 := m.GetTrustingPeer()
|
|
||||||
if trustingV2 == nil {
|
|
||||||
return errors.New("missing trusting peer")
|
|
||||||
}
|
|
||||||
|
|
||||||
var trusting PeerID
|
|
||||||
|
|
||||||
err := trusting.ReadFromV2(*trustingV2)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("invalid trusting peer: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
trustV2 := m.GetTrust()
|
|
||||||
if trustV2 == nil {
|
|
||||||
return errors.New("missing trust")
|
|
||||||
}
|
|
||||||
|
|
||||||
var trust Trust
|
|
||||||
|
|
||||||
err = trust.ReadFromV2(*trustV2)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("invalid trust: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
x.m = m
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// WriteToV2 writes PeerToPeerTrust to the reputation.PeerToPeerTrust message.
|
|
||||||
// The message must not be nil.
|
|
||||||
//
|
|
||||||
// See also ReadFromV2.
|
|
||||||
func (x PeerToPeerTrust) WriteToV2(m *reputation.PeerToPeerTrust) {
|
|
||||||
*m = x.m
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetTrustingPeer specifies the peer from which trust comes in terms of the
|
|
||||||
// FrostFS reputation system.
|
|
||||||
//
|
|
||||||
// See also TrustingPeer.
|
|
||||||
func (x *PeerToPeerTrust) SetTrustingPeer(id PeerID) {
|
|
||||||
var m reputation.PeerID
|
|
||||||
id.WriteToV2(&m)
|
|
||||||
|
|
||||||
x.m.SetTrustingPeer(&m)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TrustingPeer returns peer set using SetTrustingPeer.
|
|
||||||
//
|
|
||||||
// Zero PeerToPeerTrust has no trusting peer which is incorrect according
|
|
||||||
// to the FrostFS API protocol.
|
|
||||||
func (x PeerToPeerTrust) TrustingPeer() (res PeerID) {
|
|
||||||
m := x.m.GetTrustingPeer()
|
|
||||||
if m != nil {
|
|
||||||
err := res.ReadFromV2(*m)
|
|
||||||
if err != nil {
|
|
||||||
panic(fmt.Sprintf("unexpected error from PeerID.ReadFromV2: %v", err))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetTrust sets trust value of the trusting peer to another participant
|
|
||||||
// of the FrostFS reputation system.
|
|
||||||
//
|
|
||||||
// See also Trust.
|
|
||||||
func (x *PeerToPeerTrust) SetTrust(t Trust) {
|
|
||||||
var tV2 reputation.Trust
|
|
||||||
t.WriteToV2(&tV2)
|
|
||||||
|
|
||||||
x.m.SetTrust(&tV2)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Trust returns trust set using SetTrust.
|
|
||||||
//
|
|
||||||
// Zero PeerToPeerTrust returns zero Trust which is incorrect according to the
|
|
||||||
// FrostFS API protocol.
|
|
||||||
func (x PeerToPeerTrust) Trust() (res Trust) {
|
|
||||||
m := x.m.GetTrust()
|
|
||||||
if m != nil {
|
|
||||||
err := res.ReadFromV2(*m)
|
|
||||||
if err != nil {
|
|
||||||
panic(fmt.Sprintf("unexpected error from Trust.ReadFromV2: %v", err))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// GlobalTrust represents the final assessment of trust in the participant of
|
|
||||||
// the FrostFS reputation system obtained taking into account all other participants.
|
|
||||||
//
|
|
||||||
// GlobalTrust is mutually compatible with git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/reputation.GlobalTrust
|
|
||||||
// message. See ReadFromV2 / WriteToV2 methods.
|
|
||||||
//
|
|
||||||
// To submit GlobalTrust value in FrostFS zero instance SHOULD be declared,
|
|
||||||
// initialized using Init method and filled using dedicated methods.
|
|
||||||
type GlobalTrust struct {
|
|
||||||
m reputation.GlobalTrust
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReadFromV2 reads GlobalTrust from the reputation.GlobalTrust message.
|
|
||||||
// Returns an error if the message is malformed according to the FrostFS API V2
|
|
||||||
// protocol.
|
|
||||||
//
|
|
||||||
// See also WriteToV2.
|
|
||||||
func (x *GlobalTrust) ReadFromV2(m reputation.GlobalTrust) error {
|
|
||||||
if m.GetVersion() == nil {
|
|
||||||
return errors.New("missing version")
|
|
||||||
}
|
|
||||||
|
|
||||||
if m.GetSignature() == nil {
|
|
||||||
return errors.New("missing signature")
|
|
||||||
}
|
|
||||||
|
|
||||||
body := m.GetBody()
|
|
||||||
if body == nil {
|
|
||||||
return errors.New("missing body")
|
|
||||||
}
|
|
||||||
|
|
||||||
managerV2 := body.GetManager()
|
|
||||||
if managerV2 == nil {
|
|
||||||
return errors.New("missing manager")
|
|
||||||
}
|
|
||||||
|
|
||||||
var manager PeerID
|
|
||||||
|
|
||||||
err := manager.ReadFromV2(*managerV2)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("invalid manager: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
trustV2 := body.GetTrust()
|
|
||||||
if trustV2 == nil {
|
|
||||||
return errors.New("missing trust")
|
|
||||||
}
|
|
||||||
|
|
||||||
var trust Trust
|
|
||||||
|
|
||||||
err = trust.ReadFromV2(*trustV2)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("invalid trust: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
x.m = m
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// WriteToV2 writes GlobalTrust to the reputation.GlobalTrust message.
|
|
||||||
// The message must not be nil.
|
|
||||||
//
|
|
||||||
// See also ReadFromV2.
|
|
||||||
func (x GlobalTrust) WriteToV2(m *reputation.GlobalTrust) {
|
|
||||||
*m = x.m
|
|
||||||
}
|
|
||||||
|
|
||||||
// Init initializes all internal data of the GlobalTrust required by FrostFS API
|
|
||||||
// protocol. Init MUST be called when creating a new global trust instance.
|
|
||||||
// Init SHOULD NOT be called multiple times. Init SHOULD NOT be called if
|
|
||||||
// the GlobalTrust instance is used for decoding only.
|
|
||||||
func (x *GlobalTrust) Init() {
|
|
||||||
var ver refs.Version
|
|
||||||
version.Current().WriteToV2(&ver)
|
|
||||||
|
|
||||||
x.m.SetVersion(&ver)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *GlobalTrust) setBodyField(setter func(*reputation.GlobalTrustBody)) {
|
|
||||||
if x != nil {
|
|
||||||
body := x.m.GetBody()
|
|
||||||
if body == nil {
|
|
||||||
body = new(reputation.GlobalTrustBody)
|
|
||||||
x.m.SetBody(body)
|
|
||||||
}
|
|
||||||
|
|
||||||
setter(body)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetManager sets identifier of the FrostFS reputation system's participant which
|
|
||||||
// performed trust estimation.
|
|
||||||
//
|
|
||||||
// See also Manager.
|
|
||||||
func (x *GlobalTrust) SetManager(id PeerID) {
|
|
||||||
var m reputation.PeerID
|
|
||||||
id.WriteToV2(&m)
|
|
||||||
|
|
||||||
x.setBodyField(func(body *reputation.GlobalTrustBody) {
|
|
||||||
body.SetManager(&m)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Manager returns peer set using SetManager.
|
|
||||||
//
|
|
||||||
// Zero GlobalTrust has zero manager which is incorrect according to the
|
|
||||||
// FrostFS API protocol.
|
|
||||||
func (x GlobalTrust) Manager() (res PeerID) {
|
|
||||||
m := x.m.GetBody().GetManager()
|
|
||||||
if m != nil {
|
|
||||||
err := res.ReadFromV2(*m)
|
|
||||||
if err != nil {
|
|
||||||
panic(fmt.Sprintf("unexpected error from ReadFromV2: %v", err))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetTrust sets the global trust score of the network to a specific network
|
|
||||||
// member.
|
|
||||||
//
|
|
||||||
// See also Trust.
|
|
||||||
func (x *GlobalTrust) SetTrust(trust Trust) {
|
|
||||||
var m reputation.Trust
|
|
||||||
trust.WriteToV2(&m)
|
|
||||||
|
|
||||||
x.setBodyField(func(body *reputation.GlobalTrustBody) {
|
|
||||||
body.SetTrust(&m)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Trust returns trust set using SetTrust.
|
|
||||||
//
|
|
||||||
// Zero GlobalTrust return zero Trust which is incorrect according to the
|
|
||||||
// FrostFS API protocol.
|
|
||||||
func (x GlobalTrust) Trust() (res Trust) {
|
|
||||||
m := x.m.GetBody().GetTrust()
|
|
||||||
if m != nil {
|
|
||||||
err := res.ReadFromV2(*m)
|
|
||||||
if err != nil {
|
|
||||||
panic(fmt.Sprintf("unexpected error from ReadFromV2: %v", err))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sign calculates and writes signature of the GlobalTrust data. Returns
|
|
||||||
// signature calculation errors.
|
|
||||||
//
|
|
||||||
// Zero GlobalTrust is unsigned.
|
|
||||||
//
|
|
||||||
// Note that any GlobalTrust mutation is likely to break the signature, so it is
|
|
||||||
// expected to be calculated as a final stage of GlobalTrust formation.
|
|
||||||
//
|
|
||||||
// See also VerifySignature.
|
|
||||||
func (x *GlobalTrust) Sign(signer frostfscrypto.Signer) error {
|
|
||||||
var sig frostfscrypto.Signature
|
|
||||||
|
|
||||||
err := sig.Calculate(signer, x.m.GetBody().StableMarshal(nil))
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("calculate signature: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var sigv2 refs.Signature
|
|
||||||
sig.WriteToV2(&sigv2)
|
|
||||||
|
|
||||||
x.m.SetSignature(&sigv2)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// VerifySignature checks if GlobalTrust signature is presented and valid.
|
|
||||||
//
|
|
||||||
// Zero GlobalTrust fails the check.
|
|
||||||
//
|
|
||||||
// See also Sign.
|
|
||||||
func (x GlobalTrust) VerifySignature() bool {
|
|
||||||
sigV2 := x.m.GetSignature()
|
|
||||||
if sigV2 == nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
var sig frostfscrypto.Signature
|
|
||||||
|
|
||||||
return sig.ReadFromV2(*sigV2) == nil && sig.Verify(x.m.GetBody().StableMarshal(nil))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Marshal encodes GlobalTrust into a binary format of the FrostFS API protocol
|
|
||||||
// (Protocol Buffers with direct field order).
|
|
||||||
//
|
|
||||||
// See also Unmarshal.
|
|
||||||
func (x GlobalTrust) Marshal() []byte {
|
|
||||||
return x.m.StableMarshal(nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unmarshal decodes FrostFS API protocol binary format into the GlobalTrust
|
|
||||||
// (Protocol Buffers with direct field order). Returns an error describing
|
|
||||||
// a format violation.
|
|
||||||
//
|
|
||||||
// See also Marshal.
|
|
||||||
func (x *GlobalTrust) Unmarshal(data []byte) error {
|
|
||||||
return x.m.Unmarshal(data)
|
|
||||||
}
|
|
|
@ -1,208 +0,0 @@
|
||||||
package reputation_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs"
|
|
||||||
v2reputation "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/reputation"
|
|
||||||
frostfsecdsa "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/crypto/ecdsa"
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/reputation"
|
|
||||||
reputationtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/reputation/test"
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/version"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestTrust_Peer(t *testing.T) {
|
|
||||||
var trust reputation.Trust
|
|
||||||
|
|
||||||
require.Zero(t, trust.Peer())
|
|
||||||
|
|
||||||
trust = reputationtest.Trust()
|
|
||||||
|
|
||||||
peer := reputationtest.PeerID()
|
|
||||||
|
|
||||||
trust.SetPeer(peer)
|
|
||||||
|
|
||||||
var peerV2 v2reputation.PeerID
|
|
||||||
peer.WriteToV2(&peerV2)
|
|
||||||
|
|
||||||
var trustV2 v2reputation.Trust
|
|
||||||
trust.WriteToV2(&trustV2)
|
|
||||||
|
|
||||||
require.Equal(t, &peerV2, trustV2.GetPeer())
|
|
||||||
|
|
||||||
var val2 reputation.Trust
|
|
||||||
require.NoError(t, val2.ReadFromV2(trustV2))
|
|
||||||
|
|
||||||
require.Equal(t, peer, val2.Peer())
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestTrust_Value(t *testing.T) {
|
|
||||||
var val reputation.Trust
|
|
||||||
|
|
||||||
require.Zero(t, val.Value())
|
|
||||||
|
|
||||||
val = reputationtest.Trust()
|
|
||||||
|
|
||||||
const value = 0.75
|
|
||||||
|
|
||||||
val.SetValue(value)
|
|
||||||
|
|
||||||
var trustV2 v2reputation.Trust
|
|
||||||
val.WriteToV2(&trustV2)
|
|
||||||
|
|
||||||
require.EqualValues(t, value, trustV2.GetValue())
|
|
||||||
|
|
||||||
var val2 reputation.Trust
|
|
||||||
require.NoError(t, val2.ReadFromV2(trustV2))
|
|
||||||
|
|
||||||
require.EqualValues(t, value, val2.Value())
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPeerToPeerTrust_TrustingPeer(t *testing.T) {
|
|
||||||
var val reputation.PeerToPeerTrust
|
|
||||||
|
|
||||||
require.Zero(t, val.TrustingPeer())
|
|
||||||
|
|
||||||
val = reputationtest.PeerToPeerTrust()
|
|
||||||
|
|
||||||
peer := reputationtest.PeerID()
|
|
||||||
|
|
||||||
val.SetTrustingPeer(peer)
|
|
||||||
|
|
||||||
var peerV2 v2reputation.PeerID
|
|
||||||
peer.WriteToV2(&peerV2)
|
|
||||||
|
|
||||||
var trustV2 v2reputation.PeerToPeerTrust
|
|
||||||
val.WriteToV2(&trustV2)
|
|
||||||
|
|
||||||
require.Equal(t, &peerV2, trustV2.GetTrustingPeer())
|
|
||||||
|
|
||||||
var val2 reputation.PeerToPeerTrust
|
|
||||||
require.NoError(t, val2.ReadFromV2(trustV2))
|
|
||||||
|
|
||||||
require.Equal(t, peer, val2.TrustingPeer())
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPeerToPeerTrust_Trust(t *testing.T) {
|
|
||||||
var val reputation.PeerToPeerTrust
|
|
||||||
|
|
||||||
require.Zero(t, val.Trust())
|
|
||||||
|
|
||||||
val = reputationtest.PeerToPeerTrust()
|
|
||||||
|
|
||||||
trust := reputationtest.Trust()
|
|
||||||
|
|
||||||
val.SetTrust(trust)
|
|
||||||
|
|
||||||
var trustV2 v2reputation.Trust
|
|
||||||
trust.WriteToV2(&trustV2)
|
|
||||||
|
|
||||||
var valV2 v2reputation.PeerToPeerTrust
|
|
||||||
val.WriteToV2(&valV2)
|
|
||||||
|
|
||||||
require.Equal(t, &trustV2, valV2.GetTrust())
|
|
||||||
|
|
||||||
var val2 reputation.PeerToPeerTrust
|
|
||||||
require.NoError(t, val2.ReadFromV2(valV2))
|
|
||||||
|
|
||||||
require.Equal(t, trust, val2.Trust())
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGlobalTrust_Init(t *testing.T) {
|
|
||||||
var val reputation.GlobalTrust
|
|
||||||
val.Init()
|
|
||||||
|
|
||||||
var valV2 v2reputation.GlobalTrust
|
|
||||||
val.WriteToV2(&valV2)
|
|
||||||
|
|
||||||
var verV2 refs.Version
|
|
||||||
version.Current().WriteToV2(&verV2)
|
|
||||||
|
|
||||||
require.Equal(t, &verV2, valV2.GetVersion())
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGlobalTrust_Manager(t *testing.T) {
|
|
||||||
var val reputation.GlobalTrust
|
|
||||||
|
|
||||||
require.Zero(t, val.Manager())
|
|
||||||
|
|
||||||
val = reputationtest.SignedGlobalTrust()
|
|
||||||
|
|
||||||
peer := reputationtest.PeerID()
|
|
||||||
|
|
||||||
val.SetManager(peer)
|
|
||||||
|
|
||||||
var peerV2 v2reputation.PeerID
|
|
||||||
peer.WriteToV2(&peerV2)
|
|
||||||
|
|
||||||
var trustV2 v2reputation.GlobalTrust
|
|
||||||
val.WriteToV2(&trustV2)
|
|
||||||
|
|
||||||
require.Equal(t, &peerV2, trustV2.GetBody().GetManager())
|
|
||||||
|
|
||||||
var val2 reputation.GlobalTrust
|
|
||||||
require.NoError(t, val2.ReadFromV2(trustV2))
|
|
||||||
|
|
||||||
require.Equal(t, peer, val2.Manager())
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGlobalTrust_Trust(t *testing.T) {
|
|
||||||
var val reputation.GlobalTrust
|
|
||||||
|
|
||||||
require.Zero(t, val.Trust())
|
|
||||||
|
|
||||||
val = reputationtest.SignedGlobalTrust()
|
|
||||||
|
|
||||||
trust := reputationtest.Trust()
|
|
||||||
|
|
||||||
val.SetTrust(trust)
|
|
||||||
|
|
||||||
var trustV2 v2reputation.Trust
|
|
||||||
trust.WriteToV2(&trustV2)
|
|
||||||
|
|
||||||
var valV2 v2reputation.GlobalTrust
|
|
||||||
val.WriteToV2(&valV2)
|
|
||||||
|
|
||||||
require.Equal(t, &trustV2, valV2.GetBody().GetTrust())
|
|
||||||
|
|
||||||
var val2 reputation.GlobalTrust
|
|
||||||
require.NoError(t, val2.ReadFromV2(valV2))
|
|
||||||
|
|
||||||
require.Equal(t, trust, val2.Trust())
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGlobalTrust_Sign(t *testing.T) {
|
|
||||||
k, err := keys.NewPrivateKey()
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
val := reputationtest.GlobalTrust()
|
|
||||||
|
|
||||||
require.False(t, val.VerifySignature())
|
|
||||||
|
|
||||||
require.NoError(t, val.Sign(frostfsecdsa.Signer(k.PrivateKey)))
|
|
||||||
|
|
||||||
var valV2 v2reputation.GlobalTrust
|
|
||||||
val.WriteToV2(&valV2)
|
|
||||||
|
|
||||||
require.NotZero(t, valV2.GetSignature())
|
|
||||||
|
|
||||||
var val2 reputation.GlobalTrust
|
|
||||||
require.NoError(t, val2.ReadFromV2(valV2))
|
|
||||||
|
|
||||||
require.True(t, val2.VerifySignature())
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGlobalTrustEncoding(t *testing.T) {
|
|
||||||
val := reputationtest.SignedGlobalTrust()
|
|
||||||
|
|
||||||
t.Run("binary", func(t *testing.T) {
|
|
||||||
data := val.Marshal()
|
|
||||||
|
|
||||||
var val2 reputation.GlobalTrust
|
|
||||||
require.NoError(t, val2.Unmarshal(data))
|
|
||||||
|
|
||||||
require.Equal(t, val, val2)
|
|
||||||
})
|
|
||||||
}
|
|
Loading…
Reference in a new issue