9a11a75b77
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
201 lines
3.7 KiB
Go
201 lines
3.7 KiB
Go
package consumerstorage
|
|
|
|
import (
|
|
"fmt"
|
|
"sync"
|
|
|
|
"github.com/nspcc-dev/neofs-node/pkg/services/reputation"
|
|
"github.com/nspcc-dev/neofs-node/pkg/services/reputation/eigentrust"
|
|
eigentrustcalc "github.com/nspcc-dev/neofs-node/pkg/services/reputation/eigentrust/calculator"
|
|
apireputation "github.com/nspcc-dev/neofs-sdk-go/reputation"
|
|
)
|
|
|
|
// Put saves intermediate trust of the consumer to daughter peer.
|
|
func (x *Storage) Put(trust eigentrust.IterationTrust) {
|
|
var s *iterationConsumersStorage
|
|
|
|
x.mtx.Lock()
|
|
|
|
{
|
|
epoch := trust.Epoch()
|
|
|
|
s = x.mItems[epoch]
|
|
if s == nil {
|
|
s = &iterationConsumersStorage{
|
|
mItems: make(map[uint32]*ConsumersStorage, 1),
|
|
}
|
|
|
|
x.mItems[epoch] = s
|
|
}
|
|
}
|
|
|
|
x.mtx.Unlock()
|
|
|
|
s.put(trust)
|
|
}
|
|
|
|
// Consumers returns the storage of trusts of the consumers of the daughter peers
|
|
// for particular iteration of EigenTrust calculation for particular epoch.
|
|
//
|
|
// Returns false if there is no data for the epoch and iter.
|
|
func (x *Storage) Consumers(epoch uint64, iter uint32) (*ConsumersStorage, bool) {
|
|
var (
|
|
s *iterationConsumersStorage
|
|
ok bool
|
|
)
|
|
|
|
x.mtx.Lock()
|
|
|
|
{
|
|
s, ok = x.mItems[epoch]
|
|
}
|
|
|
|
x.mtx.Unlock()
|
|
|
|
if !ok {
|
|
return nil, false
|
|
}
|
|
|
|
return s.consumers(iter)
|
|
}
|
|
|
|
// maps iteration numbers of EigenTrust algorithm to repositories
|
|
// of the trusts of the consumers of the daughter peers.
|
|
type iterationConsumersStorage struct {
|
|
mtx sync.RWMutex
|
|
|
|
mItems map[uint32]*ConsumersStorage
|
|
}
|
|
|
|
func (x *iterationConsumersStorage) put(trust eigentrust.IterationTrust) {
|
|
var s *ConsumersStorage
|
|
|
|
x.mtx.Lock()
|
|
|
|
{
|
|
iter := trust.I()
|
|
|
|
s = x.mItems[iter]
|
|
if s == nil {
|
|
s = &ConsumersStorage{
|
|
mItems: make(map[string]*ConsumersTrusts, 1),
|
|
}
|
|
|
|
x.mItems[iter] = s
|
|
}
|
|
}
|
|
|
|
x.mtx.Unlock()
|
|
|
|
s.put(trust)
|
|
}
|
|
|
|
func (x *iterationConsumersStorage) consumers(iter uint32) (s *ConsumersStorage, ok bool) {
|
|
x.mtx.Lock()
|
|
|
|
{
|
|
s, ok = x.mItems[iter]
|
|
}
|
|
|
|
x.mtx.Unlock()
|
|
|
|
return
|
|
}
|
|
|
|
// ConsumersStorage represents in-memory storage of intermediate trusts
|
|
// of the peer consumers.
|
|
//
|
|
// Maps daughter peers to repositories of the trusts of their consumers.
|
|
type ConsumersStorage struct {
|
|
mtx sync.RWMutex
|
|
|
|
mItems map[string]*ConsumersTrusts
|
|
}
|
|
|
|
func (x *ConsumersStorage) put(trust eigentrust.IterationTrust) {
|
|
var s *ConsumersTrusts
|
|
|
|
x.mtx.Lock()
|
|
|
|
{
|
|
daughter := trust.Peer().EncodeToString()
|
|
|
|
s = x.mItems[daughter]
|
|
if s == nil {
|
|
s = &ConsumersTrusts{
|
|
mItems: make(map[string]reputation.Trust, 1),
|
|
}
|
|
|
|
x.mItems[daughter] = s
|
|
}
|
|
}
|
|
|
|
x.mtx.Unlock()
|
|
|
|
s.put(trust)
|
|
}
|
|
|
|
// Iterate passes IDs of the daughter peers with the trusts of their consumers to h.
|
|
//
|
|
// Returns errors from h directly.
|
|
func (x *ConsumersStorage) Iterate(h eigentrustcalc.PeerTrustsHandler) (err error) {
|
|
x.mtx.RLock()
|
|
|
|
{
|
|
for strTrusted, trusts := range x.mItems {
|
|
var trusted apireputation.PeerID
|
|
|
|
if strTrusted != "" {
|
|
err = trusted.DecodeString(strTrusted)
|
|
if err != nil {
|
|
panic(fmt.Sprintf("decode peer ID string %s: %v", strTrusted, err))
|
|
}
|
|
}
|
|
|
|
if err = h(trusted, trusts); err != nil {
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
x.mtx.RUnlock()
|
|
|
|
return
|
|
}
|
|
|
|
// ConsumersTrusts represents in-memory storage of the trusts
|
|
// of the consumer peers to some other peer.
|
|
type ConsumersTrusts struct {
|
|
mtx sync.RWMutex
|
|
|
|
mItems map[string]reputation.Trust
|
|
}
|
|
|
|
func (x *ConsumersTrusts) put(trust eigentrust.IterationTrust) {
|
|
x.mtx.Lock()
|
|
|
|
{
|
|
x.mItems[trust.TrustingPeer().EncodeToString()] = trust.Trust
|
|
}
|
|
|
|
x.mtx.Unlock()
|
|
}
|
|
|
|
// Iterate passes all stored trusts to h.
|
|
//
|
|
// Returns errors from h directly.
|
|
func (x *ConsumersTrusts) Iterate(h reputation.TrustHandler) (err error) {
|
|
x.mtx.RLock()
|
|
|
|
{
|
|
for _, trust := range x.mItems {
|
|
if err = h(trust); err != nil {
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
x.mtx.RUnlock()
|
|
|
|
return
|
|
}
|