multi: move LightningNode struct to models package

This commit is contained in:
Elle Mouton committed 2024-11-28 13:36:32 +02:00
1 parent ccb8f0eeb8
commit 6e13898981
20 files changed
+252 -246

No files matched your search

+37 -160
View File
@@ -6,7 +6,6 @@ import (
"encoding/binary"
"errors"
"fmt"
"image/color"
"io"
"math"
"net"
@@ -16,7 +15,6 @@ import (
"time"
"github.com/btcsuite/btcd/btcec/v2"
"github.com/btcsuite/btcd/btcec/v2/ecdsa"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/txscript"
"github.com/btcsuite/btcd/wire"
@@ -602,7 +600,7 @@ func (c *ChannelGraph) ForEachNodeCached(cb func(node route.Vertex,
// We'll iterate over each node, then the set of channels for each
// node, and construct a similar callback functiopn signature as the
// main funcotin expects.
return c.ForEachNode(func(tx kvdb.RTx, node *LightningNode) error {
return c.ForEachNode(func(tx kvdb.RTx, node *models.LightningNode) error {
channels := make(map[uint64]*DirectedChannel)
err := c.ForEachNodeChannelTx(tx, node.PubKeyBytes,
@@ -710,7 +708,7 @@ func (c *ChannelGraph) DisabledChannelIDs() ([]uint64, error) {
// TODO(roasbeef): add iterator interface to allow for memory efficient graph
// traversal when graph gets mega
func (c *ChannelGraph) ForEachNode(
cb func(kvdb.RTx, *LightningNode) error) error {
cb func(kvdb.RTx, *models.LightningNode) error) error {
traversal := func(tx kvdb.RTx) error {
// First grab the nodes bucket which stores the mapping from
@@ -787,8 +785,8 @@ func (c *ChannelGraph) ForEachNodeCacheable(cb func(kvdb.RTx,
// 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.
func (c *ChannelGraph) SourceNode() (*LightningNode, error) {
var source *LightningNode
func (c *ChannelGraph) SourceNode() (*models.LightningNode, error) {
var source *models.LightningNode
err := kvdb.View(c.db, func(tx kvdb.RTx) error {
// First grab the nodes bucket which stores the mapping from
// pubKey to node information.
@@ -818,7 +816,7 @@ func (c *ChannelGraph) SourceNode() (*LightningNode, error) {
// 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.
func (c *ChannelGraph) sourceNode(nodes kvdb.RBucket) (*LightningNode, error) {
func (c *ChannelGraph) sourceNode(nodes kvdb.RBucket) (*models.LightningNode, error) {
selfPub := nodes.Get(sourceKey)
if selfPub == nil {
return nil, ErrSourceNodeNotSet
@@ -837,7 +835,7 @@ func (c *ChannelGraph) sourceNode(nodes kvdb.RBucket) (*LightningNode, error) {
// SetSourceNode sets the source node within the graph database. The source
// node is to be used as the center of a star-graph within path finding
// algorithms.
func (c *ChannelGraph) SetSourceNode(node *LightningNode) error {
func (c *ChannelGraph) SetSourceNode(node *models.LightningNode) error {
nodePubBytes := node.PubKeyBytes[:]
return kvdb.Update(c.db, func(tx kvdb.RwTx) error {
@@ -868,7 +866,7 @@ func (c *ChannelGraph) SetSourceNode(node *LightningNode) error {
// channel update.
//
// TODO(roasbeef): also need sig of announcement
func (c *ChannelGraph) AddLightningNode(node *LightningNode,
func (c *ChannelGraph) AddLightningNode(node *models.LightningNode,
op ...batch.SchedulerOption) error {
r := &batch.Request{
@@ -894,7 +892,7 @@ func (c *ChannelGraph) AddLightningNode(node *LightningNode,
return c.nodeScheduler.Execute(r)
}
func addLightningNode(tx kvdb.RwTx, node *LightningNode) error {
func addLightningNode(tx kvdb.RwTx, node *models.LightningNode) error {
nodes, err := tx.CreateTopLevelBucket(nodeBucket)
if err != nil {
return err
@@ -1107,7 +1105,7 @@ func (c *ChannelGraph) addChannelEdge(tx kvdb.RwTx,
_, node1Err := fetchLightningNode(nodes, edge.NodeKey1Bytes[:])
switch {
case node1Err == ErrGraphNodeNotFound:
node1Shell := LightningNode{
node1Shell := models.LightningNode{
PubKeyBytes: edge.NodeKey1Bytes,
HaveNodeAnnouncement: false,
}
@@ -1123,7 +1121,7 @@ func (c *ChannelGraph) addChannelEdge(tx kvdb.RwTx,
_, node2Err := fetchLightningNode(nodes, edge.NodeKey2Bytes[:])
switch {
case node2Err == ErrGraphNodeNotFound:
node2Shell := LightningNode{
node2Shell := models.LightningNode{
PubKeyBytes: edge.NodeKey2Bytes,
HaveNodeAnnouncement: false,
}
@@ -1922,11 +1920,11 @@ type ChannelEdge struct {
// Node1 is "node 1" in the channel. This is the node that would have
// produced Policy1 if it exists.
Node1 *LightningNode
Node1 *models.LightningNode
// Node2 is "node 2" in the channel. This is the node that would have
// produced Policy2 if it exists.
Node2 *LightningNode
Node2 *models.LightningNode
}
// ChanUpdatesInHorizon returns all the known channel edges which have at least
@@ -2082,9 +2080,9 @@ func (c *ChannelGraph) ChanUpdatesInHorizon(startTime,
// nodes to quickly determine if they have the same set of up to date node
// announcements.
func (c *ChannelGraph) NodeUpdatesInHorizon(startTime,
endTime time.Time) ([]LightningNode, error) {
endTime time.Time) ([]models.LightningNode, error) {
var nodesInHorizon []LightningNode
var nodesInHorizon []models.LightningNode
err := kvdb.View(c.db, func(tx kvdb.RTx) error {
nodes := tx.ReadBucket(nodeBucket)
@@ -2880,127 +2878,6 @@ func updateEdgePolicy(tx kvdb.RwTx, edge *models.ChannelEdgePolicy,
return isUpdate1, nil
}
// LightningNode represents an individual vertex/node within the channel graph.
// A node is connected to other nodes by one or more channel edges emanating
// from it. As the graph is directed, a node will also have an incoming edge
// attached to it for each outgoing edge.
type LightningNode struct {
// PubKeyBytes is the raw bytes of the public key of the target node.
PubKeyBytes [33]byte
pubKey *btcec.PublicKey
// HaveNodeAnnouncement indicates whether we received a node
// announcement for this particular node. If true, the remaining fields
// will be set, if false only the PubKey is known for this node.
HaveNodeAnnouncement bool
// LastUpdate is the last time the vertex information for this node has
// been updated.
LastUpdate time.Time
// Address is the TCP address this node is reachable over.
Addresses []net.Addr
// Color is the selected color for the node.
Color color.RGBA
// Alias is a nick-name for the node. The alias can be used to confirm
// a node's identity or to serve as a short ID for an address book.
Alias string
// AuthSigBytes is the raw signature under the advertised public key
// which serves to authenticate the attributes announced by this node.
AuthSigBytes []byte
// Features is the list of protocol features supported by this node.
Features *lnwire.FeatureVector
// ExtraOpaqueData is the set of data that was appended to this
// message, some of which we may not actually know how to iterate or
// parse. By holding onto this data, we ensure that we're able to
// properly validate the set of signatures that cover these new fields,
// and ensure we're able to make upgrades to the network in a forwards
// compatible manner.
ExtraOpaqueData []byte
// TODO(roasbeef): discovery will need storage to keep it's last IP
// address and re-announce if interface changes?
// TODO(roasbeef): add update method and fetch?
}
// PubKey is the node's long-term identity public key. This key will be used to
// authenticated any advertisements/updates sent by the node.
//
// NOTE: By having this method to access an attribute, we ensure we only need
// to fully deserialize the pubkey if absolutely necessary.
func (l *LightningNode) PubKey() (*btcec.PublicKey, error) {
if l.pubKey != nil {
return l.pubKey, nil
}
key, err := btcec.ParsePubKey(l.PubKeyBytes[:])
if err != nil {
return nil, err
}
l.pubKey = key
return key, nil
}
// AuthSig is a signature under the advertised public key which serves to
// authenticate the attributes announced by this node.
//
// NOTE: By having this method to access an attribute, we ensure we only need
// to fully deserialize the signature if absolutely necessary.
func (l *LightningNode) AuthSig() (*ecdsa.Signature, error) {
return ecdsa.ParseSignature(l.AuthSigBytes)
}
// AddPubKey is a setter-link method that can be used to swap out the public
// key for a node.
func (l *LightningNode) AddPubKey(key *btcec.PublicKey) {
l.pubKey = key
copy(l.PubKeyBytes[:], key.SerializeCompressed())
}
// NodeAnnouncement retrieves the latest node announcement of the node.
func (l *LightningNode) NodeAnnouncement(signed bool) (*lnwire.NodeAnnouncement,
error) {
if !l.HaveNodeAnnouncement {
return nil, fmt.Errorf("node does not have node announcement")
}
alias, err := lnwire.NewNodeAlias(l.Alias)
if err != nil {
return nil, err
}
nodeAnn := &lnwire.NodeAnnouncement{
Features: l.Features.RawFeatureVector,
NodeID: l.PubKeyBytes,
RGBColor: l.Color,
Alias: alias,
Addresses: l.Addresses,
Timestamp: uint32(l.LastUpdate.Unix()),
ExtraOpaqueData: l.ExtraOpaqueData,
}
if !signed {
return nodeAnn, nil
}
sig, err := lnwire.NewSigFromECDSARawSignature(l.AuthSigBytes)
if err != nil {
return nil, err
}
nodeAnn.Signature = sig
return nodeAnn, nil
}
// isPublic determines whether the node is seen as public within the graph from
// the source node's point of view. An existing database transaction can also be
// specified.
@@ -3050,7 +2927,7 @@ func (c *ChannelGraph) isPublic(tx kvdb.RTx, nodePub route.Vertex,
// ErrGraphNodeNotFound is returned. An optional transaction may be provided.
// If none is provided, then a new one will be created.
func (c *ChannelGraph) FetchLightningNodeTx(tx kvdb.RTx, nodePub route.Vertex) (
*LightningNode, error) {
*models.LightningNode, error) {
return c.fetchLightningNode(tx, nodePub)
}
@@ -3058,7 +2935,7 @@ func (c *ChannelGraph) FetchLightningNodeTx(tx kvdb.RTx, nodePub route.Vertex) (
// 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.
func (c *ChannelGraph) FetchLightningNode(nodePub route.Vertex) (*LightningNode,
func (c *ChannelGraph) FetchLightningNode(nodePub route.Vertex) (*models.LightningNode,
error) {
return c.fetchLightningNode(nil, nodePub)
@@ -3069,9 +2946,9 @@ func (c *ChannelGraph) FetchLightningNode(nodePub route.Vertex) (*LightningNode,
// returned. An optional transaction may be provided. If none is provided, then
// a new one will be created.
func (c *ChannelGraph) fetchLightningNode(tx kvdb.RTx,
nodePub route.Vertex) (*LightningNode, error) {
nodePub route.Vertex) (*models.LightningNode, error) {
var node *LightningNode
var node *models.LightningNode
fetch := func(tx kvdb.RTx) error {
// First grab the nodes bucket which stores the mapping from
// pubKey to node information.
@@ -3339,7 +3216,7 @@ func (c *ChannelGraph) ForEachNodeChannelTx(tx kvdb.RTx,
// one of the nodes, and wishes to obtain the full LightningNode for the other
// end of the channel.
func (c *ChannelGraph) FetchOtherNode(tx kvdb.RTx,
channel *models.ChannelEdgeInfo, thisNodeKey []byte) (*LightningNode,
channel *models.ChannelEdgeInfo, thisNodeKey []byte) (*models.LightningNode,
error) {
// Ensure that the node passed in is actually a member of the channel.
@@ -3353,7 +3230,7 @@ func (c *ChannelGraph) FetchOtherNode(tx kvdb.RTx,
return nil, fmt.Errorf("node not participating in this channel")
}
var targetNode *LightningNode
var targetNode *models.LightningNode
fetchNodeFunc := func(tx kvdb.RTx) error {
// First grab the nodes bucket which stores the mapping from
// pubKey to node information.
@@ -3976,7 +3853,7 @@ func (c *ChannelGraph) IsClosedScid(scid lnwire.ShortChannelID) (bool, error) {
}
func putLightningNode(nodeBucket kvdb.RwBucket, aliasBucket kvdb.RwBucket, // nolint:dupl
updateIndex kvdb.RwBucket, node *LightningNode) error {
updateIndex kvdb.RwBucket, node *models.LightningNode) error {
var (
scratch [16]byte
@@ -4105,11 +3982,11 @@ func putLightningNode(nodeBucket kvdb.RwBucket, aliasBucket kvdb.RwBucket, // no
}
func fetchLightningNode(nodeBucket kvdb.RBucket,
nodePub []byte) (LightningNode, error) {
nodePub []byte) (models.LightningNode, error) {
nodeBytes := nodeBucket.Get(nodePub)
if nodeBytes == nil {
return LightningNode{}, ErrGraphNodeNotFound
return models.LightningNode{}, ErrGraphNodeNotFound
}
nodeReader := bytes.NewReader(nodeBytes)
@@ -4172,9 +4049,9 @@ func deserializeLightningNodeCacheable(r io.Reader) (*graphCacheNode, error) {
return node, nil
}
func deserializeLightningNode(r io.Reader) (LightningNode, error) {
func deserializeLightningNode(r io.Reader) (models.LightningNode, error) {
var (
node LightningNode
node models.LightningNode
scratch [8]byte
err error
)
@@ -4184,18 +4061,18 @@ func deserializeLightningNode(r io.Reader) (LightningNode, error) {
node.Features = lnwire.EmptyFeatureVector()
if _, err := r.Read(scratch[:]); err != nil {
return LightningNode{}, err
return models.LightningNode{}, err
}
unix := int64(byteOrder.Uint64(scratch[:]))
node.LastUpdate = time.Unix(unix, 0)
if _, err := io.ReadFull(r, node.PubKeyBytes[:]); err != nil {
return LightningNode{}, err
return models.LightningNode{}, err
}
if _, err := r.Read(scratch[:2]); err != nil {
return LightningNode{}, err
return models.LightningNode{}, err
}
hasNodeAnn := byteOrder.Uint16(scratch[:2])
@@ -4214,27 +4091,27 @@ func deserializeLightningNode(r io.Reader) (LightningNode, error) {
// We did get a node announcement for this node, so we'll have the rest
// of the data available.
if err := binary.Read(r, byteOrder, &node.Color.R); err != nil {
return LightningNode{}, err
return models.LightningNode{}, err
}
if err := binary.Read(r, byteOrder, &node.Color.G); err != nil {
return LightningNode{}, err
return models.LightningNode{}, err
}
if err := binary.Read(r, byteOrder, &node.Color.B); err != nil {
return LightningNode{}, err
return models.LightningNode{}, err
}
node.Alias, err = wire.ReadVarString(r, 0)
if err != nil {
return LightningNode{}, err
return models.LightningNode{}, err
}
err = node.Features.Decode(r)
if err != nil {
return LightningNode{}, err
return models.LightningNode{}, err
}
if _, err := r.Read(scratch[:2]); err != nil {
return LightningNode{}, err
return models.LightningNode{}, err
}
numAddresses := int(byteOrder.Uint16(scratch[:2]))
@@ -4242,7 +4119,7 @@ func deserializeLightningNode(r io.Reader) (LightningNode, error) {
for i := 0; i < numAddresses; i++ {
address, err := DeserializeAddr(r)
if err != nil {
return LightningNode{}, err
return models.LightningNode{}, err
}
addresses = append(addresses, address)
}
@@ -4250,7 +4127,7 @@ func deserializeLightningNode(r io.Reader) (LightningNode, error) {
node.AuthSigBytes, err = wire.ReadVarBytes(r, 0, 80, "sig")
if err != nil {
return LightningNode{}, err
return models.LightningNode{}, err
}
// We'll try and see if there are any opaque bytes left, if not, then
@@ -4262,7 +4139,7 @@ func deserializeLightningNode(r io.Reader) (LightningNode, error) {
case err == io.ErrUnexpectedEOF:
case err == io.EOF:
case err != nil:
return LightningNode{}, err
return models.LightningNode{}, err
}
return node, nil