9a11a75b77
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
177 lines
3.3 KiB
Go
177 lines
3.3 KiB
Go
package daughters
|
|
|
|
import (
|
|
"fmt"
|
|
"sync"
|
|
|
|
"github.com/nspcc-dev/neofs-node/pkg/services/reputation"
|
|
eigentrustcalc "github.com/nspcc-dev/neofs-node/pkg/services/reputation/eigentrust/calculator"
|
|
apireputation "github.com/nspcc-dev/neofs-sdk-go/reputation"
|
|
)
|
|
|
|
// Put saves daughter peer's trust to its provider for the epoch.
|
|
func (x *Storage) Put(epoch uint64, trust reputation.Trust) {
|
|
var s *DaughterStorage
|
|
|
|
x.mtx.Lock()
|
|
|
|
{
|
|
s = x.mItems[epoch]
|
|
if s == nil {
|
|
s = &DaughterStorage{
|
|
mItems: make(map[string]*DaughterTrusts, 1),
|
|
}
|
|
|
|
x.mItems[epoch] = s
|
|
}
|
|
}
|
|
|
|
x.mtx.Unlock()
|
|
|
|
s.put(trust)
|
|
}
|
|
|
|
// DaughterTrusts returns daughter trusts for the epoch.
|
|
//
|
|
// Returns false if there is no data for the epoch and daughter.
|
|
func (x *Storage) DaughterTrusts(epoch uint64, daughter apireputation.PeerID) (*DaughterTrusts, bool) {
|
|
var (
|
|
s *DaughterStorage
|
|
ok bool
|
|
)
|
|
|
|
x.mtx.RLock()
|
|
|
|
{
|
|
s, ok = x.mItems[epoch]
|
|
}
|
|
|
|
x.mtx.RUnlock()
|
|
|
|
if !ok {
|
|
return nil, false
|
|
}
|
|
|
|
return s.daughterTrusts(daughter)
|
|
}
|
|
|
|
// AllDaughterTrusts returns daughter iterator for the epoch.
|
|
//
|
|
// Returns false if there is no data for the epoch and daughter.
|
|
func (x *Storage) AllDaughterTrusts(epoch uint64) (*DaughterStorage, bool) {
|
|
x.mtx.RLock()
|
|
defer x.mtx.RUnlock()
|
|
|
|
s, ok := x.mItems[epoch]
|
|
|
|
return s, ok
|
|
}
|
|
|
|
// DaughterStorage maps IDs of daughter peers to repositories of the local trusts to their providers.
|
|
type DaughterStorage struct {
|
|
mtx sync.RWMutex
|
|
|
|
mItems map[string]*DaughterTrusts
|
|
}
|
|
|
|
// Iterate passes IDs of the daughter peers with their trusts to h.
|
|
//
|
|
// Returns errors from h directly.
|
|
func (x *DaughterStorage) Iterate(h eigentrustcalc.PeerTrustsHandler) (err error) {
|
|
x.mtx.RLock()
|
|
|
|
{
|
|
for strDaughter, daughterTrusts := range x.mItems {
|
|
var daughter apireputation.PeerID
|
|
|
|
if strDaughter != "" {
|
|
err = daughter.DecodeString(strDaughter)
|
|
if err != nil {
|
|
panic(fmt.Sprintf("decode peer ID string %s: %v", strDaughter, err))
|
|
}
|
|
}
|
|
|
|
if err = h(daughter, daughterTrusts); err != nil {
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
x.mtx.RUnlock()
|
|
|
|
return
|
|
}
|
|
|
|
func (x *DaughterStorage) put(trust reputation.Trust) {
|
|
var dt *DaughterTrusts
|
|
|
|
x.mtx.Lock()
|
|
|
|
{
|
|
trusting := trust.TrustingPeer().EncodeToString()
|
|
|
|
dt = x.mItems[trusting]
|
|
if dt == nil {
|
|
dt = &DaughterTrusts{
|
|
mItems: make(map[string]reputation.Trust, 1),
|
|
}
|
|
|
|
x.mItems[trusting] = dt
|
|
}
|
|
}
|
|
|
|
x.mtx.Unlock()
|
|
|
|
dt.put(trust)
|
|
}
|
|
|
|
func (x *DaughterStorage) daughterTrusts(id apireputation.PeerID) (dt *DaughterTrusts, ok bool) {
|
|
x.mtx.RLock()
|
|
|
|
{
|
|
dt, ok = x.mItems[id.EncodeToString()]
|
|
}
|
|
|
|
x.mtx.RUnlock()
|
|
|
|
return
|
|
}
|
|
|
|
// DaughterTrusts represents in-memory storage of local trusts
|
|
// of the daughter peer to its providers.
|
|
//
|
|
// Maps IDs of daughter's providers to the local trusts to them.
|
|
type DaughterTrusts struct {
|
|
mtx sync.RWMutex
|
|
|
|
mItems map[string]reputation.Trust
|
|
}
|
|
|
|
func (x *DaughterTrusts) put(trust reputation.Trust) {
|
|
x.mtx.Lock()
|
|
|
|
{
|
|
x.mItems[trust.Peer().EncodeToString()] = trust
|
|
}
|
|
|
|
x.mtx.Unlock()
|
|
}
|
|
|
|
// Iterate passes all stored trusts to h.
|
|
//
|
|
// Returns errors from h directly.
|
|
func (x *DaughterTrusts) 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
|
|
}
|