forked from TrueCloudLab/frostfs-node
[#473] Implement EigenTrust calculations
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
This commit is contained in:
parent
0ec8bcf6b4
commit
a97e08cfd7
14 changed files with 1112 additions and 3 deletions
189
pkg/services/reputation/eigentrust/storage/consumers/calls.go
Normal file
189
pkg/services/reputation/eigentrust/storage/consumers/calls.go
Normal file
|
@ -0,0 +1,189 @@
|
|||
package consumerstorage
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/nspcc-dev/neofs-node/pkg/services/reputation"
|
||||
"github.com/nspcc-dev/neofs-node/pkg/services/reputation/eigentrust"
|
||||
)
|
||||
|
||||
// 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 daugher 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[reputation.PeerID]*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[reputation.PeerID]*ConsumersTrusts
|
||||
}
|
||||
|
||||
func (x *ConsumersStorage) put(trust eigentrust.IterationTrust) {
|
||||
var s *ConsumersTrusts
|
||||
|
||||
x.mtx.Lock()
|
||||
|
||||
{
|
||||
daughter := trust.Peer()
|
||||
|
||||
s = x.mItems[daughter]
|
||||
if s == nil {
|
||||
s = &ConsumersTrusts{
|
||||
mItems: make(map[reputation.PeerID]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 func(trusted reputation.PeerID, consumerTrusts *ConsumersTrusts) error) (err error) {
|
||||
x.mtx.RLock()
|
||||
|
||||
{
|
||||
for trusted, trusts := range x.mItems {
|
||||
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[reputation.PeerID]reputation.Trust
|
||||
}
|
||||
|
||||
func (x *ConsumersTrusts) put(trust eigentrust.IterationTrust) {
|
||||
x.mtx.Lock()
|
||||
|
||||
{
|
||||
x.mItems[trust.TrustingPeer()] = 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
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package consumerstorage
|
||||
|
||||
import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
// Prm groups the required parameters of the Storage's constructor.
|
||||
//
|
||||
// All values must comply with the requirements imposed on them.
|
||||
// Passing incorrect parameter values will result in constructor
|
||||
// failure (error or panic depending on the implementation).
|
||||
//
|
||||
// The component is not parameterizable at the moment.
|
||||
type Prm struct{}
|
||||
|
||||
// Storage represents in-memory storage that of the trusts
|
||||
// of the consumer peers.
|
||||
//
|
||||
// It maps epoch numbers to the repositories of intermediate
|
||||
// trusts of the consumers of the daughter peers.
|
||||
//
|
||||
// For correct operation, Storage must be created
|
||||
// using the constructor (New) based on the required parameters
|
||||
// and optional components. After successful creation,
|
||||
// Storage is immediately ready to work through API.
|
||||
type Storage struct {
|
||||
mtx sync.RWMutex
|
||||
|
||||
mItems map[uint64]*iterationConsumersStorage
|
||||
}
|
||||
|
||||
// New creates a new instance of the Storage.
|
||||
//
|
||||
// The created Storage does not require additional
|
||||
// initialization and is completely ready for work.
|
||||
func New(_ Prm) *Storage {
|
||||
return &Storage{
|
||||
mItems: make(map[uint64]*iterationConsumersStorage),
|
||||
}
|
||||
}
|
134
pkg/services/reputation/eigentrust/storage/daughters/calls.go
Normal file
134
pkg/services/reputation/eigentrust/storage/daughters/calls.go
Normal file
|
@ -0,0 +1,134 @@
|
|||
package daughters
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/nspcc-dev/neofs-node/pkg/services/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[reputation.PeerID]*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 reputation.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)
|
||||
}
|
||||
|
||||
// maps IDs of daughter peers to repositories of the local trusts to their providers.
|
||||
type daughterStorage struct {
|
||||
mtx sync.RWMutex
|
||||
|
||||
mItems map[reputation.PeerID]*DaughterTrusts
|
||||
}
|
||||
|
||||
func (x *daughterStorage) put(trust reputation.Trust) {
|
||||
var dt *DaughterTrusts
|
||||
|
||||
x.mtx.Lock()
|
||||
|
||||
{
|
||||
trusting := trust.TrustingPeer()
|
||||
|
||||
dt = x.mItems[trusting]
|
||||
if dt == nil {
|
||||
dt = &DaughterTrusts{
|
||||
mItems: make(map[reputation.PeerID]reputation.Trust, 1),
|
||||
}
|
||||
|
||||
x.mItems[trusting] = dt
|
||||
}
|
||||
}
|
||||
|
||||
x.mtx.Unlock()
|
||||
|
||||
dt.put(trust)
|
||||
}
|
||||
|
||||
func (x *daughterStorage) daughterTrusts(id reputation.PeerID) (dt *DaughterTrusts, ok bool) {
|
||||
x.mtx.RLock()
|
||||
|
||||
{
|
||||
dt, ok = x.mItems[id]
|
||||
}
|
||||
|
||||
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[reputation.PeerID]reputation.Trust
|
||||
}
|
||||
|
||||
func (x *DaughterTrusts) put(trust reputation.Trust) {
|
||||
x.mtx.Lock()
|
||||
|
||||
{
|
||||
x.mItems[trust.Peer()] = 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
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package daughters
|
||||
|
||||
import "sync"
|
||||
|
||||
// Prm groups the required parameters of the Storage's constructor.
|
||||
//
|
||||
// All values must comply with the requirements imposed on them.
|
||||
// Passing incorrect parameter values will result in constructor
|
||||
// failure (error or panic depending on the implementation).
|
||||
//
|
||||
// The component is not parameterizable at the moment.
|
||||
type Prm struct{}
|
||||
|
||||
// Storage represents in-memory storage of local trust
|
||||
// values of the daughter peers.
|
||||
//
|
||||
// It maps epoch numbers to the repositories of local trusts
|
||||
// of the daughter peers.
|
||||
//
|
||||
// For correct operation, Storage must be created
|
||||
// using the constructor (New) based on the required parameters
|
||||
// and optional components. After successful creation,
|
||||
// Storage is immediately ready to work through API.
|
||||
type Storage struct {
|
||||
mtx sync.RWMutex
|
||||
|
||||
mItems map[uint64]*daughterStorage
|
||||
}
|
||||
|
||||
// New creates a new instance of the Storage.
|
||||
//
|
||||
// The created Storage does not require additional
|
||||
// initialization and is completely ready for work.
|
||||
func New(_ Prm) *Storage {
|
||||
return &Storage{
|
||||
mItems: make(map[uint64]*daughterStorage),
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue