mirror of
https://github.com/lightningnetwork/lnd.git
synced 2024-11-19 09:53:54 +01:00
be84d6974e
..which describes the database methods that are required for graph maintaining and building.
281 lines
13 KiB
Go
281 lines
13 KiB
Go
package graph
|
|
|
|
import (
|
|
"time"
|
|
|
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
|
"github.com/btcsuite/btcd/wire"
|
|
"github.com/lightningnetwork/lnd/batch"
|
|
"github.com/lightningnetwork/lnd/channeldb"
|
|
"github.com/lightningnetwork/lnd/channeldb/models"
|
|
"github.com/lightningnetwork/lnd/kvdb"
|
|
"github.com/lightningnetwork/lnd/lnwire"
|
|
"github.com/lightningnetwork/lnd/routing/route"
|
|
)
|
|
|
|
// 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.
|
|
//
|
|
//nolint:interfacebloat
|
|
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,
|
|
op ...batch.SchedulerOption) 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 *models.ChannelEdgeInfo,
|
|
op ...batch.SchedulerOption) 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 *models.ChannelAuthProof) error
|
|
|
|
// UpdateEdge is used to update edge information, without this message
|
|
// edge considered as not fully constructed.
|
|
UpdateEdge(policy *models.ChannelEdgePolicy,
|
|
op ...batch.SchedulerOption) 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(tx kvdb.RTx,
|
|
c *models.ChannelEdgeInfo,
|
|
e *models.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) (
|
|
*models.ChannelEdgeInfo, *models.ChannelEdgePolicy,
|
|
*models.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
|
|
}
|
|
|
|
// DB is an interface describing a persisted Lightning Network graph.
|
|
//
|
|
//nolint:interfacebloat
|
|
type DB interface {
|
|
// PruneTip returns the block height and hash of the latest block that
|
|
// has been used to prune channels in the graph. Knowing the "prune tip"
|
|
// allows callers to tell if the graph is currently in sync with the
|
|
// current best known UTXO state.
|
|
PruneTip() (*chainhash.Hash, uint32, error)
|
|
|
|
// PruneGraph prunes newly closed channels from the channel graph in
|
|
// response to a new block being solved on the network. Any transactions
|
|
// which spend the funding output of any known channels within the graph
|
|
// will be deleted. Additionally, the "prune tip", or the last block
|
|
// which has been used to prune the graph is stored so callers can
|
|
// ensure the graph is fully in sync with the current UTXO state. A
|
|
// slice of channels that have been closed by the target block are
|
|
// returned if the function succeeds without error.
|
|
PruneGraph(spentOutputs []*wire.OutPoint, blockHash *chainhash.Hash,
|
|
blockHeight uint32) ([]*models.ChannelEdgeInfo, error)
|
|
|
|
// ChannelView returns the verifiable edge information for each active
|
|
// channel within the known channel graph. The set of UTXO's (along with
|
|
// their scripts) returned are the ones that need to be watched on
|
|
// chain to detect channel closes on the resident blockchain.
|
|
ChannelView() ([]channeldb.EdgePoint, error)
|
|
|
|
// PruneGraphNodes is a garbage collection method which attempts to
|
|
// prune out any nodes from the channel graph that are currently
|
|
// unconnected. This ensure that we only maintain a graph of reachable
|
|
// nodes. In the event that a pruned node gains more channels, it will
|
|
// be re-added back to the graph.
|
|
PruneGraphNodes() error
|
|
|
|
// SourceNode returns the source node of the graph. The source node is
|
|
// treated as the center node within a star-graph. This method may be
|
|
// used to kick off a path finding algorithm in order to explore the
|
|
// reachability of another node based off the source node.
|
|
SourceNode() (*channeldb.LightningNode, error)
|
|
|
|
// DisabledChannelIDs returns the channel ids of disabled channels.
|
|
// A channel is disabled when two of the associated ChanelEdgePolicies
|
|
// have their disabled bit on.
|
|
DisabledChannelIDs() ([]uint64, error)
|
|
|
|
// FetchChanInfos returns the set of channel edges that correspond to
|
|
// the passed channel ID's. If an edge is the query is unknown to the
|
|
// database, it will skipped and the result will contain only those
|
|
// edges that exist at the time of the query. This can be used to
|
|
// respond to peer queries that are seeking to fill in gaps in their
|
|
// view of the channel graph.
|
|
FetchChanInfos(chanIDs []uint64) ([]channeldb.ChannelEdge, error)
|
|
|
|
// ChanUpdatesInHorizon returns all the known channel edges which have
|
|
// at least one edge that has an update timestamp within the specified
|
|
// horizon.
|
|
ChanUpdatesInHorizon(startTime, endTime time.Time) (
|
|
[]channeldb.ChannelEdge, error)
|
|
|
|
// DeleteChannelEdges removes edges with the given channel IDs from the
|
|
// database and marks them as zombies. This ensures that we're unable to
|
|
// re-add it to our database once again. If an edge does not exist
|
|
// within the database, then ErrEdgeNotFound will be returned. If
|
|
// strictZombiePruning is true, then when we mark these edges as
|
|
// zombies, we'll set up the keys such that we require the node that
|
|
// failed to send the fresh update to be the one that resurrects the
|
|
// channel from its zombie state. The markZombie bool denotes whether
|
|
// to mark the channel as a zombie.
|
|
DeleteChannelEdges(strictZombiePruning, markZombie bool,
|
|
chanIDs ...uint64) error
|
|
|
|
// DisconnectBlockAtHeight is used to indicate that the block specified
|
|
// by the passed height has been disconnected from the main chain. This
|
|
// will "rewind" the graph back to the height below, deleting channels
|
|
// that are no longer confirmed from the graph. The prune log will be
|
|
// set to the last prune height valid for the remaining chain.
|
|
// Channels that were removed from the graph resulting from the
|
|
// disconnected block are returned.
|
|
DisconnectBlockAtHeight(height uint32) ([]*models.ChannelEdgeInfo,
|
|
error)
|
|
|
|
// HasChannelEdge returns true if the database knows of a channel edge
|
|
// with the passed channel ID, and false otherwise. If an edge with that
|
|
// ID is found within the graph, then two time stamps representing the
|
|
// last time the edge was updated for both directed edges are returned
|
|
// along with the boolean. If it is not found, then the zombie index is
|
|
// checked and its result is returned as the second boolean.
|
|
HasChannelEdge(chanID uint64) (time.Time, time.Time, bool, bool, error)
|
|
|
|
// FetchChannelEdgesByID attempts to lookup the two directed edges for
|
|
// the channel identified by the channel ID. If the channel can't be
|
|
// found, then ErrEdgeNotFound is returned. A struct which houses the
|
|
// general information for the channel itself is returned as well as
|
|
// two structs that contain the routing policies for the channel in
|
|
// either direction.
|
|
//
|
|
// ErrZombieEdge an be returned if the edge is currently marked as a
|
|
// zombie within the database. In this case, the ChannelEdgePolicy's
|
|
// will be nil, and the ChannelEdgeInfo will only include the public
|
|
// keys of each node.
|
|
FetchChannelEdgesByID(chanID uint64) (*models.ChannelEdgeInfo,
|
|
*models.ChannelEdgePolicy, *models.ChannelEdgePolicy, error)
|
|
|
|
// AddLightningNode adds a vertex/node to the graph database. If the
|
|
// node is not in the database from before, this will add a new,
|
|
// unconnected one to the graph. If it is present from before, this will
|
|
// update that node's information. Note that this method is expected to
|
|
// only be called to update an already present node from a node
|
|
// announcement, or to insert a node found in a channel update.
|
|
AddLightningNode(node *channeldb.LightningNode,
|
|
op ...batch.SchedulerOption) error
|
|
|
|
// AddChannelEdge adds a new (undirected, blank) edge to the graph
|
|
// database. An undirected edge from the two target nodes are created.
|
|
// The information stored denotes the static attributes of the channel,
|
|
// such as the channelID, the keys involved in creation of the channel,
|
|
// and the set of features that the channel supports. The chanPoint and
|
|
// chanID are used to uniquely identify the edge globally within the
|
|
// database.
|
|
AddChannelEdge(edge *models.ChannelEdgeInfo,
|
|
op ...batch.SchedulerOption) error
|
|
|
|
// MarkEdgeZombie attempts to mark a channel identified by its channel
|
|
// ID as a zombie. This method is used on an ad-hoc basis, when channels
|
|
// need to be marked as zombies outside the normal pruning cycle.
|
|
MarkEdgeZombie(chanID uint64, pubKey1, pubKey2 [33]byte) error
|
|
|
|
// UpdateEdgePolicy updates the edge routing policy for a single
|
|
// directed edge within the database for the referenced channel. The
|
|
// `flags` attribute within the ChannelEdgePolicy determines which of
|
|
// the directed edges are being updated. If the flag is 1, then the
|
|
// first node's information is being updated, otherwise it's the second
|
|
// node's information. The node ordering is determined by the
|
|
// lexicographical ordering of the identity public keys of the nodes on
|
|
// either side of the channel.
|
|
UpdateEdgePolicy(edge *models.ChannelEdgePolicy,
|
|
op ...batch.SchedulerOption) error
|
|
|
|
// HasLightningNode determines if the graph has a vertex identified by
|
|
// the target node identity public key. If the node exists in the
|
|
// database, a timestamp of when the data for the node was lasted
|
|
// updated is returned along with a true boolean. Otherwise, an empty
|
|
// time.Time is returned with a false boolean.
|
|
HasLightningNode(nodePub [33]byte) (time.Time, bool, error)
|
|
|
|
// FetchLightningNode attempts to look up a target node by its identity
|
|
// public key. If the node isn't found in the database, then
|
|
// ErrGraphNodeNotFound is returned.
|
|
FetchLightningNode(nodePub route.Vertex) (*channeldb.LightningNode,
|
|
error)
|
|
|
|
// ForEachNode iterates through all the stored vertices/nodes in the
|
|
// graph, executing the passed callback with each node encountered. If
|
|
// the callback returns an error, then the transaction is aborted and
|
|
// the iteration stops early.
|
|
ForEachNode(cb func(kvdb.RTx, *channeldb.LightningNode) error) error
|
|
|
|
// ForEachNodeChannel iterates through all channels of the given node,
|
|
// executing the passed callback with an edge info structure and the
|
|
// policies of each end of the channel. The first edge policy is the
|
|
// outgoing edge *to* the connecting node, while the second is the
|
|
// incoming edge *from* the connecting node. If the callback returns an
|
|
// error, then the iteration is halted with the error propagated back up
|
|
// to the caller.
|
|
//
|
|
// Unknown policies are passed into the callback as nil values.
|
|
ForEachNodeChannel(nodePub route.Vertex, cb func(kvdb.RTx,
|
|
*models.ChannelEdgeInfo,
|
|
*models.ChannelEdgePolicy,
|
|
*models.ChannelEdgePolicy) error) error
|
|
|
|
// UpdateChannelEdge retrieves and update edge of the graph database.
|
|
// Method only reserved for updating an edge info after its already been
|
|
// created. In order to maintain this constraints, we return an error in
|
|
// the scenario that an edge info hasn't yet been created yet, but
|
|
// someone attempts to update it.
|
|
UpdateChannelEdge(edge *models.ChannelEdgeInfo) error
|
|
|
|
// IsPublicNode is a helper method that determines whether the node with
|
|
// the given public key is seen as a public node in the graph from the
|
|
// graph's source node's point of view.
|
|
IsPublicNode(pubKey [33]byte) (bool, error)
|
|
|
|
// MarkEdgeLive clears an edge from our zombie index, deeming it as
|
|
// live.
|
|
MarkEdgeLive(chanID uint64) error
|
|
}
|