autopilot: "Look ma no hands!", introducing autopilot mode
This commit introduces the initial implementation of the autopilot
mode. Autopilot is new mode within lnd that enables automatic channel
management. This means that if enabled lnd will attempt to
automatically manage channels according to a set of heuristic defined
within the main configuration for autopilot.Agent instance.
The autopilot.Agent implements a simple closed control loop. It takes
in external signals such as wallet balance updates, new open channel,
and channels that are now closed the updates its internal state. With
each external trigger it will consult the registered
AttachmentHeuristic to decide: if it needs to open any more channels,
and if so how much it should use to open the channels, ultimately
returning a set of recommended AttachmentDirectives. The
autopilot.Agent loop will then take those attempt to establish
connection, and go back in waiting for a new external signal.
With this first implementation the default heuristic is the
ConstrainedPrefAttachment implementation of AttachmentHeuristic. Given
a min and max channel size, a limit on the number of channels, and the
percentage of wallet funds to allocate to channels, it will attempt to
execute a heuristic drive by the Barabási–Albert model model in order
to attempt to drive the global graph towards a scale free topology.
This is commit implements a foundational layer for future simulations,
optimization, and additional heuristics.
2017-08-11 07:14:41 +03:00
|
|
|
|
package autopilot
|
|
|
|
|
|
|
|
|
|
import (
|
2018-08-30 01:44:26 +03:00
|
|
|
|
"bytes"
|
autopilot: "Look ma no hands!", introducing autopilot mode
This commit introduces the initial implementation of the autopilot
mode. Autopilot is new mode within lnd that enables automatic channel
management. This means that if enabled lnd will attempt to
automatically manage channels according to a set of heuristic defined
within the main configuration for autopilot.Agent instance.
The autopilot.Agent implements a simple closed control loop. It takes
in external signals such as wallet balance updates, new open channel,
and channels that are now closed the updates its internal state. With
each external trigger it will consult the registered
AttachmentHeuristic to decide: if it needs to open any more channels,
and if so how much it should use to open the channels, ultimately
returning a set of recommended AttachmentDirectives. The
autopilot.Agent loop will then take those attempt to establish
connection, and go back in waiting for a new external signal.
With this first implementation the default heuristic is the
ConstrainedPrefAttachment implementation of AttachmentHeuristic. Given
a min and max channel size, a limit on the number of channels, and the
percentage of wallet funds to allocate to channels, it will attempt to
execute a heuristic drive by the Barabási–Albert model model in order
to attempt to drive the global graph towards a scale free topology.
This is commit implements a foundational layer for future simulations,
optimization, and additional heuristics.
2017-08-11 07:14:41 +03:00
|
|
|
|
"fmt"
|
|
|
|
|
prand "math/rand"
|
2018-11-23 01:18:09 +03:00
|
|
|
|
"net"
|
autopilot: "Look ma no hands!", introducing autopilot mode
This commit introduces the initial implementation of the autopilot
mode. Autopilot is new mode within lnd that enables automatic channel
management. This means that if enabled lnd will attempt to
automatically manage channels according to a set of heuristic defined
within the main configuration for autopilot.Agent instance.
The autopilot.Agent implements a simple closed control loop. It takes
in external signals such as wallet balance updates, new open channel,
and channels that are now closed the updates its internal state. With
each external trigger it will consult the registered
AttachmentHeuristic to decide: if it needs to open any more channels,
and if so how much it should use to open the channels, ultimately
returning a set of recommended AttachmentDirectives. The
autopilot.Agent loop will then take those attempt to establish
connection, and go back in waiting for a new external signal.
With this first implementation the default heuristic is the
ConstrainedPrefAttachment implementation of AttachmentHeuristic. Given
a min and max channel size, a limit on the number of channels, and the
percentage of wallet funds to allocate to channels, it will attempt to
execute a heuristic drive by the Barabási–Albert model model in order
to attempt to drive the global graph towards a scale free topology.
This is commit implements a foundational layer for future simulations,
optimization, and additional heuristics.
2017-08-11 07:14:41 +03:00
|
|
|
|
"time"
|
|
|
|
|
|
2018-06-05 04:34:16 +03:00
|
|
|
|
"github.com/btcsuite/btcd/btcec"
|
|
|
|
|
"github.com/btcsuite/btcutil"
|
autopilot: "Look ma no hands!", introducing autopilot mode
This commit introduces the initial implementation of the autopilot
mode. Autopilot is new mode within lnd that enables automatic channel
management. This means that if enabled lnd will attempt to
automatically manage channels according to a set of heuristic defined
within the main configuration for autopilot.Agent instance.
The autopilot.Agent implements a simple closed control loop. It takes
in external signals such as wallet balance updates, new open channel,
and channels that are now closed the updates its internal state. With
each external trigger it will consult the registered
AttachmentHeuristic to decide: if it needs to open any more channels,
and if so how much it should use to open the channels, ultimately
returning a set of recommended AttachmentDirectives. The
autopilot.Agent loop will then take those attempt to establish
connection, and go back in waiting for a new external signal.
With this first implementation the default heuristic is the
ConstrainedPrefAttachment implementation of AttachmentHeuristic. Given
a min and max channel size, a limit on the number of channels, and the
percentage of wallet funds to allocate to channels, it will attempt to
execute a heuristic drive by the Barabási–Albert model model in order
to attempt to drive the global graph towards a scale free topology.
This is commit implements a foundational layer for future simulations,
optimization, and additional heuristics.
2017-08-11 07:14:41 +03:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// ConstrainedPrefAttachment is an implementation of the AttachmentHeuristic
|
|
|
|
|
// interface that implement a constrained non-linear preferential attachment
|
|
|
|
|
// heuristic. This means that given a threshold to allocate to automatic
|
|
|
|
|
// channel establishment, the heuristic will attempt to favor connecting to
|
|
|
|
|
// nodes which already have a set amount of links, selected by sampling from a
|
2018-10-09 19:28:34 +03:00
|
|
|
|
// power law distribution. The attachment is non-linear in that it favors
|
autopilot: "Look ma no hands!", introducing autopilot mode
This commit introduces the initial implementation of the autopilot
mode. Autopilot is new mode within lnd that enables automatic channel
management. This means that if enabled lnd will attempt to
automatically manage channels according to a set of heuristic defined
within the main configuration for autopilot.Agent instance.
The autopilot.Agent implements a simple closed control loop. It takes
in external signals such as wallet balance updates, new open channel,
and channels that are now closed the updates its internal state. With
each external trigger it will consult the registered
AttachmentHeuristic to decide: if it needs to open any more channels,
and if so how much it should use to open the channels, ultimately
returning a set of recommended AttachmentDirectives. The
autopilot.Agent loop will then take those attempt to establish
connection, and go back in waiting for a new external signal.
With this first implementation the default heuristic is the
ConstrainedPrefAttachment implementation of AttachmentHeuristic. Given
a min and max channel size, a limit on the number of channels, and the
percentage of wallet funds to allocate to channels, it will attempt to
execute a heuristic drive by the Barabási–Albert model model in order
to attempt to drive the global graph towards a scale free topology.
This is commit implements a foundational layer for future simulations,
optimization, and additional heuristics.
2017-08-11 07:14:41 +03:00
|
|
|
|
// nodes with a higher in-degree but less so that regular linear preferential
|
|
|
|
|
// attachment. As a result, this creates smaller and less clusters than regular
|
|
|
|
|
// linear preferential attachment.
|
|
|
|
|
//
|
|
|
|
|
// TODO(roasbeef): BA, with k=-3
|
|
|
|
|
type ConstrainedPrefAttachment struct {
|
2018-11-23 01:18:08 +03:00
|
|
|
|
constraints *HeuristicConstraints
|
autopilot: "Look ma no hands!", introducing autopilot mode
This commit introduces the initial implementation of the autopilot
mode. Autopilot is new mode within lnd that enables automatic channel
management. This means that if enabled lnd will attempt to
automatically manage channels according to a set of heuristic defined
within the main configuration for autopilot.Agent instance.
The autopilot.Agent implements a simple closed control loop. It takes
in external signals such as wallet balance updates, new open channel,
and channels that are now closed the updates its internal state. With
each external trigger it will consult the registered
AttachmentHeuristic to decide: if it needs to open any more channels,
and if so how much it should use to open the channels, ultimately
returning a set of recommended AttachmentDirectives. The
autopilot.Agent loop will then take those attempt to establish
connection, and go back in waiting for a new external signal.
With this first implementation the default heuristic is the
ConstrainedPrefAttachment implementation of AttachmentHeuristic. Given
a min and max channel size, a limit on the number of channels, and the
percentage of wallet funds to allocate to channels, it will attempt to
execute a heuristic drive by the Barabási–Albert model model in order
to attempt to drive the global graph towards a scale free topology.
This is commit implements a foundational layer for future simulations,
optimization, and additional heuristics.
2017-08-11 07:14:41 +03:00
|
|
|
|
}
|
|
|
|
|
|
2017-08-11 08:07:15 +03:00
|
|
|
|
// NewConstrainedPrefAttachment creates a new instance of a
|
|
|
|
|
// ConstrainedPrefAttachment heuristics given bounds on allowed channel sizes,
|
|
|
|
|
// and an allocation amount which is interpreted as a percentage of funds that
|
|
|
|
|
// is to be committed to channels at all times.
|
2018-11-23 01:18:08 +03:00
|
|
|
|
func NewConstrainedPrefAttachment(
|
|
|
|
|
cfg *HeuristicConstraints) *ConstrainedPrefAttachment {
|
autopilot: "Look ma no hands!", introducing autopilot mode
This commit introduces the initial implementation of the autopilot
mode. Autopilot is new mode within lnd that enables automatic channel
management. This means that if enabled lnd will attempt to
automatically manage channels according to a set of heuristic defined
within the main configuration for autopilot.Agent instance.
The autopilot.Agent implements a simple closed control loop. It takes
in external signals such as wallet balance updates, new open channel,
and channels that are now closed the updates its internal state. With
each external trigger it will consult the registered
AttachmentHeuristic to decide: if it needs to open any more channels,
and if so how much it should use to open the channels, ultimately
returning a set of recommended AttachmentDirectives. The
autopilot.Agent loop will then take those attempt to establish
connection, and go back in waiting for a new external signal.
With this first implementation the default heuristic is the
ConstrainedPrefAttachment implementation of AttachmentHeuristic. Given
a min and max channel size, a limit on the number of channels, and the
percentage of wallet funds to allocate to channels, it will attempt to
execute a heuristic drive by the Barabási–Albert model model in order
to attempt to drive the global graph towards a scale free topology.
This is commit implements a foundational layer for future simulations,
optimization, and additional heuristics.
2017-08-11 07:14:41 +03:00
|
|
|
|
|
|
|
|
|
prand.Seed(time.Now().Unix())
|
|
|
|
|
|
|
|
|
|
return &ConstrainedPrefAttachment{
|
2018-11-23 01:18:08 +03:00
|
|
|
|
constraints: cfg,
|
autopilot: "Look ma no hands!", introducing autopilot mode
This commit introduces the initial implementation of the autopilot
mode. Autopilot is new mode within lnd that enables automatic channel
management. This means that if enabled lnd will attempt to
automatically manage channels according to a set of heuristic defined
within the main configuration for autopilot.Agent instance.
The autopilot.Agent implements a simple closed control loop. It takes
in external signals such as wallet balance updates, new open channel,
and channels that are now closed the updates its internal state. With
each external trigger it will consult the registered
AttachmentHeuristic to decide: if it needs to open any more channels,
and if so how much it should use to open the channels, ultimately
returning a set of recommended AttachmentDirectives. The
autopilot.Agent loop will then take those attempt to establish
connection, and go back in waiting for a new external signal.
With this first implementation the default heuristic is the
ConstrainedPrefAttachment implementation of AttachmentHeuristic. Given
a min and max channel size, a limit on the number of channels, and the
percentage of wallet funds to allocate to channels, it will attempt to
execute a heuristic drive by the Barabási–Albert model model in order
to attempt to drive the global graph towards a scale free topology.
This is commit implements a foundational layer for future simulations,
optimization, and additional heuristics.
2017-08-11 07:14:41 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// A compile time assertion to ensure ConstrainedPrefAttachment meets the
|
|
|
|
|
// AttachmentHeuristic interface.
|
|
|
|
|
var _ AttachmentHeuristic = (*ConstrainedPrefAttachment)(nil)
|
|
|
|
|
|
|
|
|
|
// NeedMoreChans is a predicate that should return true if, given the passed
|
|
|
|
|
// parameters, and its internal state, more channels should be opened within
|
|
|
|
|
// the channel graph. If the heuristic decides that we do indeed need more
|
|
|
|
|
// channels, then the second argument returned will represent the amount of
|
|
|
|
|
// additional funds to be used towards creating channels.
|
|
|
|
|
//
|
|
|
|
|
// NOTE: This is a part of the AttachmentHeuristic interface.
|
|
|
|
|
func (p *ConstrainedPrefAttachment) NeedMoreChans(channels []Channel,
|
2018-02-09 07:06:57 +03:00
|
|
|
|
funds btcutil.Amount) (btcutil.Amount, uint32, bool) {
|
autopilot: "Look ma no hands!", introducing autopilot mode
This commit introduces the initial implementation of the autopilot
mode. Autopilot is new mode within lnd that enables automatic channel
management. This means that if enabled lnd will attempt to
automatically manage channels according to a set of heuristic defined
within the main configuration for autopilot.Agent instance.
The autopilot.Agent implements a simple closed control loop. It takes
in external signals such as wallet balance updates, new open channel,
and channels that are now closed the updates its internal state. With
each external trigger it will consult the registered
AttachmentHeuristic to decide: if it needs to open any more channels,
and if so how much it should use to open the channels, ultimately
returning a set of recommended AttachmentDirectives. The
autopilot.Agent loop will then take those attempt to establish
connection, and go back in waiting for a new external signal.
With this first implementation the default heuristic is the
ConstrainedPrefAttachment implementation of AttachmentHeuristic. Given
a min and max channel size, a limit on the number of channels, and the
percentage of wallet funds to allocate to channels, it will attempt to
execute a heuristic drive by the Barabási–Albert model model in order
to attempt to drive the global graph towards a scale free topology.
This is commit implements a foundational layer for future simulations,
optimization, and additional heuristics.
2017-08-11 07:14:41 +03:00
|
|
|
|
|
2018-11-23 01:18:08 +03:00
|
|
|
|
// We'll try to open more channels as long as the constraints allow it.
|
|
|
|
|
availableFunds, availableChans := p.constraints.availableChans(
|
|
|
|
|
channels, funds,
|
|
|
|
|
)
|
|
|
|
|
return availableFunds, availableChans, availableChans > 0
|
autopilot: "Look ma no hands!", introducing autopilot mode
This commit introduces the initial implementation of the autopilot
mode. Autopilot is new mode within lnd that enables automatic channel
management. This means that if enabled lnd will attempt to
automatically manage channels according to a set of heuristic defined
within the main configuration for autopilot.Agent instance.
The autopilot.Agent implements a simple closed control loop. It takes
in external signals such as wallet balance updates, new open channel,
and channels that are now closed the updates its internal state. With
each external trigger it will consult the registered
AttachmentHeuristic to decide: if it needs to open any more channels,
and if so how much it should use to open the channels, ultimately
returning a set of recommended AttachmentDirectives. The
autopilot.Agent loop will then take those attempt to establish
connection, and go back in waiting for a new external signal.
With this first implementation the default heuristic is the
ConstrainedPrefAttachment implementation of AttachmentHeuristic. Given
a min and max channel size, a limit on the number of channels, and the
percentage of wallet funds to allocate to channels, it will attempt to
execute a heuristic drive by the Barabási–Albert model model in order
to attempt to drive the global graph towards a scale free topology.
This is commit implements a foundational layer for future simulations,
optimization, and additional heuristics.
2017-08-11 07:14:41 +03:00
|
|
|
|
}
|
|
|
|
|
|
2018-04-18 05:02:04 +03:00
|
|
|
|
// NodeID is a simple type that holds an EC public key serialized in compressed
|
autopilot: "Look ma no hands!", introducing autopilot mode
This commit introduces the initial implementation of the autopilot
mode. Autopilot is new mode within lnd that enables automatic channel
management. This means that if enabled lnd will attempt to
automatically manage channels according to a set of heuristic defined
within the main configuration for autopilot.Agent instance.
The autopilot.Agent implements a simple closed control loop. It takes
in external signals such as wallet balance updates, new open channel,
and channels that are now closed the updates its internal state. With
each external trigger it will consult the registered
AttachmentHeuristic to decide: if it needs to open any more channels,
and if so how much it should use to open the channels, ultimately
returning a set of recommended AttachmentDirectives. The
autopilot.Agent loop will then take those attempt to establish
connection, and go back in waiting for a new external signal.
With this first implementation the default heuristic is the
ConstrainedPrefAttachment implementation of AttachmentHeuristic. Given
a min and max channel size, a limit on the number of channels, and the
percentage of wallet funds to allocate to channels, it will attempt to
execute a heuristic drive by the Barabási–Albert model model in order
to attempt to drive the global graph towards a scale free topology.
This is commit implements a foundational layer for future simulations,
optimization, and additional heuristics.
2017-08-11 07:14:41 +03:00
|
|
|
|
// format.
|
|
|
|
|
type NodeID [33]byte
|
|
|
|
|
|
|
|
|
|
// NewNodeID creates a new nodeID from a passed public key.
|
|
|
|
|
func NewNodeID(pub *btcec.PublicKey) NodeID {
|
|
|
|
|
var n NodeID
|
|
|
|
|
copy(n[:], pub.SerializeCompressed())
|
|
|
|
|
return n
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-31 04:55:48 +03:00
|
|
|
|
// shuffleCandidates shuffles the set of candidate nodes for preferential
|
|
|
|
|
// attachment in order to break any ordering already enforced by the sorted
|
|
|
|
|
// order of the public key for each node. To shuffle the set of candidates, we
|
|
|
|
|
// use a version of the Fisher–Yates shuffle algorithm.
|
|
|
|
|
func shuffleCandidates(candidates []Node) []Node {
|
|
|
|
|
shuffledNodes := make([]Node, len(candidates))
|
|
|
|
|
perm := prand.Perm(len(candidates))
|
|
|
|
|
|
|
|
|
|
for i, v := range perm {
|
|
|
|
|
shuffledNodes[v] = candidates[i]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return shuffledNodes
|
|
|
|
|
}
|
|
|
|
|
|
autopilot: "Look ma no hands!", introducing autopilot mode
This commit introduces the initial implementation of the autopilot
mode. Autopilot is new mode within lnd that enables automatic channel
management. This means that if enabled lnd will attempt to
automatically manage channels according to a set of heuristic defined
within the main configuration for autopilot.Agent instance.
The autopilot.Agent implements a simple closed control loop. It takes
in external signals such as wallet balance updates, new open channel,
and channels that are now closed the updates its internal state. With
each external trigger it will consult the registered
AttachmentHeuristic to decide: if it needs to open any more channels,
and if so how much it should use to open the channels, ultimately
returning a set of recommended AttachmentDirectives. The
autopilot.Agent loop will then take those attempt to establish
connection, and go back in waiting for a new external signal.
With this first implementation the default heuristic is the
ConstrainedPrefAttachment implementation of AttachmentHeuristic. Given
a min and max channel size, a limit on the number of channels, and the
percentage of wallet funds to allocate to channels, it will attempt to
execute a heuristic drive by the Barabási–Albert model model in order
to attempt to drive the global graph towards a scale free topology.
This is commit implements a foundational layer for future simulations,
optimization, and additional heuristics.
2017-08-11 07:14:41 +03:00
|
|
|
|
// Select returns a candidate set of attachment directives that should be
|
|
|
|
|
// executed based on the current internal state, the state of the channel
|
|
|
|
|
// graph, the set of nodes we should exclude, and the amount of funds
|
|
|
|
|
// available. The heuristic employed by this method is one that attempts to
|
|
|
|
|
// promote a scale-free network globally, via local attachment preferences for
|
|
|
|
|
// new nodes joining the network with an amount of available funds to be
|
|
|
|
|
// allocated to channels. Specifically, we consider the degree of each node
|
|
|
|
|
// (and the flow in/out of the node available via its open channels) and
|
|
|
|
|
// utilize the Barabási–Albert model to drive our recommended attachment
|
|
|
|
|
// heuristics. If implemented globally for each new participant, this results
|
|
|
|
|
// in a channel graph that is scale-free and follows a power law distribution
|
|
|
|
|
// with k=-3.
|
|
|
|
|
//
|
|
|
|
|
// NOTE: This is a part of the AttachmentHeuristic interface.
|
|
|
|
|
func (p *ConstrainedPrefAttachment) Select(self *btcec.PublicKey, g ChannelGraph,
|
2018-02-09 07:06:57 +03:00
|
|
|
|
fundsAvailable btcutil.Amount, numNewChans uint32,
|
2017-08-22 08:24:35 +03:00
|
|
|
|
skipNodes map[NodeID]struct{}) ([]AttachmentDirective, error) {
|
autopilot: "Look ma no hands!", introducing autopilot mode
This commit introduces the initial implementation of the autopilot
mode. Autopilot is new mode within lnd that enables automatic channel
management. This means that if enabled lnd will attempt to
automatically manage channels according to a set of heuristic defined
within the main configuration for autopilot.Agent instance.
The autopilot.Agent implements a simple closed control loop. It takes
in external signals such as wallet balance updates, new open channel,
and channels that are now closed the updates its internal state. With
each external trigger it will consult the registered
AttachmentHeuristic to decide: if it needs to open any more channels,
and if so how much it should use to open the channels, ultimately
returning a set of recommended AttachmentDirectives. The
autopilot.Agent loop will then take those attempt to establish
connection, and go back in waiting for a new external signal.
With this first implementation the default heuristic is the
ConstrainedPrefAttachment implementation of AttachmentHeuristic. Given
a min and max channel size, a limit on the number of channels, and the
percentage of wallet funds to allocate to channels, it will attempt to
execute a heuristic drive by the Barabási–Albert model model in order
to attempt to drive the global graph towards a scale free topology.
This is commit implements a foundational layer for future simulations,
optimization, and additional heuristics.
2017-08-11 07:14:41 +03:00
|
|
|
|
|
|
|
|
|
// TODO(roasbeef): rename?
|
|
|
|
|
|
|
|
|
|
var directives []AttachmentDirective
|
|
|
|
|
|
2018-11-23 01:18:08 +03:00
|
|
|
|
if fundsAvailable < p.constraints.MinChanSize {
|
autopilot: "Look ma no hands!", introducing autopilot mode
This commit introduces the initial implementation of the autopilot
mode. Autopilot is new mode within lnd that enables automatic channel
management. This means that if enabled lnd will attempt to
automatically manage channels according to a set of heuristic defined
within the main configuration for autopilot.Agent instance.
The autopilot.Agent implements a simple closed control loop. It takes
in external signals such as wallet balance updates, new open channel,
and channels that are now closed the updates its internal state. With
each external trigger it will consult the registered
AttachmentHeuristic to decide: if it needs to open any more channels,
and if so how much it should use to open the channels, ultimately
returning a set of recommended AttachmentDirectives. The
autopilot.Agent loop will then take those attempt to establish
connection, and go back in waiting for a new external signal.
With this first implementation the default heuristic is the
ConstrainedPrefAttachment implementation of AttachmentHeuristic. Given
a min and max channel size, a limit on the number of channels, and the
percentage of wallet funds to allocate to channels, it will attempt to
execute a heuristic drive by the Barabási–Albert model model in order
to attempt to drive the global graph towards a scale free topology.
This is commit implements a foundational layer for future simulations,
optimization, and additional heuristics.
2017-08-11 07:14:41 +03:00
|
|
|
|
return directives, nil
|
|
|
|
|
}
|
|
|
|
|
|
2018-08-30 01:44:26 +03:00
|
|
|
|
selfPubBytes := self.SerializeCompressed()
|
|
|
|
|
|
autopilot: "Look ma no hands!", introducing autopilot mode
This commit introduces the initial implementation of the autopilot
mode. Autopilot is new mode within lnd that enables automatic channel
management. This means that if enabled lnd will attempt to
automatically manage channels according to a set of heuristic defined
within the main configuration for autopilot.Agent instance.
The autopilot.Agent implements a simple closed control loop. It takes
in external signals such as wallet balance updates, new open channel,
and channels that are now closed the updates its internal state. With
each external trigger it will consult the registered
AttachmentHeuristic to decide: if it needs to open any more channels,
and if so how much it should use to open the channels, ultimately
returning a set of recommended AttachmentDirectives. The
autopilot.Agent loop will then take those attempt to establish
connection, and go back in waiting for a new external signal.
With this first implementation the default heuristic is the
ConstrainedPrefAttachment implementation of AttachmentHeuristic. Given
a min and max channel size, a limit on the number of channels, and the
percentage of wallet funds to allocate to channels, it will attempt to
execute a heuristic drive by the Barabási–Albert model model in order
to attempt to drive the global graph towards a scale free topology.
This is commit implements a foundational layer for future simulations,
optimization, and additional heuristics.
2017-08-11 07:14:41 +03:00
|
|
|
|
// We'll continue our attachment loop until we've exhausted the current
|
|
|
|
|
// amount of available funds.
|
|
|
|
|
visited := make(map[NodeID]struct{})
|
2018-02-09 07:06:57 +03:00
|
|
|
|
for i := uint32(0); i < numNewChans; i++ {
|
autopilot: "Look ma no hands!", introducing autopilot mode
This commit introduces the initial implementation of the autopilot
mode. Autopilot is new mode within lnd that enables automatic channel
management. This means that if enabled lnd will attempt to
automatically manage channels according to a set of heuristic defined
within the main configuration for autopilot.Agent instance.
The autopilot.Agent implements a simple closed control loop. It takes
in external signals such as wallet balance updates, new open channel,
and channels that are now closed the updates its internal state. With
each external trigger it will consult the registered
AttachmentHeuristic to decide: if it needs to open any more channels,
and if so how much it should use to open the channels, ultimately
returning a set of recommended AttachmentDirectives. The
autopilot.Agent loop will then take those attempt to establish
connection, and go back in waiting for a new external signal.
With this first implementation the default heuristic is the
ConstrainedPrefAttachment implementation of AttachmentHeuristic. Given
a min and max channel size, a limit on the number of channels, and the
percentage of wallet funds to allocate to channels, it will attempt to
execute a heuristic drive by the Barabási–Albert model model in order
to attempt to drive the global graph towards a scale free topology.
This is commit implements a foundational layer for future simulations,
optimization, and additional heuristics.
2017-08-11 07:14:41 +03:00
|
|
|
|
// selectionSlice will be used to randomly select a node
|
|
|
|
|
// according to a power law distribution. For each connected
|
|
|
|
|
// edge, we'll add an instance of the node to this slice. Thus,
|
|
|
|
|
// for a given node, the probability that we'll attach to it
|
|
|
|
|
// is: k_i / sum(k_j), where k_i is the degree of the target
|
|
|
|
|
// node, and k_j is the degree of all other nodes i != j. This
|
|
|
|
|
// implements the classic Barabási–Albert model for
|
|
|
|
|
// preferential attachment.
|
|
|
|
|
var selectionSlice []Node
|
|
|
|
|
|
|
|
|
|
// For each node, and each channel that the node has, we'll add
|
|
|
|
|
// an instance of that node to the selection slice above.
|
|
|
|
|
// This'll slice where the frequency of each node is equivalent
|
|
|
|
|
// to the number of channels that connect to it.
|
|
|
|
|
//
|
|
|
|
|
// TODO(roasbeef): add noise to make adversarially resistant?
|
|
|
|
|
if err := g.ForEachNode(func(node Node) error {
|
2018-08-30 01:44:26 +03:00
|
|
|
|
nID := NodeID(node.PubKey())
|
autopilot: "Look ma no hands!", introducing autopilot mode
This commit introduces the initial implementation of the autopilot
mode. Autopilot is new mode within lnd that enables automatic channel
management. This means that if enabled lnd will attempt to
automatically manage channels according to a set of heuristic defined
within the main configuration for autopilot.Agent instance.
The autopilot.Agent implements a simple closed control loop. It takes
in external signals such as wallet balance updates, new open channel,
and channels that are now closed the updates its internal state. With
each external trigger it will consult the registered
AttachmentHeuristic to decide: if it needs to open any more channels,
and if so how much it should use to open the channels, ultimately
returning a set of recommended AttachmentDirectives. The
autopilot.Agent loop will then take those attempt to establish
connection, and go back in waiting for a new external signal.
With this first implementation the default heuristic is the
ConstrainedPrefAttachment implementation of AttachmentHeuristic. Given
a min and max channel size, a limit on the number of channels, and the
percentage of wallet funds to allocate to channels, it will attempt to
execute a heuristic drive by the Barabási–Albert model model in order
to attempt to drive the global graph towards a scale free topology.
This is commit implements a foundational layer for future simulations,
optimization, and additional heuristics.
2017-08-11 07:14:41 +03:00
|
|
|
|
|
|
|
|
|
// Once a node has already been attached to, we'll
|
|
|
|
|
// ensure that it isn't factored into any further
|
|
|
|
|
// decisions within this round.
|
|
|
|
|
if _, ok := visited[nID]; ok {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If we come across ourselves, them we'll continue in
|
|
|
|
|
// order to avoid attempting to make a channel with
|
|
|
|
|
// ourselves.
|
2018-08-30 01:44:26 +03:00
|
|
|
|
if bytes.Equal(nID[:], selfPubBytes) {
|
autopilot: "Look ma no hands!", introducing autopilot mode
This commit introduces the initial implementation of the autopilot
mode. Autopilot is new mode within lnd that enables automatic channel
management. This means that if enabled lnd will attempt to
automatically manage channels according to a set of heuristic defined
within the main configuration for autopilot.Agent instance.
The autopilot.Agent implements a simple closed control loop. It takes
in external signals such as wallet balance updates, new open channel,
and channels that are now closed the updates its internal state. With
each external trigger it will consult the registered
AttachmentHeuristic to decide: if it needs to open any more channels,
and if so how much it should use to open the channels, ultimately
returning a set of recommended AttachmentDirectives. The
autopilot.Agent loop will then take those attempt to establish
connection, and go back in waiting for a new external signal.
With this first implementation the default heuristic is the
ConstrainedPrefAttachment implementation of AttachmentHeuristic. Given
a min and max channel size, a limit on the number of channels, and the
percentage of wallet funds to allocate to channels, it will attempt to
execute a heuristic drive by the Barabási–Albert model model in order
to attempt to drive the global graph towards a scale free topology.
This is commit implements a foundational layer for future simulations,
optimization, and additional heuristics.
2017-08-11 07:14:41 +03:00
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2018-10-09 19:28:34 +03:00
|
|
|
|
// Additionally, if this node is in the blacklist, then
|
autopilot: "Look ma no hands!", introducing autopilot mode
This commit introduces the initial implementation of the autopilot
mode. Autopilot is new mode within lnd that enables automatic channel
management. This means that if enabled lnd will attempt to
automatically manage channels according to a set of heuristic defined
within the main configuration for autopilot.Agent instance.
The autopilot.Agent implements a simple closed control loop. It takes
in external signals such as wallet balance updates, new open channel,
and channels that are now closed the updates its internal state. With
each external trigger it will consult the registered
AttachmentHeuristic to decide: if it needs to open any more channels,
and if so how much it should use to open the channels, ultimately
returning a set of recommended AttachmentDirectives. The
autopilot.Agent loop will then take those attempt to establish
connection, and go back in waiting for a new external signal.
With this first implementation the default heuristic is the
ConstrainedPrefAttachment implementation of AttachmentHeuristic. Given
a min and max channel size, a limit on the number of channels, and the
percentage of wallet funds to allocate to channels, it will attempt to
execute a heuristic drive by the Barabási–Albert model model in order
to attempt to drive the global graph towards a scale free topology.
This is commit implements a foundational layer for future simulations,
optimization, and additional heuristics.
2017-08-11 07:14:41 +03:00
|
|
|
|
// we'll skip it.
|
|
|
|
|
if _, ok := skipNodes[nID]; ok {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// For initial bootstrap purposes, if a node doesn't
|
|
|
|
|
// have any channels, then we'll ensure that it has at
|
|
|
|
|
// least one item in the selection slice.
|
|
|
|
|
//
|
|
|
|
|
// TODO(roasbeef): make conditional?
|
|
|
|
|
selectionSlice = append(selectionSlice, node)
|
|
|
|
|
|
|
|
|
|
// For each active channel the node has, we'll add an
|
|
|
|
|
// additional channel to the selection slice to
|
|
|
|
|
// increase their weight.
|
|
|
|
|
if err := node.ForEachChannel(func(channel ChannelEdge) error {
|
|
|
|
|
selectionSlice = append(selectionSlice, node)
|
|
|
|
|
return nil
|
|
|
|
|
}); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}); err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If no nodes at all were accumulated, then we'll exit early
|
|
|
|
|
// as there are no eligible candidates.
|
|
|
|
|
if len(selectionSlice) == 0 {
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Given our selection slice, we'll now generate a random index
|
|
|
|
|
// into this slice. The node we select will be recommended by
|
|
|
|
|
// us to create a channel to.
|
2017-10-31 04:55:48 +03:00
|
|
|
|
candidates := shuffleCandidates(selectionSlice)
|
|
|
|
|
selectedIndex := prand.Int31n(int32(len(candidates)))
|
|
|
|
|
selectedNode := candidates[selectedIndex]
|
autopilot: "Look ma no hands!", introducing autopilot mode
This commit introduces the initial implementation of the autopilot
mode. Autopilot is new mode within lnd that enables automatic channel
management. This means that if enabled lnd will attempt to
automatically manage channels according to a set of heuristic defined
within the main configuration for autopilot.Agent instance.
The autopilot.Agent implements a simple closed control loop. It takes
in external signals such as wallet balance updates, new open channel,
and channels that are now closed the updates its internal state. With
each external trigger it will consult the registered
AttachmentHeuristic to decide: if it needs to open any more channels,
and if so how much it should use to open the channels, ultimately
returning a set of recommended AttachmentDirectives. The
autopilot.Agent loop will then take those attempt to establish
connection, and go back in waiting for a new external signal.
With this first implementation the default heuristic is the
ConstrainedPrefAttachment implementation of AttachmentHeuristic. Given
a min and max channel size, a limit on the number of channels, and the
percentage of wallet funds to allocate to channels, it will attempt to
execute a heuristic drive by the Barabási–Albert model model in order
to attempt to drive the global graph towards a scale free topology.
This is commit implements a foundational layer for future simulations,
optimization, and additional heuristics.
2017-08-11 07:14:41 +03:00
|
|
|
|
|
|
|
|
|
// TODO(roasbeef): cap on num channels to same participant?
|
|
|
|
|
|
|
|
|
|
// With the node selected, we'll add this (node, amount) tuple
|
|
|
|
|
// to out set of recommended directives.
|
2018-08-30 01:44:26 +03:00
|
|
|
|
pubBytes := selectedNode.PubKey()
|
2018-12-06 15:59:46 +03:00
|
|
|
|
nID := NodeID(pubBytes)
|
autopilot: "Look ma no hands!", introducing autopilot mode
This commit introduces the initial implementation of the autopilot
mode. Autopilot is new mode within lnd that enables automatic channel
management. This means that if enabled lnd will attempt to
automatically manage channels according to a set of heuristic defined
within the main configuration for autopilot.Agent instance.
The autopilot.Agent implements a simple closed control loop. It takes
in external signals such as wallet balance updates, new open channel,
and channels that are now closed the updates its internal state. With
each external trigger it will consult the registered
AttachmentHeuristic to decide: if it needs to open any more channels,
and if so how much it should use to open the channels, ultimately
returning a set of recommended AttachmentDirectives. The
autopilot.Agent loop will then take those attempt to establish
connection, and go back in waiting for a new external signal.
With this first implementation the default heuristic is the
ConstrainedPrefAttachment implementation of AttachmentHeuristic. Given
a min and max channel size, a limit on the number of channels, and the
percentage of wallet funds to allocate to channels, it will attempt to
execute a heuristic drive by the Barabási–Albert model model in order
to attempt to drive the global graph towards a scale free topology.
This is commit implements a foundational layer for future simulations,
optimization, and additional heuristics.
2017-08-11 07:14:41 +03:00
|
|
|
|
directives = append(directives, AttachmentDirective{
|
2018-12-06 15:59:46 +03:00
|
|
|
|
NodeID: nID,
|
2018-08-31 06:41:12 +03:00
|
|
|
|
Addrs: selectedNode.Addrs(),
|
autopilot: "Look ma no hands!", introducing autopilot mode
This commit introduces the initial implementation of the autopilot
mode. Autopilot is new mode within lnd that enables automatic channel
management. This means that if enabled lnd will attempt to
automatically manage channels according to a set of heuristic defined
within the main configuration for autopilot.Agent instance.
The autopilot.Agent implements a simple closed control loop. It takes
in external signals such as wallet balance updates, new open channel,
and channels that are now closed the updates its internal state. With
each external trigger it will consult the registered
AttachmentHeuristic to decide: if it needs to open any more channels,
and if so how much it should use to open the channels, ultimately
returning a set of recommended AttachmentDirectives. The
autopilot.Agent loop will then take those attempt to establish
connection, and go back in waiting for a new external signal.
With this first implementation the default heuristic is the
ConstrainedPrefAttachment implementation of AttachmentHeuristic. Given
a min and max channel size, a limit on the number of channels, and the
percentage of wallet funds to allocate to channels, it will attempt to
execute a heuristic drive by the Barabási–Albert model model in order
to attempt to drive the global graph towards a scale free topology.
This is commit implements a foundational layer for future simulations,
optimization, and additional heuristics.
2017-08-11 07:14:41 +03:00
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
// With the node selected, we'll add it to the set of visited
|
|
|
|
|
// nodes to avoid attaching to it again.
|
2018-12-06 15:59:46 +03:00
|
|
|
|
visited[nID] = struct{}{}
|
autopilot: "Look ma no hands!", introducing autopilot mode
This commit introduces the initial implementation of the autopilot
mode. Autopilot is new mode within lnd that enables automatic channel
management. This means that if enabled lnd will attempt to
automatically manage channels according to a set of heuristic defined
within the main configuration for autopilot.Agent instance.
The autopilot.Agent implements a simple closed control loop. It takes
in external signals such as wallet balance updates, new open channel,
and channels that are now closed the updates its internal state. With
each external trigger it will consult the registered
AttachmentHeuristic to decide: if it needs to open any more channels,
and if so how much it should use to open the channels, ultimately
returning a set of recommended AttachmentDirectives. The
autopilot.Agent loop will then take those attempt to establish
connection, and go back in waiting for a new external signal.
With this first implementation the default heuristic is the
ConstrainedPrefAttachment implementation of AttachmentHeuristic. Given
a min and max channel size, a limit on the number of channels, and the
percentage of wallet funds to allocate to channels, it will attempt to
execute a heuristic drive by the Barabási–Albert model model in order
to attempt to drive the global graph towards a scale free topology.
This is commit implements a foundational layer for future simulations,
optimization, and additional heuristics.
2017-08-11 07:14:41 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
numSelectedNodes := int64(len(directives))
|
|
|
|
|
switch {
|
|
|
|
|
// If we have enough available funds to distribute the maximum channel
|
|
|
|
|
// size for each of the selected peers to attach to, then we'll
|
|
|
|
|
// allocate the maximum amount to each peer.
|
2018-11-23 01:18:08 +03:00
|
|
|
|
case int64(fundsAvailable) >= numSelectedNodes*int64(p.constraints.MaxChanSize):
|
autopilot: "Look ma no hands!", introducing autopilot mode
This commit introduces the initial implementation of the autopilot
mode. Autopilot is new mode within lnd that enables automatic channel
management. This means that if enabled lnd will attempt to
automatically manage channels according to a set of heuristic defined
within the main configuration for autopilot.Agent instance.
The autopilot.Agent implements a simple closed control loop. It takes
in external signals such as wallet balance updates, new open channel,
and channels that are now closed the updates its internal state. With
each external trigger it will consult the registered
AttachmentHeuristic to decide: if it needs to open any more channels,
and if so how much it should use to open the channels, ultimately
returning a set of recommended AttachmentDirectives. The
autopilot.Agent loop will then take those attempt to establish
connection, and go back in waiting for a new external signal.
With this first implementation the default heuristic is the
ConstrainedPrefAttachment implementation of AttachmentHeuristic. Given
a min and max channel size, a limit on the number of channels, and the
percentage of wallet funds to allocate to channels, it will attempt to
execute a heuristic drive by the Barabási–Albert model model in order
to attempt to drive the global graph towards a scale free topology.
This is commit implements a foundational layer for future simulations,
optimization, and additional heuristics.
2017-08-11 07:14:41 +03:00
|
|
|
|
for i := 0; i < int(numSelectedNodes); i++ {
|
2018-11-23 01:18:08 +03:00
|
|
|
|
directives[i].ChanAmt = p.constraints.MaxChanSize
|
autopilot: "Look ma no hands!", introducing autopilot mode
This commit introduces the initial implementation of the autopilot
mode. Autopilot is new mode within lnd that enables automatic channel
management. This means that if enabled lnd will attempt to
automatically manage channels according to a set of heuristic defined
within the main configuration for autopilot.Agent instance.
The autopilot.Agent implements a simple closed control loop. It takes
in external signals such as wallet balance updates, new open channel,
and channels that are now closed the updates its internal state. With
each external trigger it will consult the registered
AttachmentHeuristic to decide: if it needs to open any more channels,
and if so how much it should use to open the channels, ultimately
returning a set of recommended AttachmentDirectives. The
autopilot.Agent loop will then take those attempt to establish
connection, and go back in waiting for a new external signal.
With this first implementation the default heuristic is the
ConstrainedPrefAttachment implementation of AttachmentHeuristic. Given
a min and max channel size, a limit on the number of channels, and the
percentage of wallet funds to allocate to channels, it will attempt to
execute a heuristic drive by the Barabási–Albert model model in order
to attempt to drive the global graph towards a scale free topology.
This is commit implements a foundational layer for future simulations,
optimization, and additional heuristics.
2017-08-11 07:14:41 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return directives, nil
|
|
|
|
|
|
|
|
|
|
// Otherwise, we'll greedily allocate our funds to the channels
|
|
|
|
|
// successively until we run out of available funds, or can't create a
|
|
|
|
|
// channel above the min channel size.
|
2018-11-23 01:18:08 +03:00
|
|
|
|
case int64(fundsAvailable) < numSelectedNodes*int64(p.constraints.MaxChanSize):
|
autopilot: "Look ma no hands!", introducing autopilot mode
This commit introduces the initial implementation of the autopilot
mode. Autopilot is new mode within lnd that enables automatic channel
management. This means that if enabled lnd will attempt to
automatically manage channels according to a set of heuristic defined
within the main configuration for autopilot.Agent instance.
The autopilot.Agent implements a simple closed control loop. It takes
in external signals such as wallet balance updates, new open channel,
and channels that are now closed the updates its internal state. With
each external trigger it will consult the registered
AttachmentHeuristic to decide: if it needs to open any more channels,
and if so how much it should use to open the channels, ultimately
returning a set of recommended AttachmentDirectives. The
autopilot.Agent loop will then take those attempt to establish
connection, and go back in waiting for a new external signal.
With this first implementation the default heuristic is the
ConstrainedPrefAttachment implementation of AttachmentHeuristic. Given
a min and max channel size, a limit on the number of channels, and the
percentage of wallet funds to allocate to channels, it will attempt to
execute a heuristic drive by the Barabási–Albert model model in order
to attempt to drive the global graph towards a scale free topology.
This is commit implements a foundational layer for future simulations,
optimization, and additional heuristics.
2017-08-11 07:14:41 +03:00
|
|
|
|
i := 0
|
2018-11-23 01:18:08 +03:00
|
|
|
|
for fundsAvailable > p.constraints.MinChanSize {
|
autopilot: "Look ma no hands!", introducing autopilot mode
This commit introduces the initial implementation of the autopilot
mode. Autopilot is new mode within lnd that enables automatic channel
management. This means that if enabled lnd will attempt to
automatically manage channels according to a set of heuristic defined
within the main configuration for autopilot.Agent instance.
The autopilot.Agent implements a simple closed control loop. It takes
in external signals such as wallet balance updates, new open channel,
and channels that are now closed the updates its internal state. With
each external trigger it will consult the registered
AttachmentHeuristic to decide: if it needs to open any more channels,
and if so how much it should use to open the channels, ultimately
returning a set of recommended AttachmentDirectives. The
autopilot.Agent loop will then take those attempt to establish
connection, and go back in waiting for a new external signal.
With this first implementation the default heuristic is the
ConstrainedPrefAttachment implementation of AttachmentHeuristic. Given
a min and max channel size, a limit on the number of channels, and the
percentage of wallet funds to allocate to channels, it will attempt to
execute a heuristic drive by the Barabási–Albert model model in order
to attempt to drive the global graph towards a scale free topology.
This is commit implements a foundational layer for future simulations,
optimization, and additional heuristics.
2017-08-11 07:14:41 +03:00
|
|
|
|
// We'll attempt to allocate the max channel size
|
|
|
|
|
// initially. If we don't have enough funds to do this,
|
|
|
|
|
// then we'll allocate the remainder of the funds
|
|
|
|
|
// available to the channel.
|
2018-11-23 01:18:08 +03:00
|
|
|
|
delta := p.constraints.MaxChanSize
|
autopilot: "Look ma no hands!", introducing autopilot mode
This commit introduces the initial implementation of the autopilot
mode. Autopilot is new mode within lnd that enables automatic channel
management. This means that if enabled lnd will attempt to
automatically manage channels according to a set of heuristic defined
within the main configuration for autopilot.Agent instance.
The autopilot.Agent implements a simple closed control loop. It takes
in external signals such as wallet balance updates, new open channel,
and channels that are now closed the updates its internal state. With
each external trigger it will consult the registered
AttachmentHeuristic to decide: if it needs to open any more channels,
and if so how much it should use to open the channels, ultimately
returning a set of recommended AttachmentDirectives. The
autopilot.Agent loop will then take those attempt to establish
connection, and go back in waiting for a new external signal.
With this first implementation the default heuristic is the
ConstrainedPrefAttachment implementation of AttachmentHeuristic. Given
a min and max channel size, a limit on the number of channels, and the
percentage of wallet funds to allocate to channels, it will attempt to
execute a heuristic drive by the Barabási–Albert model model in order
to attempt to drive the global graph towards a scale free topology.
This is commit implements a foundational layer for future simulations,
optimization, and additional heuristics.
2017-08-11 07:14:41 +03:00
|
|
|
|
if fundsAvailable-delta < 0 {
|
|
|
|
|
delta = fundsAvailable
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
directives[i].ChanAmt = delta
|
|
|
|
|
|
|
|
|
|
fundsAvailable -= delta
|
|
|
|
|
i++
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// We'll slice the initial set of directives to properly
|
|
|
|
|
// reflect the amount of funds we were able to allocate.
|
|
|
|
|
return directives[:i:i], nil
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
return nil, fmt.Errorf("err")
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-11-23 01:18:09 +03:00
|
|
|
|
|
|
|
|
|
// NodeScores is a method that given the current channel graph, current set of
|
|
|
|
|
// local channels and funds available, scores the given nodes according the the
|
|
|
|
|
// preference of opening a channel with them.
|
|
|
|
|
//
|
|
|
|
|
// The heuristic employed by this method is one that attempts to promote a
|
|
|
|
|
// scale-free network globally, via local attachment preferences for new nodes
|
|
|
|
|
// joining the network with an amount of available funds to be allocated to
|
|
|
|
|
// channels. Specifically, we consider the degree of each node (and the flow
|
|
|
|
|
// in/out of the node available via its open channels) and utilize the
|
|
|
|
|
// Barabási–Albert model to drive our recommended attachment heuristics. If
|
|
|
|
|
// implemented globally for each new participant, this results in a channel
|
|
|
|
|
// graph that is scale-free and follows a power law distribution with k=-3.
|
|
|
|
|
//
|
|
|
|
|
// The returned scores will be in the range [0.0, 1.0], where higher scores are
|
|
|
|
|
// given to nodes already having high connectivity in the graph.
|
|
|
|
|
//
|
|
|
|
|
// NOTE: This is a part of the AttachmentHeuristic interface.
|
|
|
|
|
func (p *ConstrainedPrefAttachment) NodeScores(g ChannelGraph, chans []Channel,
|
|
|
|
|
fundsAvailable btcutil.Amount, nodes map[NodeID]struct{}) (
|
|
|
|
|
map[NodeID]*AttachmentDirective, error) {
|
|
|
|
|
|
|
|
|
|
// Count the number of channels in the graph. We'll also count the
|
|
|
|
|
// number of channels as we go for the nodes we are interested in, and
|
|
|
|
|
// record their addresses found in the db.
|
|
|
|
|
var graphChans int
|
|
|
|
|
nodeChanNum := make(map[NodeID]int)
|
|
|
|
|
addresses := make(map[NodeID][]net.Addr)
|
|
|
|
|
if err := g.ForEachNode(func(n Node) error {
|
|
|
|
|
var nodeChans int
|
|
|
|
|
err := n.ForEachChannel(func(_ ChannelEdge) error {
|
|
|
|
|
nodeChans++
|
|
|
|
|
graphChans++
|
|
|
|
|
return nil
|
|
|
|
|
})
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If this node is not among our nodes to score, we can return
|
|
|
|
|
// early.
|
|
|
|
|
nID := NodeID(n.PubKey())
|
|
|
|
|
if _, ok := nodes[nID]; !ok {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Otherwise we'll record the number of channels, and also
|
|
|
|
|
// populate the address in our channel candidates map.
|
|
|
|
|
nodeChanNum[nID] = nodeChans
|
|
|
|
|
addresses[nID] = n.Addrs()
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}); err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If there are no channels in the graph we cannot determine any
|
|
|
|
|
// preferences, so we return, indicating all candidates get a score of
|
|
|
|
|
// zero.
|
|
|
|
|
if graphChans == 0 {
|
|
|
|
|
return nil, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
existingPeers := make(map[NodeID]struct{})
|
|
|
|
|
for _, c := range chans {
|
|
|
|
|
existingPeers[c.Node] = struct{}{}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// For each node in the set of nodes, count their fraction of channels
|
|
|
|
|
// in the graph, and use that as the score.
|
|
|
|
|
candidates := make(map[NodeID]*AttachmentDirective)
|
|
|
|
|
for nID, nodeChans := range nodeChanNum {
|
|
|
|
|
// As channel size we'll use the maximum channel size available.
|
|
|
|
|
chanSize := p.constraints.MaxChanSize
|
|
|
|
|
if fundsAvailable-chanSize < 0 {
|
|
|
|
|
chanSize = fundsAvailable
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_, ok := existingPeers[nID]
|
|
|
|
|
|
|
|
|
|
switch {
|
|
|
|
|
|
|
|
|
|
// If the node is among or existing channel peers, we don't
|
|
|
|
|
// need another channel.
|
|
|
|
|
case ok:
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
// If the amount is too small, we don't want to attempt opening
|
|
|
|
|
// another channel.
|
|
|
|
|
case chanSize == 0 || chanSize < p.constraints.MinChanSize:
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Otherwise we score the node according to its fraction of
|
|
|
|
|
// channels in the graph.
|
|
|
|
|
score := float64(nodeChans) / float64(graphChans)
|
|
|
|
|
candidates[nID] = &AttachmentDirective{
|
|
|
|
|
NodeID: nID,
|
|
|
|
|
ChanAmt: chanSize,
|
|
|
|
|
Score: score,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return candidates, nil
|
|
|
|
|
}
|