autopilot

package
v1.0.0-...-b07499f Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 28, 2018 License: MIT Imports: 17 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func DisableLog

func DisableLog()

DisableLog disables all library log output. Logging output is disabled by default until UseLogger is called.

func UseLogger

func UseLogger(logger btclog.Logger)

UseLogger uses a specified Logger to output package logging info. This should be used in preference to SetLogWriter if the caller is also using btclog.

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

func New(cfg Config, initialState []Channel) (*Agent, error)

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

func (a *Agent) OnChannelOpen(c Channel)

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) 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.

func (*Agent) Start

func (a *Agent) Start() error

Start starts the agent along with any goroutines it needs to perform its normal duties.

func (*Agent) Stop

func (a *Agent) Stop() error

Stop signals the Agent to gracefully shutdown. This function will block until all goroutines have exited.

type AttachmentDirective

type AttachmentDirective struct {
	// NodeKey is 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.
	NodeKey *btcec.PublicKey

	// NodeID is the serialized compressed pubkey of the target node.
	NodeID NodeID

	// ChanAmt is the size of the channel that should be opened, expressed
	// in satoshis.
	ChanAmt btcutil.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 {
	// 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. This method should also return the exact *number* of
	// additional channels that are needed in order to converge towards our
	// ideal state.
	NeedMoreChans(chans []Channel, balance btcutil.Amount) (btcutil.Amount, uint32, bool)

	// Select is a method that given the current state of the channel
	// graph, a set of nodes to ignore, and an amount of available funds,
	// should return a set of attachment directives which describe which
	// additional channels should be opened within the graph to push the
	// heuristic back towards its equilibrium state. The numNewChans
	// argument represents the additional number of channels that should be
	// open.
	Select(self *btcec.PublicKey, graph ChannelGraph,
		amtToUse btcutil.Amount, numNewChans uint32,
		skipNodes map[NodeID]struct{}) ([]AttachmentDirective, 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 btcutil.Amount

	// FundedAmt is the amount the local node funded into the target
	// channel.
	//
	// TODO(roasbeef): need this?
	FundedAmt btcutil.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, with a capacity of the
	// specified amount. This function should un-block immediately after
	// the funding transaction that marks the channel open has been
	// broadcast.
	OpenChannel(target *btcec.PublicKey, amt btcutil.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 btcutil.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 btcutil.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() (btcutil.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

	// MaxPendingOpens is 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
}

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 ConstrainedPrefAttachment

type ConstrainedPrefAttachment struct {
	// contains filtered or unexported fields
}

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 power law distribution. The attachment is non-linear in that it favors 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

func NewConstrainedPrefAttachment

func NewConstrainedPrefAttachment(minChanSize, maxChanSize btcutil.Amount,
	chanLimit uint16, allocation float64) *ConstrainedPrefAttachment

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.

func (*ConstrainedPrefAttachment) NeedMoreChans

func (p *ConstrainedPrefAttachment) NeedMoreChans(channels []Channel,
	funds btcutil.Amount) (btcutil.Amount, uint32, bool)

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 (*ConstrainedPrefAttachment) Select

func (p *ConstrainedPrefAttachment) Select(self *btcec.PublicKey, g ChannelGraph,
	fundsAvailable btcutil.Amount, numNewChans uint32,
	skipNodes map[NodeID]struct{}) ([]AttachmentDirective, error)

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.

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.

func NewNodeID

func NewNodeID(pub *btcec.PublicKey) NodeID

NewNodeID creates a new nodeID from a passed public key.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL