diff --git a/autopilot/agent.go b/autopilot/agent.go index cc850357..8d346b9e 100644 --- a/autopilot/agent.go +++ b/autopilot/agent.go @@ -768,3 +768,55 @@ func (a *Agent) executeDirective(directive AttachmentDirective) { // we'll trigger the autopilot agent to query for more peers. a.OnChannelPendingOpen() } + +// HeuristicScores is an alias for a map that maps heuristic names to a map of +// scores for pubkeys. +type HeuristicScores map[string]map[NodeID]float64 + +// queryHeuristics gets node scores from all available simple heuristics, and +// the agent's current active heuristic. +func (a *Agent) queryHeuristics(nodes map[NodeID]struct{}) ( + HeuristicScores, error) { + + // Get the agent's current channel state. + a.chanStateMtx.Lock() + a.pendingMtx.Lock() + totalChans := mergeChanState(a.pendingOpens, a.chanState) + a.pendingMtx.Unlock() + a.chanStateMtx.Unlock() + + // As channel size we'll use the maximum size. + chanSize := a.cfg.Constraints.MaxChanSize() + + // We'll start by getting the scores from each available sub-heuristic, + // in addition the active agent heuristic. + report := make(HeuristicScores) + for _, h := range append(availableHeuristics, a.cfg.Heuristic) { + name := h.Name() + + // If the active agent heuristic is among the simple heuristics + // it might get queried more than once. As an optimization + // we'll just skip it the second time. + if _, ok := report[name]; ok { + continue + } + + s, err := h.NodeScores( + a.cfg.Graph, totalChans, chanSize, nodes, + ) + if err != nil { + return nil, fmt.Errorf("unable to get sub score: %v", err) + } + + log.Debugf("Heuristic \"%v\" scored %d nodes", name, len(s)) + + scores := make(map[NodeID]float64) + for nID, score := range s { + scores[nID] = score.Score + } + + report[name] = scores + } + + return report, nil +}