decred.org/dcrdex@v1.0.5/tatanka/peer.go (about)

     1  // This code is available on the terms of the project LICENSE.md file,
     2  // also available online at https://blueoakcouncil.org/license/1.0.0.
     3  
     4  package tatanka
     5  
     6  import (
     7  	"math"
     8  	"sync"
     9  
    10  	"decred.org/dcrdex/tatanka/mj"
    11  	"decred.org/dcrdex/tatanka/tanka"
    12  )
    13  
    14  // peer represents a locally connected client.
    15  type peer struct {
    16  	tanka.Sender
    17  
    18  	mtx         sync.RWMutex
    19  	*tanka.Peer // Bonds and Reputation protected by mtx
    20  	rrs         map[tanka.PeerID]*mj.RemoteReputation
    21  }
    22  
    23  // score calculates the peer's reputation score.
    24  func (p *peer) score() int16 {
    25  	p.mtx.RLock()
    26  	defer p.mtx.RUnlock()
    27  	// If we have registered enough points ourselves, just use our score.
    28  	if len(p.Reputation.Points) == tanka.MaxReputationEntries {
    29  		return p.Reputation.Score
    30  	}
    31  	// Create a composite score. This is not an average. If we have 90 or the
    32  	// max 100 sepearate point entries, our score is weighted as 90%. The other
    33  	// 10% is taken from a poll of peers, weighted according to the number of
    34  	// points that they report.
    35  	myScoreRatio := float64(len(p.Reputation.Points)) / tanka.MaxReputationEntries
    36  	remainingScoreRatio := (tanka.MaxReputationEntries - float64(len(p.Reputation.Points))) / tanka.MaxReputationEntries
    37  	var weight int64
    38  	var ptCount uint32
    39  	for _, r := range p.rrs {
    40  		if r == nil {
    41  			continue
    42  		}
    43  		weight += int64(r.Score) * int64(r.NumPts)
    44  		ptCount += uint32(r.NumPts)
    45  	}
    46  
    47  	remoteScore := float64(weight) / float64(ptCount)
    48  	score := int64(math.Round(float64(p.Reputation.Score)*myScoreRatio + remoteScore*remainingScoreRatio))
    49  	if score > math.MaxUint16 {
    50  		score = math.MaxInt64
    51  	}
    52  	if score < -int64(math.MaxInt16) {
    53  		score = -int64(math.MaxInt16)
    54  	}
    55  	return int16(score)
    56  }
    57  
    58  // banned checks whether the peer is banned.
    59  func (p *peer) banned() bool {
    60  	p.mtx.RLock()
    61  	defer p.mtx.RUnlock()
    62  	// NEED TO CONSIDER *RemoteReputations....
    63  	tier := calcTier(p.Reputation, p.BondTier())
    64  	return tier <= 0
    65  }
    66  
    67  // bondTier is the peer's current bonded tier.
    68  func (p *peer) bondTier() uint64 {
    69  	p.mtx.RLock()
    70  	defer p.mtx.RUnlock()
    71  	return p.BondTier()
    72  }
    73  
    74  // updateBonds updates the peers bond set.
    75  func (p *peer) updateBonds(bonds []*tanka.Bond) {
    76  	p.mtx.Lock()
    77  	defer p.mtx.Unlock()
    78  	p.Bonds = bonds
    79  }
    80  
    81  type client struct {
    82  	*peer
    83  }