b23e53ea33
ScoreSettable is an interface that let caller set external scores for the heuristic. The ExternalScoreAttachment and WeightedCombAttachment heuristics implement this interface.
123 lines
3.4 KiB
Go
123 lines
3.4 KiB
Go
package autopilot
|
|
|
|
import (
|
|
"fmt"
|
|
"sync"
|
|
|
|
"github.com/btcsuite/btcutil"
|
|
)
|
|
|
|
// ExternalScoreAttachment is an implementation of the AttachmentHeuristic
|
|
// interface that allows an external source to provide it with node scores.
|
|
type ExternalScoreAttachment struct {
|
|
// TODO(halseth): persist across restarts.
|
|
nodeScores map[NodeID]float64
|
|
|
|
sync.Mutex
|
|
}
|
|
|
|
// NewExternalScoreAttachment creates a new instance of an
|
|
// ExternalScoreAttachment.
|
|
func NewExternalScoreAttachment() *ExternalScoreAttachment {
|
|
return &ExternalScoreAttachment{}
|
|
}
|
|
|
|
// A compile time assertion to ensure ExternalScoreAttachment meets the
|
|
// AttachmentHeuristic and ScoreSettable interfaces.
|
|
var _ AttachmentHeuristic = (*ExternalScoreAttachment)(nil)
|
|
var _ ScoreSettable = (*ExternalScoreAttachment)(nil)
|
|
|
|
// Name returns the name of this heuristic.
|
|
//
|
|
// NOTE: This is a part of the AttachmentHeuristic interface.
|
|
func (s *ExternalScoreAttachment) Name() string {
|
|
return "externalscore"
|
|
}
|
|
|
|
// SetNodeScores is used to set the internal map from NodeIDs to scores. The
|
|
// passed scores must be in the range [0, 1.0]. The fist parameter is the name
|
|
// of the targeted heuristic, to allow recursively target specific
|
|
// sub-heuristics. The returned boolean indicates whether the targeted
|
|
// heuristic was found.
|
|
//
|
|
// NOTE: This is a part of the ScoreSettable interface.
|
|
func (s *ExternalScoreAttachment) SetNodeScores(targetHeuristic string,
|
|
newScores map[NodeID]float64) (bool, error) {
|
|
|
|
// Return if this heuristic wasn't targeted.
|
|
if targetHeuristic != s.Name() {
|
|
return false, nil
|
|
}
|
|
|
|
// Since there's a requirement that all score are in the range [0,
|
|
// 1.0], we validate them before setting the internal list.
|
|
for nID, s := range newScores {
|
|
if s < 0 || s > 1.0 {
|
|
return false, fmt.Errorf("invalid score %v for "+
|
|
"nodeID %v", s, nID)
|
|
}
|
|
}
|
|
|
|
s.Lock()
|
|
defer s.Unlock()
|
|
|
|
s.nodeScores = newScores
|
|
return true, nil
|
|
}
|
|
|
|
// NodeScores is a method that given the current channel graph and current set
|
|
// of local channels, scores the given nodes according to the preference of
|
|
// opening a channel of the given size with them. The returned channel
|
|
// candidates maps the NodeID to a NodeScore for the node.
|
|
//
|
|
// The returned scores will be in the range [0, 1.0], where 0 indicates no
|
|
// improvement in connectivity if a channel is opened to this node, while 1.0
|
|
// is the maximum possible improvement in connectivity.
|
|
//
|
|
// The scores are determined by checking the internal node scores list. Nodes
|
|
// not known will get a score of 0.
|
|
//
|
|
// NOTE: This is a part of the AttachmentHeuristic interface.
|
|
func (s *ExternalScoreAttachment) NodeScores(g ChannelGraph, chans []Channel,
|
|
chanSize btcutil.Amount, nodes map[NodeID]struct{}) (
|
|
map[NodeID]*NodeScore, error) {
|
|
|
|
existingPeers := make(map[NodeID]struct{})
|
|
for _, c := range chans {
|
|
existingPeers[c.Node] = struct{}{}
|
|
}
|
|
|
|
s.Lock()
|
|
defer s.Unlock()
|
|
|
|
// Fill the map of candidates to return.
|
|
candidates := make(map[NodeID]*NodeScore)
|
|
for nID := range nodes {
|
|
var score float64
|
|
if nodeScore, ok := s.nodeScores[nID]; ok {
|
|
score = float64(nodeScore)
|
|
}
|
|
|
|
_, ok := existingPeers[nID]
|
|
switch {
|
|
|
|
// If the node is among or existing channel peers, we don't
|
|
// need another channel.
|
|
case ok:
|
|
continue
|
|
|
|
// Instead of adding a node with score 0 to the returned set,
|
|
// we just skip it.
|
|
case score == 0:
|
|
continue
|
|
}
|
|
|
|
candidates[nID] = &NodeScore{
|
|
NodeID: nID,
|
|
Score: score,
|
|
}
|
|
}
|
|
|
|
return candidates, nil
|
|
}
|