routing

package
v0.4.0 Latest Latest
Warning

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

Go to latest
Published: Jun 9, 2023 License: MIT Imports: 38 Imported by: 0

README

routing

Build Status MIT licensed GoDoc

The routing package implements authentication+validation of channel announcements, pruning of the channel graph, path finding within the network, sending outgoing payments into the network and synchronizing new peers to our channel graph state.

Installation and Updating

$ go get -u github.com/decred/dcrlnd/routing

Documentation

Index

Constants

View Source
const (
	// ErrOutdated is returned when the routing update already have
	// been applied, or a newer update is already known.
	ErrOutdated errorCode = iota

	// ErrIgnored is returned when the update have been ignored because
	// this update can't bring us something new, or because a node
	// announcement was given for node not found in any channel.
	ErrIgnored
)
View Source
const (
	// DefaultPenaltyHalfLife is the default half-life duration. The
	// half-life duration defines after how much time a penalized node or
	// channel is back at 50% probability.
	DefaultPenaltyHalfLife = time.Hour

	// DefaultMaxMcHistory is the default maximum history size.
	DefaultMaxMcHistory = 1000

	// DefaultAprioriWeight is the default a priori weight. See
	// MissionControlConfig for further explanation.
	DefaultAprioriWeight = 0.5

	// DefaultMinFailureRelaxInterval is the default minimum time that must
	// have passed since the previously recorded failure before the failure
	// amount may be raised.
	DefaultMinFailureRelaxInterval = time.Minute
)
View Source
const (
	// DefaultPayAttemptTimeout is the default payment attempt timeout. The
	// payment attempt timeout defines the duration after which we stop
	// trying more routes for a payment.
	DefaultPayAttemptTimeout = time.Second * 60

	// DefaultChannelPruneExpiry is the default duration used to determine
	// if a channel should be pruned or not.
	DefaultChannelPruneExpiry = time.Hour * 24 * 14

	// MinCLTVDelta is the minimum CLTV value accepted by LND for all
	// timelock deltas. This includes both forwarding CLTV deltas set on
	// channel updates, as well as final CLTV deltas used to create BOLT 11
	// payment requests.
	//
	// NOTE: For payment requests, BOLT 11 stipulates that a final CLTV
	// delta of 9 should be used when no value is decoded. This however
	// leads to inflexiblity in upgrading this default parameter, since it
	// can create inconsistencies around the assumed value between sender
	// and receiver. Specifically, if the receiver assumes a higher value
	// than the sender, the receiver will always see the received HTLCs as
	// invalid due to their timelock not meeting the required delta.
	//
	// We skirt this by always setting an explicit CLTV delta when creating
	// invoices. This allows LND nodes to freely update the minimum without
	// creating incompatibilities during the upgrade process. For some time
	// LND has used an explicit default final CLTV delta of 40 blocks for
	// bitcoin (160 for litecoin), though we now clamp the lower end of this
	// range for user-chosen deltas to 18 blocks to be conservative.
	MinCLTVDelta = 18
)
View Source
const BlockPadding uint16 = 3

BlockPadding is used to increment the finalCltvDelta value for the last hop to prevent an HTLC being failed if some blocks are mined while it's in-flight.

View Source
const (

	// RiskFactorBillionths controls the influence of time lock delta
	// of a channel on route selection. It is expressed as billionths
	// of mAt per mAt sent through the channel per time lock delta
	// block. See edgeWeight function below for more details.
	// The chosen value is based on the previous incorrect weight function
	// 1 + timelock + fee * fee. In this function, the fee penalty
	// diminishes the time lock penalty for all but the smallest amounts.
	// To not change the behaviour of path finding too drastically, a
	// relatively small value is chosen which is still big enough to give
	// some effect with smaller time lock values. The value may need
	// tweaking and/or be made configurable in the future.
	RiskFactorBillionths = 15
)
View Source
const Subsystem = "CRTR"

Variables

View Source
var (
	// DefaultPaymentAttemptPenalty is the virtual cost in path finding weight
	// units of executing a payment attempt that fails. It is used to trade
	// off potentially better routes against their probability of
	// succeeding.
	DefaultPaymentAttemptPenalty = lnwire.NewMAtomsFromAtoms(100)

	// DefaultMinRouteProbability is the default minimum probability for routes
	// returned from findPath.
	DefaultMinRouteProbability = float64(0.01)

	// DefaultAprioriHopProbability is the default a priori probability for
	// a hop.
	DefaultAprioriHopProbability = float64(0.6)
)
View Source
var (
	// DefaultShardMinAmt is the default amount beyond which we won't try to
	// further split the payment if no route is found. It is the minimum
	// amount that we use as the shard size when splitting.
	DefaultShardMinAmt = lnwire.NewMAtomsFromAtoms(10000)
)
View Source
var (
	// ErrRouterShuttingDown is returned if the router is in the process of
	// shutting down.
	ErrRouterShuttingDown = fmt.Errorf("router shutting down")
)
View Source
var ErrVBarrierShuttingDown = errors.New("validation barrier shutting down")

ErrVBarrierShuttingDown signals that the barrier has been requested to shutdown, and that the caller should not treat the wait condition as fulfilled.

Functions

func DisableLog

func DisableLog()

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

func EncodeHexColor added in v0.2.0

func EncodeHexColor(color color.RGBA) string

EncodeHexColor takes a color and returns it in hex code format.

func IsError

func IsError(e interface{}, codes ...errorCode) bool

IsError is a helper function which is needed to have ability to check that returned error has specific error code.

func RouteHintsToEdges added in v0.3.0

func RouteHintsToEdges(routeHints [][]zpay32.HopHint, target route.Vertex) (
	map[route.Vertex][]*channeldb.ChannelEdgePolicy, error)

RouteHintsToEdges converts a list of invoice route hints to an edge map that can be passed into pathfinding.

func UseLogger

