Documentation ¶
Index ¶
- Constants
- Variables
- func DisableLog()
- func Median(vals []ltcutil.Amount) ltcutil.Amount
- func UseLogger(logger btclog.Logger)
- type Agent
- func (a *Agent) OnBalanceChange()
- func (a *Agent) OnChannelClose(closedChans ...lnwire.ShortChannelID)
- func (a *Agent) OnChannelOpen(c Channel)
- func (a *Agent) OnChannelOpenFailure()
- func (a *Agent) OnChannelPendingOpen()
- func (a *Agent) OnHeuristicUpdate(h AttachmentHeuristic)
- func (a *Agent) OnNodeUpdates()
- func (a *Agent) Start() error
- func (a *Agent) Stop() error
- type AgentConstraints
- type AttachmentDirective
- type AttachmentHeuristic
- type Channel
- type ChannelController
- type ChannelEdge
- type ChannelGraph
- type Config
- type ExternalScoreAttachment
- func (s *ExternalScoreAttachment) Name() string
- func (s *ExternalScoreAttachment) NodeScores(g ChannelGraph, chans []Channel, chanSize ltcutil.Amount, ...) (map[NodeID]*NodeScore, error)
- func (s *ExternalScoreAttachment) SetNodeScores(targetHeuristic string, newScores map[NodeID]float64) (bool, error)
- type HeuristicScores
- type Manager
- func (m *Manager) IsActive() bool
- func (m *Manager) QueryHeuristics(nodes []NodeID, localState bool) (HeuristicScores, error)
- func (m *Manager) SetNodeScores(name string, scores map[NodeID]float64) error
- func (m *Manager) Start() error
- func (m *Manager) StartAgent() error
- func (m *Manager) Stop() error
- func (m *Manager) StopAgent() error
- type ManagerCfg
- type Node
- type NodeID
- type NodeScore
- type PrefAttachment
- type ScoreSettable
- type WeightedCombAttachment
- type WeightedHeuristic
Constants ¶
const DefaultConfTarget = 3
DefaultConfTarget is the default confirmation target for autopilot channels. TODO(halseth): possibly make dynamic, going aggressive->lax as more channels are opened.
Variables ¶
var ( // AvailableHeuristics is a map that holds the name of available // heuristics to the actual heuristic for easy lookup. It will be // filled during init(). AvailableHeuristics = make(map[string]AttachmentHeuristic) )
var ErrNoPositive = errors.New("no positive weights left")
ErrNoPositive is returned from weightedChoice when there are no positive weights left to choose from.
Functions ¶
func DisableLog ¶
func DisableLog()
DisableLog disables all library log output. Logging output is disabled by default until UseLogger is called.
Types ¶
type Agent ¶
type Agent struct {
// contains filtered or unexported fields
}
Agent implements a closed-loop control system which seeks to autonomously optimize the allocation of satoshis within channels throughput the network's channel graph. An agent is configurable by swapping out different AttachmentHeuristic strategies. The agent uses external signals such as the wallet balance changing, or new channels being opened/closed for the local node as an indicator to re-examine its internal state, and the amount of available funds in order to make updated decisions w.r.t the channel graph. The Agent will automatically open, close, and splice in/out channel as necessary for it to step closer to its optimal state.
TODO(roasbeef): prob re-word
func New ¶
New creates a new instance of the Agent instantiated using the passed configuration and initial channel state. The initial channel state slice should be populated with the set of Channels that are currently opened by the backing Lightning Node.
func (*Agent) OnBalanceChange ¶
func (a *Agent) OnBalanceChange()
OnBalanceChange is a callback that should be executed each time the balance of the backing wallet changes.
func (*Agent) OnChannelClose ¶
func (a *Agent) OnChannelClose(closedChans ...lnwire.ShortChannelID)
OnChannelClose is a callback that should be executed each time a prior channel has been closed for any reason. This includes regular closes, force closes, and channel breaches.
func (*Agent) OnChannelOpen ¶
OnChannelOpen is a callback that should be executed each time a new channel is manually opened by the user or any system outside the autopilot agent.
func (*Agent) OnChannelOpenFailure ¶
func (a *Agent) OnChannelOpenFailure()
OnChannelOpenFailure is a callback that should be executed when the autopilot has attempted to open a channel, but failed. In this case we can retry channel creation with a different node.
func (*Agent) OnChannelPendingOpen ¶
func (a *Agent) OnChannelPendingOpen()
OnChannelPendingOpen is a callback that should be executed each time a new channel is opened, either by the agent or an external subsystems, but is still pending.
func (*Agent) OnHeuristicUpdate ¶
func (a *Agent) OnHeuristicUpdate(h AttachmentHeuristic)
OnHeuristicUpdate is a method called when a heuristic has been updated, to trigger the agent to do a new state assessment.
func (*Agent) OnNodeUpdates ¶
func (a *Agent) OnNodeUpdates()
OnNodeUpdates is a callback that should be executed each time our channel graph has new nodes or their node announcements are updated.
type AgentConstraints ¶
type AgentConstraints interface { // ChannelBudget should, given the passed parameters, return whether // more channels can be be opened while still staying within the set // constraints. If the constraints allow us to open more channels, then // the first return value will represent the amount of additional funds // available towards creating channels. The second return value is the // exact *number* of additional channels available. ChannelBudget(chans []Channel, balance ltcutil.Amount) ( ltcutil.Amount, uint32) // MaxPendingOpens returns the maximum number of pending channel // establishment goroutines that can be lingering. We cap this value in // order to control the level of parallelism caused by the autopilot // agent. MaxPendingOpens() uint16 // MinChanSize returns the smallest channel that the autopilot agent // should create. MinChanSize() ltcutil.Amount // MaxChanSize returns largest channel that the autopilot agent should // create. MaxChanSize() ltcutil.Amount }
AgentConstraints is an interface the agent will query to determine what limits it will need to stay inside when opening channels.
func NewConstraints ¶
func NewConstraints(minChanSize, maxChanSize ltcutil.Amount, chanLimit, maxPendingOpens uint16, allocation float64) AgentConstraints
NewConstraints returns a new AgentConstraints with the given limits.
type AttachmentDirective ¶
type AttachmentDirective struct { // NodeID is the serialized compressed pubkey of the target node for // this attachment directive. It can be identified by its public key, // and therefore can be used along with a ChannelOpener implementation // to execute the directive. NodeID NodeID // ChanAmt is the size of the channel that should be opened, expressed // in satoshis. ChanAmt ltcutil.Amount // Addrs is a list of addresses that the target peer may be reachable // at. Addrs []net.Addr }
AttachmentDirective describes a channel attachment proscribed by an AttachmentHeuristic. It details to which node a channel should be created to, and also the parameters which should be used in the channel creation.
type AttachmentHeuristic ¶
type AttachmentHeuristic interface { // Name returns the name of this heuristic. Name() string // 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 // implementation of this interface must return scores in this range to // properly allow the autopilot agent to make a reasonable choice based // on the score from multiple heuristics. // // NOTE: A NodeID not found in the returned map is implicitly given a // score of 0. NodeScores(g ChannelGraph, chans []Channel, chanSize ltcutil.Amount, nodes map[NodeID]struct{}) ( map[NodeID]*NodeScore, error) }
AttachmentHeuristic is one of the primary interfaces within this package. Implementations of this interface will be used to implement a control system which automatically regulates channels of a particular agent, attempting to optimize channels opened/closed based on various heuristics. The purpose of the interface is to allow an auto-pilot agent to decide if it needs more channels, and if so, which exact channels should be opened.
type Channel ¶
type Channel struct { // ChanID is the short channel ID for this channel as defined within // BOLT-0007. ChanID lnwire.ShortChannelID // Capacity is the capacity of the channel expressed in satoshis. Capacity ltcutil.Amount // FundedAmt is the amount the local node funded into the target // channel. // // TODO(roasbeef): need this? FundedAmt ltcutil.Amount // Node is the peer that this channel has been established with. Node NodeID }
Channel is a simple struct which contains relevant details of a particular channel within the channel graph. The fields in this struct may be used a signals for various AttachmentHeuristic implementations.
type ChannelController ¶
type ChannelController interface { // OpenChannel opens a channel to a target peer, using at most amt // funds. This means that the resulting channel capacity might be // slightly less to account for fees. This function should un-block // immediately after the funding transaction that marks the channel // open has been broadcast. OpenChannel(target *btcec.PublicKey, amt ltcutil.Amount) error // CloseChannel attempts to close out the target channel. // // TODO(roasbeef): add force option? CloseChannel(chanPoint *wire.OutPoint) error // SpliceIn attempts to add additional funds to the target channel via // a splice in mechanism. The new channel with an updated capacity // should be returned. SpliceIn(chanPoint *wire.OutPoint, amt ltcutil.Amount) (*Channel, error) // SpliceOut attempts to remove funds from an existing channels using a // splice out mechanism. The removed funds from the channel should be // returned to an output under the control of the backing wallet. SpliceOut(chanPoint *wire.OutPoint, amt ltcutil.Amount) (*Channel, error) }
ChannelController is a simple interface that allows an auto-pilot agent to open a channel within the graph to a target peer, close targeted channels, or add/remove funds from existing channels via a splice in/out mechanisms.
type ChannelEdge ¶
type ChannelEdge struct { // Channel contains the attributes of this channel. Channel // Peer is the peer that this channel creates an edge to in the channel // graph. Peer Node }
ChannelEdge is a struct that holds details concerning a channel, but also contains a reference to the Node that this channel connects to as a directed edge within the graph. The existence of this reference to the connected node will allow callers to traverse the graph in an object-oriented manner.
type ChannelGraph ¶
type ChannelGraph interface { // ForEachNode is a higher-order function that should be called once // for each connected node within the channel graph. If the passed // callback returns an error, then execution should be terminated. ForEachNode(func(Node) error) error }
ChannelGraph in an interface that represents a traversable channel graph. The autopilot agent will use this interface as its source of graph traits in order to make decisions concerning which channels should be opened, and to whom.
TODO(roasbeef): abstract??
func ChannelGraphFromDatabase ¶
func ChannelGraphFromDatabase(db *channeldb.ChannelGraph) ChannelGraph
ChannelGraphFromDatabase returns an instance of the autopilot.ChannelGraph backed by a live, open channeldb instance.
type Config ¶
type Config struct { // Self is the identity public key of the Lightning Network node that // is being driven by the agent. This is used to ensure that we don't // accidentally attempt to open a channel with ourselves. Self *btcec.PublicKey // Heuristic is an attachment heuristic which will govern to whom we // open channels to, and also what those channels look like in terms of // desired capacity. The Heuristic will take into account the current // state of the graph, our set of open channels, and the amount of // available funds when determining how channels are to be opened. // Additionally, a heuristic make also factor in extra-graph // information in order to make more pertinent recommendations. Heuristic AttachmentHeuristic // ChanController is an interface that is able to directly manage the // creation, closing and update of channels within the network. ChanController ChannelController // ConnectToPeer attempts to connect to the peer using one of its // advertised addresses. The boolean returned signals whether the peer // was already connected. ConnectToPeer func(*btcec.PublicKey, []net.Addr) (bool, error) // DisconnectPeer attempts to disconnect the peer with the given public // key. DisconnectPeer func(*btcec.PublicKey) error // WalletBalance is a function closure that should return the current // available balance of the backing wallet. WalletBalance func() (ltcutil.Amount, error) // Graph is an abstract channel graph that the Heuristic and the Agent // will use to make decisions w.r.t channel allocation and placement // within the graph. Graph ChannelGraph // Constraints is the set of constraints the autopilot must adhere to // when opening channels. Constraints AgentConstraints }
Config couples all the items that an autopilot agent needs to function. All items within the struct MUST be populated for the Agent to be able to carry out its duties.
type ExternalScoreAttachment ¶
ExternalScoreAttachment is an implementation of the AttachmentHeuristic interface that allows an external source to provide it with node scores.
func NewExternalScoreAttachment ¶
func NewExternalScoreAttachment() *ExternalScoreAttachment
NewExternalScoreAttachment creates a new instance of an ExternalScoreAttachment.
func (*ExternalScoreAttachment) Name ¶
func (s *ExternalScoreAttachment) Name() string
Name returns the name of this heuristic.
NOTE: This is a part of the AttachmentHeuristic interface.
func (*ExternalScoreAttachment) NodeScores ¶
func (s *ExternalScoreAttachment) NodeScores(g ChannelGraph, chans []Channel, chanSize ltcutil.Amount, nodes map[NodeID]struct{}) ( map[NodeID]*NodeScore, error)
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 (*ExternalScoreAttachment) SetNodeScores ¶
func (s *ExternalScoreAttachment) SetNodeScores(targetHeuristic string, newScores map[NodeID]float64) (bool, error)
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.
type HeuristicScores ¶
HeuristicScores is an alias for a map that maps heuristic names to a map of scores for pubkeys.
type Manager ¶
Manager is struct that manages an autopilot agent, making it possible to enable and disable it at will, and hand it relevant external information. It implements the autopilot grpc service, which is used to get data about the running autopilot, and give it relevant information.
func NewManager ¶
func NewManager(cfg *ManagerCfg) (*Manager, error)
NewManager creates a new instance of the Manager from the passed config.
func (*Manager) QueryHeuristics ¶
func (m *Manager) QueryHeuristics(nodes []NodeID, localState bool) ( HeuristicScores, error)
QueryHeuristics queries the available autopilot heuristics for node scores.
func (*Manager) SetNodeScores ¶
SetNodeScores is used to set the scores of the given heuristic, if it is active, and ScoreSettable.
func (*Manager) StartAgent ¶
StartAgent creates and starts an autopilot agent from the Manager's config.
type ManagerCfg ¶
type ManagerCfg struct { // Self is the public key of the lnd instance. It is used to making // sure the autopilot is not opening channels to itself. Self *btcec.PublicKey // PilotCfg is the config of the autopilot agent managed by the // Manager. PilotCfg *Config // ChannelState is a function closure that returns the current set of // channels managed by this node. ChannelState func() ([]Channel, error) // SubscribeTransactions is used to get a subscription for transactions // relevant to this node's wallet. SubscribeTransactions func() (lnwallet.TransactionSubscription, error) // SubscribeTopology is used to get a subscription for topology changes // on the network. SubscribeTopology func() (*routing.TopologyClient, error) }
ManagerCfg houses a set of values and methods that is passed to the Manager for it to properly manage its autopilot agent.
type Node ¶
type Node interface { // PubKey is the identity public key of the node. This will be used to // attempt to target a node for channel opening by the main autopilot // agent. The key will be returned in serialized compressed format. PubKey() [33]byte // Addrs returns a slice of publicly reachable public TCP addresses // that the peer is known to be listening on. Addrs() []net.Addr // ForEachChannel is a higher-order function that will be used to // iterate through all edges emanating from/to the target node. For // each active channel, this function should be called with the // populated ChannelEdge that describes the active channel. ForEachChannel(func(ChannelEdge) error) error }
Node node is an interface which represents n abstract vertex within the channel graph. All nodes should have at least a single edge to/from them within the graph.
TODO(roasbeef): combine with routing.ChannelGraphSource
type NodeID ¶
type NodeID [33]byte
NodeID is a simple type that holds an EC public key serialized in compressed format.
type NodeScore ¶
type NodeScore struct { // NodeID is the serialized compressed pubkey of the node that is being // scored. NodeID NodeID // Score is the score given by the heuristic for opening a channel of // the given size to this node. Score float64 }
NodeScore is a tuple mapping a NodeID to a score indicating the preference of opening a channel with it.
type PrefAttachment ¶
type PrefAttachment struct { }
PrefAttachment is an implementation of the AttachmentHeuristic interface that implement a 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 power law distribution. The attachment is non-linear in that it favors nodes with a higher in-degree but less so than regular linear preferential attachment. As a result, this creates smaller and less clusters than regular linear preferential attachment.
TODO(roasbeef): BA, with k=-3
func NewPrefAttachment ¶
func NewPrefAttachment() *PrefAttachment
NewPrefAttachment creates a new instance of a PrefAttachment heuristic.
func (*PrefAttachment) Name ¶
func (p *PrefAttachment) Name() string
Name returns the name of this heuristic.
NOTE: This is a part of the AttachmentHeuristic interface.
func (*PrefAttachment) NodeScores ¶
func (p *PrefAttachment) NodeScores(g ChannelGraph, chans []Channel, chanSize ltcutil.Amount, nodes map[NodeID]struct{}) ( map[NodeID]*NodeScore, error)
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 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.
To avoid assigning a high score to nodes with a large number of small channels, we only count channels at least as large as a given fraction of the graph's median channel size.
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.
type ScoreSettable ¶
type ScoreSettable interface { // 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. SetNodeScores(string, map[NodeID]float64) (bool, error) }
ScoreSettable is an interface that indicates that the scores returned by the heuristic can be mutated by an external caller. The ExternalScoreAttachment currently implements this interface, and so should any heuristic that is using the ExternalScoreAttachment as a sub-heuristic, or keeps their own internal list of mutable scores, to allow access to setting the internal scores.
type WeightedCombAttachment ¶
type WeightedCombAttachment struct {
// contains filtered or unexported fields
}
WeightedCombAttachment is an implementation of the AttachmentHeuristic interface that combines the scores given by several sub-heuristics into one.
func NewWeightedCombAttachment ¶
func NewWeightedCombAttachment(h ...*WeightedHeuristic) ( *WeightedCombAttachment, error)
NewWeightedCombAttachment creates a new instance of a WeightedCombAttachment.
func (*WeightedCombAttachment) Name ¶
func (c *WeightedCombAttachment) Name() string
Name returns the name of this heuristic.
NOTE: This is a part of the AttachmentHeuristic interface.
func (*WeightedCombAttachment) NodeScores ¶
func (c *WeightedCombAttachment) NodeScores(g ChannelGraph, chans []Channel, chanSize ltcutil.Amount, nodes map[NodeID]struct{}) ( map[NodeID]*NodeScore, error)
NodeScores is a method that given the current channel graph, current set of local channels and funds available, scores the given nodes according to the preference of opening a channel with them. The returned channel candidates maps the NodeID to an attachment directive containing a score and a channel size.
The scores is determined by quering the set of sub-heuristics, then combining these scores into a final score according to the active configuration.
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.
NOTE: This is a part of the AttachmentHeuristic interface.
func (*WeightedCombAttachment) SetNodeScores ¶
func (c *WeightedCombAttachment) SetNodeScores(targetHeuristic string, newScores map[NodeID]float64) (bool, error)
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.
Since this heuristic doesn't keep any internal scores, it will recursively apply the scores to its sub-heuristics.
NOTE: This is a part of the ScoreSettable interface.
type WeightedHeuristic ¶
type WeightedHeuristic struct { // Weight is this AttachmentHeuristic's relative weight factor. It // should be between 0.0 and 1.0. Weight float64 AttachmentHeuristic }
WeightedHeuristic is a tuple that associates a weight to an AttachmentHeuristic. This is used to determining a node's final score when querying several heuristics for scores.