func UseLogger(logger slog.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 slog.

func ValidateChannelAnn

func ValidateChannelAnn(a *lnwire.ChannelAnnouncement) error

ValidateChannelAnn validates the channel announcement message and checks that node signatures covers the announcement message, and that the bitcoin signatures covers the node keys.

func ValidateChannelUpdateAnn

func ValidateChannelUpdateAnn(pubKey *secp256k1.PublicKey, capacity dcrutil.Amount,
	a *lnwire.ChannelUpdate) error

ValidateChannelUpdateAnn validates the channel update announcement by checking (1) that the included signature covers the announcement and has been signed by the node's private key, and (2) that the announcement's message flags and optional fields are sane.

func ValidateNodeAnn

func ValidateNodeAnn(a *lnwire.NodeAnnouncement) error

ValidateNodeAnn validates the node announcement by ensuring that the attached signature is needed a signature of the node announcement under the specified node public key.

func VerifyChannelUpdateSignature added in v0.2.0

func VerifyChannelUpdateSignature(msg *lnwire.ChannelUpdate,
	pubKey *secp256k1.PublicKey) error

VerifyChannelUpdateSignature verifies that the channel update message was signed by the party with the given node public key.

Types

type ChannelEdgeUpdate

type ChannelEdgeUpdate struct {
	// ChanID is the unique short channel ID for the channel. This encodes
	// where in the blockchain the channel's funding transaction was
	// originally confirmed.
	ChanID uint64

	// ChanPoint is the outpoint which represents the multi-sig funding
	// output for the channel.
	ChanPoint wire.OutPoint

	// Capacity is the capacity of the newly created channel.
	Capacity dcrutil.Amount

	// MinHTLC is the minimum HTLC amount that this channel will forward.
	MinHTLC lnwire.MilliAtom

	// MaxHTLC is the maximum HTLC amount that this channel will forward.
	MaxHTLC lnwire.MilliAtom

	// BaseFee is the base fee that will charged for all HTLC's forwarded
	// across the this channel direction.
	BaseFee lnwire.MilliAtom

	// FeeRate is the fee rate that will be shared for all HTLC's forwarded
	// across this channel direction.
	FeeRate lnwire.MilliAtom

	// TimeLockDelta is the time-lock expressed in blocks that will be
	// added to outgoing HTLC's from incoming HTLC's. This value is the
	// difference of the incoming and outgoing HTLC's time-locks routed
	// through this hop.
	TimeLockDelta uint16

	// AdvertisingNode is the node that's advertising this edge.
	AdvertisingNode *secp256k1.PublicKey

	// ConnectingNode is the node that the advertising node connects to.
	ConnectingNode *secp256k1.PublicKey

	// Disabled, if true, signals that the channel is unavailable to relay
	// payments.
	Disabled bool
}

ChannelEdgeUpdate is an update for a new channel within the ChannelGraph. This update is sent out once a new authenticated channel edge is discovered within the network. These updates are directional, so if a channel is fully public, then there will be two updates sent out: one for each direction within the channel. Each update will carry that particular routing edge policy for the channel direction.

An edge is a channel in the direction of AdvertisingNode -> ConnectingNode.

type ChannelGraphSource

type ChannelGraphSource interface {
	// AddNode is used to add information about a node to the router
	// database. If the node with this pubkey is not present in an existing
	// channel, it will be ignored.
	AddNode(node *channeldb.LightningNode) error

	// AddEdge is used to add edge/channel to the topology of the router,
	// after all information about channel will be gathered this
	// edge/channel might be used in construction of payment path.
	AddEdge(edge *channeldb.ChannelEdgeInfo) error

	// AddProof updates the channel edge info with proof which is needed to
	// properly announce the edge to the rest of the network.
	AddProof(chanID lnwire.ShortChannelID, proof *channeldb.ChannelAuthProof) error

	// UpdateEdge is used to update edge information, without this message
	// edge considered as not fully constructed.
	UpdateEdge(policy *channeldb.ChannelEdgePolicy) error

	// IsStaleNode returns true if the graph source has a node announcement
	// for the target node with a more recent timestamp. This method will
	// also return true if we don't have an active channel announcement for
	// the target node.
	IsStaleNode(node route.Vertex, timestamp time.Time) bool

	// IsPublicNode determines whether the given vertex is seen as a public
	// node in the graph from the graph's source node's point of view.
	IsPublicNode(node route.Vertex) (bool, error)

	// IsKnownEdge returns true if the graph source already knows of the
	// passed channel ID either as a live or zombie edge.
	IsKnownEdge(chanID lnwire.ShortChannelID) bool

	// IsStaleEdgePolicy returns true if the graph source has a channel
	// edge for the passed channel ID (and flags) that have a more recent
	// timestamp.
	IsStaleEdgePolicy(chanID lnwire.ShortChannelID, timestamp time.Time,
		flags lnwire.ChanUpdateChanFlags) bool

	// MarkEdgeLive clears an edge from our zombie index, deeming it as
	// live.
	MarkEdgeLive(chanID lnwire.ShortChannelID) error

	// ForAllOutgoingChannels is used to iterate over all channels
	// emanating from the "source" node which is the center of the
	// star-graph.
	ForAllOutgoingChannels(cb func(c *channeldb.ChannelEdgeInfo,
		e *channeldb.ChannelEdgePolicy) error) error

	// CurrentBlockHeight returns the block height from POV of the router
	// subsystem.
	CurrentBlockHeight() (uint32, error)

	// GetChannelByID return the channel by the channel id.
	GetChannelByID(chanID lnwire.ShortChannelID) (*channeldb.ChannelEdgeInfo,
		*channeldb.ChannelEdgePolicy, *channeldb.ChannelEdgePolicy, error)

	// FetchLightningNode attempts to look up a target node by its identity
	// public key. channeldb.ErrGraphNodeNotFound is returned if the node
	// doesn't exist within the graph.
	FetchLightningNode(route.Vertex) (*channeldb.LightningNode, error)

	// ForEachNode is used to iterate over every node in the known graph.
	ForEachNode(func(node *channeldb.LightningNode) error) error

	// ForEachChannel is used to iterate over every channel in the known
	// graph.
	ForEachChannel(func(chanInfo *channeldb.ChannelEdgeInfo,
		e1, e2 *channeldb.ChannelEdgePolicy) error) error
}

ChannelGraphSource represents the source of information about the topology of the lightning network. It's responsible for the addition of nodes, edges, applying edge updates, and returning the current block height with which the topology is synchronized.

type ChannelPolicy

type ChannelPolicy struct {
	// FeeSchema holds the fee configuration for a channel.
	FeeSchema

	// TimeLockDelta is the required HTLC timelock delta to be used
	// when forwarding payments.
	TimeLockDelta uint32

	// MaxHTLC is the maximum HTLC size including fees we are allowed to
	// forward over this channel.
	MaxHTLC lnwire.MilliAtom

	// MinHTLC is the minimum HTLC size including fees we are allowed to
	// forward over this channel.
	MinHTLC *lnwire.MilliAtom
}

ChannelPolicy holds the parameters that determine the policy we enforce when forwarding payments on a channel. These parameters are communicated to the rest of the network in ChannelUpdate messages.

type ChannelRouter

type ChannelRouter struct {
	sync.RWMutex
	// contains filtered or unexported fields
}

ChannelRouter is the layer 3 router within the Lightning stack. Below the ChannelRouter is the HtlcSwitch, and below that is the Bitcoin blockchain itself. The primary role of the ChannelRouter is to respond to queries for potential routes that can support a payment amount, and also general graph reachability questions. The router will prune the channel graph automatically as new blocks are discovered which spend certain known funding outpoints, thereby closing their respective channels.

func New

func New(cfg Config) (*ChannelRouter, error)

New creates a new instance of the ChannelRouter with the specified configuration parameters. As part of initialization, if the router detects that the channel graph isn't fully in sync with the latest UTXO (since the channel graph is a subset of the UTXO set) set, then the router will proceed to fully sync to the latest state of the UTXO set.

func (*ChannelRouter) AddEdge

func (r *ChannelRouter) AddEdge(edge *channeldb.ChannelEdgeInfo) error

AddEdge is used to add edge/channel to the topology of the router, after all information about channel will be gathered this edge/channel might be used in construction of payment path.

NOTE: This method is part of the ChannelGraphSource interface.

func (*ChannelRouter) AddNode

func (r *ChannelRouter) AddNode(node *channeldb.LightningNode) error

AddNode is used to add information about a node to the router database. If the node with this pubkey is not present in an existing channel, it will be ignored.

NOTE: This method is part of the ChannelGraphSource interface.

func (*ChannelRouter) AddProof

func (r *ChannelRouter) AddProof(chanID lnwire.ShortChannelID,
	proof *channeldb.ChannelAuthProof) error

AddProof updates the channel edge info with proof which is needed to properly announce the edge to the rest of the network.

NOTE: This method is part of the ChannelGraphSource interface.

func (*ChannelRouter) BuildRoute added in v0.2.0

func (r *ChannelRouter) BuildRoute(amt *lnwire.MilliAtom,
	hops []route.Vertex, outgoingChan *uint64,
	finalCltvDelta int32) (*route.Route, error)

BuildRoute returns a fully specified route based on a list of pubkeys. If amount is nil, the minimum routable amount is used. To force a specific outgoing channel, use the outgoingChan parameter.

func (*ChannelRouter) CurrentBlockHeight

func (r *ChannelRouter) CurrentBlockHeight() (uint32, error)

CurrentBlockHeight returns the block height from POV of the router subsystem.

NOTE: This method is part of the ChannelGraphSource interface.

func (*ChannelRouter) FetchLightningNode

func (r *ChannelRouter) FetchLightningNode(node route.Vertex) (*channeldb.LightningNode, error)

FetchLightningNode attempts to look up a target node by its identity public key. channeldb.ErrGraphNodeNotFound is returned if the node doesn't exist within the graph.

NOTE: This method is part of the ChannelGraphSource interface.

func (*ChannelRouter) FindRoute added in v0.2.0

func (r *ChannelRouter) FindRoute(source, target route.Vertex,
	amt lnwire.MilliAtom, restrictions *RestrictParams,
	destCustomRecords record.CustomSet,
	routeHints map[route.Vertex][]*channeldb.ChannelEdgePolicy,
	finalExpiry uint16) (*route.Route, error)

FindRoute attempts to query the ChannelRouter for the optimum path to a particular target destination to which it is able to send `amt` after factoring in channel capacities and cumulative fees along the route.

func (*ChannelRouter) ForAllOutgoingChannels

func (r *ChannelRouter) ForAllOutgoingChannels(cb func(*channeldb.ChannelEdgeInfo,
	*channeldb.ChannelEdgePolicy) error) error

ForAllOutgoingChannels is used to iterate over all outgoing channels owned by the router.

NOTE: This method is part of the ChannelGraphSource interface.

func (*ChannelRouter) ForEachChannel

func (r *ChannelRouter) ForEachChannel(cb func(chanInfo *channeldb.ChannelEdgeInfo,
	e1, e2 *channeldb.ChannelEdgePolicy) error) error

ForEachChannel is used to iterate over every known edge (channel) within our view of the channel graph.

NOTE: This method is part of the ChannelGraphSource interface.

func (*ChannelRouter) ForEachNode

func (r *ChannelRouter) ForEachNode(cb func(*channeldb.LightningNode) error) error

ForEachNode is used to iterate over every node in router topology.

NOTE: This method is part of the ChannelGraphSource interface.

func (*ChannelRouter) GetChannelByID

GetChannelByID return the channel by the channel id.

NOTE: This method is part of the ChannelGraphSource interface.

func (*ChannelRouter) IsKnownEdge

func (r *ChannelRouter) IsKnownEdge(chanID lnwire.ShortChannelID) bool

IsKnownEdge returns true if the graph source already knows of the passed channel ID either as a live or zombie edge.

NOTE: This method is part of the ChannelGraphSource interface.

func (*ChannelRouter) IsPublicNode

func (r *ChannelRouter) IsPublicNode(node route.Vertex) (bool, error)

IsPublicNode determines whether the given vertex is seen as a public node in the graph from the graph's source node's point of view.

NOTE: This method is part of the ChannelGraphSource interface.

func (*ChannelRouter) IsStaleEdgePolicy

func (r *ChannelRouter) IsStaleEdgePolicy(chanID lnwire.ShortChannelID,
	timestamp time.Time, flags lnwire.ChanUpdateChanFlags) bool

IsStaleEdgePolicy returns true if the graph source has a channel edge for the passed channel ID (and flags) that have a more recent timestamp.

NOTE: This method is part of the ChannelGraphSource interface.

func (*ChannelRouter) IsStaleNode

func (r *ChannelRouter) IsStaleNode(node route.Vertex, timestamp time.Time) bool

IsStaleNode returns true if the graph source has a node announcement for the target node with a more recent timestamp.

NOTE: This method is part of the ChannelGraphSource interface.

func (*ChannelRouter) MarkEdgeLive added in v0.2.0

func (r *ChannelRouter) MarkEdgeLive(chanID lnwire.ShortChannelID) error

MarkEdgeLive clears an edge from our zombie index, deeming it as live.

NOTE: This method is part of the ChannelGraphSource interface.

func (*ChannelRouter) SendPayment

func (r *ChannelRouter) SendPayment(payment *LightningPayment) ([32]byte,
	*route.Route, error)

SendPayment attempts to send a payment as described within the passed LightningPayment. This function is blocking and will return either: when the payment is successful, or all candidates routes have been attempted and resulted in a failed payment. If the payment succeeds, then a non-nil Route will be returned which describes the path the successful payment traversed within the network to reach the destination. Additionally, the payment preimage will also be returned.

func (*ChannelRouter) SendPaymentAsync added in v0.2.0

func (r *ChannelRouter) SendPaymentAsync(payment *LightningPayment) error

SendPaymentAsync is the non-blocking version of SendPayment. The payment result needs to be retrieved via the control tower.

func (*ChannelRouter) SendToRoute

func (r *ChannelRouter) SendToRoute(hash lntypes.Hash, rt *route.Route) (
	*channeldb.HTLCAttempt, error)

SendToRoute attempts to send a payment with the given hash through the provided route. This function is blocking and will return the attempt information as it is stored in the database. For a successful htlc, this information will contain the preimage. If an error occurs after the attempt was initiated, both return values will be non-nil.

func (*ChannelRouter) Start

func (r *ChannelRouter) Start() error

Start launches all the goroutines the ChannelRouter requires to carry out its duties. If the router has already been started, then this method is a noop.

func (*ChannelRouter) StartupPruneProgress added in v0.3.4

func (r *ChannelRouter) StartupPruneProgress() (uint32, uint32)

StartupPruneProgress returns the progress (respectively, the target height and last checked height) of the graph pruning process that happens during startup.

func (*ChannelRouter) Stop

func (r *ChannelRouter) Stop() error

Stop signals the ChannelRouter to gracefully halt all routines. This method will *block* until all goroutines have excited. If the channel router has already stopped then this method will return immediately.

func (*ChannelRouter) SubscribeTopology

func (r *ChannelRouter) SubscribeTopology() (*TopologyClient, error)

SubscribeTopology returns a new topology client which can be used by the caller to receive notifications whenever a change in the channel graph topology occurs. Changes that will be sent at notifications include: new nodes appearing, node updating their attributes, new channels, channels closing, and updates in the routing policies of a channel's directed edges.

func (*ChannelRouter) UpdateEdge

func (r *ChannelRouter) UpdateEdge(update *channeldb.ChannelEdgePolicy) error

UpdateEdge is used to update edge information, without this message edge considered as not fully constructed.

NOTE: This method is part of the ChannelGraphSource interface.

type ClosedChanSummary

type ClosedChanSummary struct {
	// ChanID is the short-channel ID which uniquely identifies the
	// channel.
	ChanID uint64

	// Capacity was the total capacity of the channel before it was closed.
	Capacity dcrutil.Amount

	// ClosedHeight is the height in the chain that the channel was closed
	// at.
	ClosedHeight uint32

	// ChanPoint is the funding point, or the multi-sig utxo which
	// previously represented the channel.
	ChanPoint wire.OutPoint
}

ClosedChanSummary is a summary of a channel that was detected as being closed by monitoring the blockchain. Once a channel's funding point has been spent, the channel will automatically be marked as closed by the ChainNotifier.

TODO(roasbeef): add nodes involved?

type Conf

type Conf struct{}

Conf provides the command line routing configuration. There are no fields in the production build so that this section is hidden by default.

func (*Conf) UseAssumeChannelValid

func (c *Conf) UseAssumeChannelValid() bool

UseAssumeChannelValid always returns false when not in experimental builds.

type Config

type Config struct {
	// Graph is the channel graph that the ChannelRouter will use to gather
	// metrics from and also to carry out path finding queries.
	// TODO(roasbeef): make into an interface
	Graph *channeldb.ChannelGraph

	// Chain is the router's source to the most up-to-date blockchain data.
	// All incoming advertised channels will be checked against the chain
	// to ensure that the channels advertised are still open.
	Chain lnwallet.BlockChainIO

	// ChainView is an instance of a FilteredChainView which is used to
	// watch the sub-set of the UTXO set (the set of active channels) that
	// we need in order to properly maintain the channel graph.
	ChainView chainview.FilteredChainView

	// Payer is an instance of a PaymentAttemptDispatcher and is used by
	// the router to send payment attempts onto the network, and receive
	// their results.
	Payer PaymentAttemptDispatcher

	// Control keeps track of the status of ongoing payments, ensuring we
	// can properly resume them across restarts.
	Control ControlTower

	// MissionControl is a shared memory of sorts that executions of
	// payment path finding use in order to remember which vertexes/edges
	// were pruned from prior attempts. During SendPayment execution,
	// errors sent by nodes are mapped into a vertex or edge to be pruned.
	// Each run will then take into account this set of pruned
	// vertexes/edges to reduce route failure and pass on graph information
	// gained to the next execution.
	MissionControl MissionController

	// SessionSource defines a source for the router to retrieve new payment
	// sessions.
	SessionSource PaymentSessionSource

	// ChannelPruneExpiry is the duration used to determine if a channel
	// should be pruned or not. If the delta between now and when the
	// channel was last updated is greater than ChannelPruneExpiry, then
	// the channel is marked as a zombie channel eligible for pruning.
	ChannelPruneExpiry time.Duration

	// GraphPruneInterval is used as an interval to determine how often we
	// should examine the channel graph to garbage collect zombie channels.
	GraphPruneInterval time.Duration

	// QueryBandwidth is a method that allows the router to query the lower
	// link layer to determine the up to date available bandwidth at a
	// prospective link to be traversed. If the  link isn't available, then
	// a value of zero should be returned. Otherwise, the current up to
	// date knowledge of the available bandwidth of the link should be
	// returned.
	QueryBandwidth func(edge *channeldb.ChannelEdgeInfo) lnwire.MilliAtom

	// NextPaymentID is a method that guarantees to return a new, unique ID
	// each time it is called. This is used by the router to generate a
	// unique payment ID for each payment it attempts to send, such that
	// the switch can properly handle the HTLC.
	NextPaymentID func() (uint64, error)

	// AssumeChannelValid toggles whether or not the router will check for
	// spentness of channel outpoints. For neutrino, this saves long rescans
	// from blocking initial usage of the daemon.
	AssumeChannelValid bool

	// PathFindingConfig defines global path finding parameters.
	PathFindingConfig PathFindingConfig

	// Clock is mockable time provider.
	Clock clock.Clock
}

Config defines the configuration for the ChannelRouter. ALL elements within the configuration MUST be non-nil for the ChannelRouter to carry out its duties.

type ControlTower added in v0.2.0

type ControlTower interface {
	// This method checks that no suceeded payment exist for this payment
	// hash.
	InitPayment(lntypes.Hash, *channeldb.PaymentCreationInfo) error

	// RegisterAttempt atomically records the provided HTLCAttemptInfo.
	RegisterAttempt(lntypes.Hash, *channeldb.HTLCAttemptInfo) error

	// SettleAttempt marks the given attempt settled with the preimage. If
	// this is a multi shard payment, this might implicitly mean the the
	// full payment succeeded.
	//
	// After invoking this method, InitPayment should always return an
	// error to prevent us from making duplicate payments to the same
	// payment hash. The provided preimage is atomically saved to the DB
	// for record keeping.
	SettleAttempt(lntypes.Hash, uint64, *channeldb.HTLCSettleInfo) (
		*channeldb.HTLCAttempt, error)

	// FailAttempt marks the given payment attempt failed.
	FailAttempt(lntypes.Hash, uint64, *channeldb.HTLCFailInfo) (
		*channeldb.HTLCAttempt, error)

	// FetchPayment fetches the payment corresponding to the given payment
	// hash.
	FetchPayment(paymentHash lntypes.Hash) (*channeldb.MPPayment, error)

	// Fail transitions a payment into the Failed state, and records the
	// ultimate reason the payment failed. Note that this should only be
	// called when all active active attempts are already failed. After
	// invoking this method, InitPayment should return nil on its next call
	// for this payment hash, allowing the user to make a subsequent
	// payment.
	Fail(lntypes.Hash, channeldb.FailureReason) error

	// FetchInFlightPayments returns all payments with status InFlight.
	FetchInFlightPayments() ([]*channeldb.InFlightPayment, error)

	// SubscribePayment subscribes to updates for the payment with the given
	// hash. A first update with the current state of the payment is always
	// sent out immediately.
	SubscribePayment(paymentHash lntypes.Hash) (*ControlTowerSubscriber,
		error)
}

ControlTower tracks all outgoing payments made, whose primary purpose is to prevent duplicate payments to the same payment hash. In production, a persistent implementation is preferred so that tracking can survive across restarts. Payments are transitioned through various payment states, and the ControlTower interface provides access to driving the state transitions.

func NewControlTower added in v0.2.0

func NewControlTower(db *channeldb.PaymentControl) ControlTower

NewControlTower creates a new instance of the controlTower.

type ControlTowerSubscriber added in v0.3.0

type ControlTowerSubscriber struct {
	// Updates is the channel over which *channeldb.MPPayment updates can be
	// received.
	Updates <-chan interface{}
	// contains filtered or unexported fields
}

ControlTowerSubscriber contains the state for a payment update subscriber.

func (*ControlTowerSubscriber) Close added in v0.3.0

func (s *ControlTowerSubscriber) Close()

Close signals that the subscriber is no longer interested in updates.

type DirectedNodePair added in v0.2.0

type DirectedNodePair struct {
	From, To route.Vertex
}

DirectedNodePair stores a directed pair of nodes.

func NewDirectedNodePair added in v0.2.0

func NewDirectedNodePair(from, to route.Vertex) DirectedNodePair

NewDirectedNodePair instantiates a new DirectedNodePair struct.

func (DirectedNodePair) Reverse added in v0.2.0

func (d DirectedNodePair) Reverse() DirectedNodePair

Reverse returns a reversed copy of the pair.

func (DirectedNodePair) String added in v0.2.0

func (d DirectedNodePair) String() string

String converts a node pair to its human readable representation.

type EdgeLocator added in v0.2.0

type EdgeLocator struct {
	// ChannelID is the channel of this edge.
	ChannelID uint64

	// Direction takes the value of 0 or 1 and is identical in definition to
	// the channel direction flag. A value of 0 means the direction from the
	// lower node pubkey to the higher.
	Direction uint8
}

EdgeLocator is a struct used to identify a specific edge.

func (*EdgeLocator) String added in v0.2.0

func (e *EdgeLocator) String() string

String returns a human readable version of the edgeLocator values.

type ErrNoChannel added in v0.2.0

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

ErrNoChannel is returned when a route cannot be built because there are no channels that satisfy all requirements.

func (ErrNoChannel) Error added in v0.2.0

func (e ErrNoChannel) Error() string

Error returns a human readable string describing the error.

type FeeSchema

type FeeSchema struct {
	// BaseFee is the base amount of milli-atoms that will be chained
	// for ANY payment forwarded.
	BaseFee lnwire.MilliAtom

	// FeeRate is the rate that will be charged for forwarding payments.
	// This value should be interpreted as the numerator for a fraction
	// (fixed point arithmetic) whose denominator is 1 million. As a result
	// the effective fee rate charged per milli-atoms will be: (amount *
	// FeeRate/1,000,000).
	FeeRate uint32
}

FeeSchema is the set fee configuration for a Lightning Node on the network. Using the coefficients described within the schema, the required fee to forward outgoing payments can be derived.

type LightningPayment

type LightningPayment struct {
	// Target is the node in which the payment should be routed towards.
	Target route.Vertex

	// Amount is the value of the payment to send through the network in
	// milli-atoms.
	Amount lnwire.MilliAtom

	// FeeLimit is the maximum fee in MilliAtoms that the payment should
	// accept when sending it through the network. The payment will fail
	// if there isn't a route with lower fees than this limit.
	FeeLimit lnwire.MilliAtom

	// CltvLimit is the maximum time lock that is allowed for attempts to
	// complete this payment.
	CltvLimit uint32

	// PaymentHash is the r-hash value to use within the HTLC extended to
	// the first hop.
	PaymentHash [32]byte

	// FinalCLTVDelta is the CTLV expiry delta to use for the _final_ hop
	// in the route. This means that the final hop will have a CLTV delta
	// of at least: currentHeight + FinalCLTVDelta.
	FinalCLTVDelta uint16

	// PayAttemptTimeout is a timeout value that we'll use to determine
	// when we should should abandon the payment attempt after consecutive
	// payment failure. This prevents us from attempting to send a payment
	// indefinitely. A zero value means the payment will never time out.
	//
	// TODO(halseth): make wallclock time to allow resume after startup.
	PayAttemptTimeout time.Duration

	// RouteHints represents the different routing hints that can be used to
	// assist a payment in reaching its destination successfully. These
	// hints will act as intermediate hops along the route.
	//
	// NOTE: This is optional unless required by the payment. When providing
	// multiple routes, ensure the hop hints within each route are chained
	// together and sorted in forward order in order to reach the
	// destination successfully.
	RouteHints [][]zpay32.HopHint

	// OutgoingChannelIDs is the list of channels that are allowed for the
	// first hop. If nil, any channel may be used.
	OutgoingChannelIDs []uint64

	// LastHop is the pubkey of the last node before the final destination
	// is reached. If nil, any node may be used.
	LastHop *route.Vertex

	// DestFeatures specifies the set of features we assume the final node
	// has for pathfinding. Typically these will be taken directly from an
	// invoice, but they can also be manually supplied or assumed by the
	// sender. If a nil feature vector is provided, the router will try to
	// fallback to the graph in order to load a feature vector for a node in
	// the public graph.
	DestFeatures *lnwire.FeatureVector

	// PaymentAddr is the payment address specified by the receiver. This
	// field should be a random 32-byte nonce presented in the receiver's
	// invoice to prevent probing of the destination.
	PaymentAddr *[32]byte

	// PaymentRequest is an optional payment request that this payment is
	// attempting to complete.
	PaymentRequest []byte

	// DestCustomRecords are TLV records that are to be sent to the final
	// hop in the new onion payload format. If the destination does not
	// understand this new onion payload format, then the payment will
	// fail.
	DestCustomRecords record.CustomSet

	// MaxParts is the maximum number of partial payments that may be used
	// to complete the full amount.
	MaxParts uint32
}

LightningPayment describes a payment to be sent through the network to the final destination.

type MissionControl added in v0.2.0

type MissionControl struct {
	sync.Mutex
	// contains filtered or unexported fields
}

MissionControl contains state which summarizes the past attempts of HTLC routing by external callers when sending payments throughout the network. It acts as a shared memory during routing attempts with the goal to optimize the payment attempt success rate.

Failed payment attempts are reported to mission control. These reports are used to track the time of the last node or channel level failure. The time since the last failure is used to estimate a success probability that is fed into the path finding process for subsequent payment attempts.

func NewMissionControl added in v0.2.0

func NewMissionControl(db kvdb.Backend, cfg *MissionControlConfig) (
	*MissionControl, error)

NewMissionControl returns a new instance of missionControl.

func (*MissionControl) GetHistorySnapshot added in v0.2.0

func (m *MissionControl) GetHistorySnapshot() *MissionControlSnapshot

GetHistorySnapshot takes a snapshot from the current mission control state and actual probability estimates.

func (*MissionControl) GetPairHistorySnapshot added in v0.3.0

func (m *MissionControl) GetPairHistorySnapshot(
	fromNode, toNode route.Vertex) TimedPairResult

GetPairHistorySnapshot returns the stored history for a given node pair.

func (*MissionControl) GetProbability added in v0.2.0

func (m *MissionControl) GetProbability(fromNode, toNode route.Vertex,
	amt lnwire.MilliAtom) float64

GetProbability is expected to return the success probability of a payment from fromNode along edge.

func (*MissionControl) ReportPaymentFail added in v0.2.0

func (m *MissionControl) ReportPaymentFail(paymentID uint64, rt *route.Route,
	failureSourceIdx *int, failure lnwire.FailureMessage) (
	*channeldb.FailureReason, error)

ReportPaymentFail reports a failed payment to mission control as input for future probability estimates. The failureSourceIdx argument indicates the failure source. If it is nil, the failure source is unknown. This function returns a reason if this failure is a final failure. In that case no further payment attempts need to be made.

func (*MissionControl) ReportPaymentSuccess added in v0.2.0

func (m *MissionControl) ReportPaymentSuccess(paymentID uint64,
	rt *route.Route) error

ReportPaymentSuccess reports a successful payment to mission control as input for future probability estimates.

func (*MissionControl) ResetHistory added in v0.2.0

func (m *MissionControl) ResetHistory() error

ResetHistory resets the history of MissionControl returning it to a state as if no payment attempts have been made.

type MissionControlConfig added in v0.2.0

type MissionControlConfig struct {
	// PenaltyHalfLife defines after how much time a penalized node or
	// channel is back at 50% probability.
	PenaltyHalfLife time.Duration

	// AprioriHopProbability is the assumed success probability of a hop in
	// a route when no other information is available.
	AprioriHopProbability float64

	// MaxMcHistory defines the maximum number of payment results that are
	// held on disk.
	MaxMcHistory int

	// AprioriWeight is a value in the range [0, 1] that defines to what
	// extent historical results should be extrapolated to untried
	// connections. Setting it to one will completely ignore historical
	// results and always assume the configured a priori probability for
	// untried connections. A value of zero will ignore the a priori
	// probability completely and only base the probability on historical
	// results, unless there are none available.
	AprioriWeight float64

	// MinFailureRelaxInterval is the minimum time that must have passed
	// since the previously recorded failure before the failure amount may
	// be raised.
	MinFailureRelaxInterval time.Duration

	// SelfNode is our own pubkey.
	SelfNode route.Vertex
}

MissionControlConfig defines parameters that control mission control behaviour.

type MissionControlPairSnapshot added in v0.2.0

type MissionControlPairSnapshot struct {
	// Pair is the node pair of which the state is described.
	Pair DirectedNodePair

	// TimedPairResult contains the data for this pair.
	TimedPairResult
}

MissionControlPairSnapshot contains a snapshot of the current node pair state in mission control.

type MissionControlSnapshot added in v0.2.0

type MissionControlSnapshot struct {
	// Pairs is a list of channels for which specific information is
	// logged.
	Pairs []MissionControlPairSnapshot
}

MissionControlSnapshot contains a snapshot of the current state of mission control.

type MissionController added in v0.2.0

type MissionController interface {
	// ReportPaymentFail reports a failed payment to mission control as
	// input for future probability estimates. It returns a bool indicating
	// whether this error is a final error and no further payment attempts
	// need to be made.
	ReportPaymentFail(paymentID uint64, rt *route.Route,
		failureSourceIdx *int, failure lnwire.FailureMessage) (
		*channeldb.FailureReason, error)

	// ReportPaymentSuccess reports a successful payment to mission control as input
	// for future probability estimates.
	ReportPaymentSuccess(paymentID uint64, rt *route.Route) error

	// GetProbability is expected to return the success probability of a
	// payment from fromNode along edge.
	GetProbability(fromNode, toNode route.Vertex,
		amt lnwire.MilliAtom) float64
}

MissionController is an interface that exposes failure reporting and probability estimation.

type NetworkNodeUpdate

type NetworkNodeUpdate struct {
	// Addresses is a slice of all the node's known addresses.
	Addresses []net.Addr

	// IdentityKey is the identity public key of the target node. This is
	// used to encrypt onion blobs as well as to authenticate any new
	// updates.
	IdentityKey *secp256k1.PublicKey

	// GlobalFeatures is a set of opaque bytes that describe the set of
	// features supported by the node.
	GlobalFeatures []byte

	// Alias is the alias or nick name of the node.
	Alias string

	// Color is the node's color in hex code format.
	Color string
}

NetworkNodeUpdate is an update for a node within the Lightning Network. A NetworkNodeUpdate is sent out either when a new node joins the network, or a node broadcasts a new update with a newer time stamp that supersedes its old update. All updates are properly authenticated.

type NodeResults added in v0.3.0

type NodeResults map[route.Vertex]TimedPairResult

NodeResults contains previous results from a node to its peers.

type PathFindingConfig added in v0.2.0

type PathFindingConfig struct {
	// PaymentAttemptPenalty is the virtual cost in path finding weight
	// units of executing a payment attempt that fails. It is used to trade
	// off potentially better routes against their probability of
	// succeeding.
	PaymentAttemptPenalty lnwire.MilliAtom

	// MinProbability defines the minimum success probability of the
	// returned route.
	MinProbability float64
}

PathFindingConfig defines global parameters that control the trade-off in path finding between fees and probabiity.

type PaymentAttemptDispatcher added in v0.2.0

type PaymentAttemptDispatcher interface {
	// SendHTLC is a function that directs a link-layer switch to
	// forward a fully encoded payment to the first hop in the route
	// denoted by its public key. A non-nil error is to be returned if the
	// payment was unsuccessful.
	SendHTLC(firstHop lnwire.ShortChannelID,
		paymentID uint64,
		htlcAdd *lnwire.UpdateAddHTLC) error

	// GetPaymentResult returns the the result of the payment attempt with
	// the given paymentID. The method returns a channel where the payment
	// result will be sent when available, or an error is encountered
	// during forwarding. When a result is received on the channel, the
	// HTLC is guaranteed to no longer be in flight. The switch shutting
	// down is signaled by closing the channel. If the paymentID is
	// unknown, ErrPaymentIDNotFound will be returned.
	GetPaymentResult(paymentID uint64, paymentHash lntypes.Hash,
		deobfuscator htlcswitch.ErrorDecrypter) (
		<-chan *htlcswitch.PaymentResult, error)
}

PaymentAttemptDispatcher is used by the router to send payment attempts onto the network, and receive their results.

type PaymentSession added in v0.2.0

type PaymentSession interface {
	// RequestRoute returns the next route to attempt for routing the
	// specified HTLC payment to the target node. The returned route should
	// carry at most maxAmt to the target node, and pay at most feeLimit in
	// fees. It can carry less if the payment is MPP. The activeShards
	// argument should be set to instruct the payment session about the
	// number of in flight HTLCS for the payment, such that it can choose
	// splitting strategy accordingly.
	//
	// A noRouteError is returned if a non-critical error is encountered
	// during path finding.
	RequestRoute(maxAmt, feeLimit lnwire.MilliAtom,
		activeShards, height uint32) (*route.Route, error)
}

PaymentSession is used during SendPayment attempts to provide routes to attempt. It also defines methods to give the PaymentSession additional information learned during the previous attempts.

type PaymentSessionSource added in v0.2.0

type PaymentSessionSource interface {
	// NewPaymentSession creates a new payment session that will produce
	// routes to the given target. An optional set of routing hints can be
	// provided in order to populate additional edges to explore when
	// finding a path to the payment's destination.
	NewPaymentSession(p *LightningPayment) (PaymentSession, error)

	// NewPaymentSessionEmpty creates a new paymentSession instance that is
	// empty, and will be exhausted immediately. Used for failure reporting
	// to missioncontrol for resumed payment we don't want to make more
	// attempts for.
	NewPaymentSessionEmpty() PaymentSession
}

PaymentSessionSource is an interface that defines a source for the router to retrive new payment sessions.

type RestrictParams added in v0.2.0

type RestrictParams struct {
	// ProbabilitySource is a callback that is expected to return the
	// success probability of traversing the channel from the node.
	ProbabilitySource func(route.Vertex, route.Vertex,
		lnwire.MilliAtom) float64

	// FeeLimit is a maximum fee amount allowed to be used on the path from
	// the source to the target.
	FeeLimit lnwire.MilliAtom

	// OutgoingChannelIDs is the list of channels that are allowed for the
	// first hop. If nil, any channel may be used.
	OutgoingChannelIDs []uint64

	// LastHop is the pubkey of the last node before the final destination
	// is reached. If nil, any node may be used.
	LastHop *route.Vertex

	// CltvLimit is the maximum time lock of the route excluding the final
	// ctlv. After path finding is complete, the caller needs to increase
	// all cltv expiry heights with the required final cltv delta.
	CltvLimit uint32

	// DestCustomRecords contains the custom records to drop off at the
	// final hop, if any.
	DestCustomRecords record.CustomSet

	// DestFeatures is a feature vector describing what the final hop
	// supports. If none are provided, pathfinding will try to inspect any
	// features on the node announcement instead.
	DestFeatures *lnwire.FeatureVector

	// PaymentAddr is a random 32-byte value generated by the receiver to
	// mitigate probing vectors and payment sniping attacks on overpaid
	// invoices.
	PaymentAddr *[32]byte
}

RestrictParams wraps the set of restrictions passed to findPath that the found path must adhere to.

type SessionSource added in v0.2.0

type SessionSource struct {
	// Graph is the channel graph that will be used to gather metrics from
	// and also to carry out path finding queries.
	Graph *channeldb.ChannelGraph

	// QueryBandwidth is a method that allows querying the lower link layer
	// to determine the up to date available bandwidth at a prospective link
	// to be traversed. If the link isn't available, then a value of zero
	// should be returned. Otherwise, the current up to date knowledge of
	// the available bandwidth of the link should be returned.
	QueryBandwidth func(*channeldb.ChannelEdgeInfo) lnwire.MilliAtom

	// MissionControl is a shared memory of sorts that executions of payment
	// path finding use in order to remember which vertexes/edges were
	// pruned from prior attempts. During payment execution, errors sent by
	// nodes are mapped into a vertex or edge to be pruned. Each run will
	// then take into account this set of pruned vertexes/edges to reduce
	// route failure and pass on graph information gained to the next
	// execution.
	MissionControl MissionController

	// PathFindingConfig defines global parameters that control the
	// trade-off in path finding between fees and probabiity.
	PathFindingConfig PathFindingConfig
}

SessionSource defines a source for the router to retrieve new payment sessions.

func (*SessionSource) NewPaymentSession added in v0.2.0

func (m *SessionSource) NewPaymentSession(p *LightningPayment) (
	PaymentSession, error)

NewPaymentSession creates a new payment session backed by the latest prune view from Mission Control. An optional set of routing hints can be provided in order to populate additional edges to explore when finding a path to the payment's destination.

func (*SessionSource) NewPaymentSessionEmpty added in v0.2.0

func (m *SessionSource) NewPaymentSessionEmpty() PaymentSession

NewPaymentSessionEmpty creates a new paymentSession instance that is empty, and will be exhausted immediately. Used for failure reporting to missioncontrol for resumed payment we don't want to make more attempts for.

type TimedPairResult added in v0.3.0

type TimedPairResult struct {
	// FailTime is the time of the last failure.
	FailTime time.Time

	// FailAmt is the amount of the last failure. This amount may be pushed
	// up if a later success is higher than the last failed amount.
	FailAmt lnwire.MilliAtom

	// SuccessTime is the time of the last success.
	SuccessTime time.Time

	// SuccessAmt is the highest amount that successfully forwarded. This
	// isn't necessarily the last success amount. The value of this field
	// may also be pushed down if a later failure is lower than the highest
	// success amount. Because of this, SuccessAmt may not match
	// SuccessTime.
	SuccessAmt lnwire.MilliAtom
}

TimedPairResult describes a timestamped pair result.

type TopologyChange

type TopologyChange struct {
	// NodeUpdates is a slice of nodes which are either new to the channel
	// graph, or have had their attributes updated in an authenticated
	// manner.
	NodeUpdates []*NetworkNodeUpdate

	// ChanelEdgeUpdates is a slice of channel edges which are either newly
	// opened and authenticated, or have had their routing policies
	// updated.
	ChannelEdgeUpdates []*ChannelEdgeUpdate

	// ClosedChannels contains a slice of close channel summaries which
	// described which block a channel was closed at, and also carry
	// supplemental information such as the capacity of the former channel.
	ClosedChannels []*ClosedChanSummary
}

TopologyChange represents a new set of modifications to the channel graph. Topology changes will be dispatched in real-time as the ChannelGraph validates and process modifications to the authenticated channel graph.

type TopologyClient

type TopologyClient struct {
	// TopologyChanges is a receive only channel that new channel graph
	// updates will be sent over.
	//
	// TODO(roasbeef): chan for each update type instead?
	TopologyChanges <-chan *TopologyChange

	// Cancel is a function closure that should be executed when the client
	// wishes to cancel their notification intent. Doing so allows the
	// ChannelRouter to free up resources.
	Cancel func()
}

TopologyClient represents an intent to receive notifications from the channel router regarding changes to the topology of the channel graph. The TopologyChanges channel will be sent upon with new updates to the channel graph in real-time as they're encountered.

type ValidationBarrier

type ValidationBarrier struct {
	sync.Mutex
	// contains filtered or unexported fields
}

ValidationBarrier is a barrier used to ensure proper validation order while concurrently validating new announcements for channel edges, and the attributes of channel edges. It uses this set of maps (protected by this mutex) to track validation dependencies. For a given channel our dependencies look like this: chanAnn <- chanUp <- nodeAnn. That is we must validate the item on the left of the arrow before that on the right.

func NewValidationBarrier

func NewValidationBarrier(numActiveReqs int,
	quitChan chan struct{}) *ValidationBarrier

NewValidationBarrier creates a new instance of a validation barrier given the total number of active requests, and a quit channel which will be used to know when to kill pending, but unfilled jobs.

func (*ValidationBarrier) CompleteJob

func (v *ValidationBarrier) CompleteJob()

CompleteJob returns a free slot to the set of available job slots. This should be called once a job has been fully completed. Otherwise, slots may not be returned to the internal scheduling, causing a deadlock when a new overflow job is attempted.

func (*ValidationBarrier) InitJobDependencies

func (v *ValidationBarrier) InitJobDependencies(job interface{})

InitJobDependencies will wait for a new job slot to become open, and then sets up any dependent signals/trigger for the new job

func (*ValidationBarrier) SignalDependants

func (v *ValidationBarrier) SignalDependants(job interface{})

SignalDependants will signal any jobs that are dependent on this job that they can continue execution. If the job doesn't have any dependants, then this function sill exit immediately.

func (*ValidationBarrier) WaitForDependants

func (v *ValidationBarrier) WaitForDependants(job interface{}) error

WaitForDependants will block until any jobs that this job dependants on have finished executing. This allows us a graceful way to schedule goroutines based on any pending uncompleted dependent jobs. If this job doesn't have an active dependent, then this function will return immediately.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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