diff --git a/autopilot/prefattach_test.go b/autopilot/prefattach_test.go index 3ab0c4fc3..78b738d3e 100644 --- a/autopilot/prefattach_test.go +++ b/autopilot/prefattach_test.go @@ -495,7 +495,11 @@ func (d *testDBGraph) addRandChannel(node1, node2 *btcec.PublicKey, Capacity: capacity, Features: lnwire.EmptyFeatureVector(), } - edge.AddNodeKeys(lnNode1, lnNode2, lnNode1, lnNode2) + copy(edge.NodeKey1Bytes[:], lnNode1.SerializeCompressed()) + copy(edge.NodeKey2Bytes[:], lnNode2.SerializeCompressed()) + copy(edge.BitcoinKey1Bytes[:], lnNode1.SerializeCompressed()) + copy(edge.BitcoinKey2Bytes[:], lnNode2.SerializeCompressed()) + if err := d.db.AddChannelEdge(ctx, edge); err != nil { return nil, nil, err } diff --git a/graph/db/kv_store.go b/graph/db/kv_store.go index ae4136e9c..c8e6151b7 100644 --- a/graph/db/kv_store.go +++ b/graph/db/kv_store.go @@ -469,7 +469,7 @@ func forEachChannel(db kvdb.Backend, cb func(*models.ChannelEdgeInfo, chanID: chanID, }] - return cb(&info, policy1, policy2) + return cb(info, policy1, policy2) }, ) }, reset) @@ -557,7 +557,7 @@ func (c *KVStore) ForEachChannelCacheable(cb func(*models.CachedEdgeInfo, } return cb( - models.NewCachedEdge(&info), + models.NewCachedEdge(info), cachedPolicy1, cachedPolicy2, ) }, @@ -1393,7 +1393,7 @@ func (c *KVStore) AddEdgeProof(chanID lnwire.ShortChannelID, edge.AuthProof = proof - return putChanEdgeInfo(edgeIndex, &edge, chanKey) + return putChanEdgeInfo(edgeIndex, edge, chanKey) }, func() {}) } @@ -2238,7 +2238,7 @@ func (c *KVStore) fetchNextChanUpdateBatch( // Now we have all the information we need to build the // channel edge. channel := ChannelEdge{ - Info: &edgeInfo, + Info: edgeInfo, Policy1: edge1, Policy2: edge2, Node1: node1, @@ -2784,7 +2784,7 @@ func (c *KVStore) FilterChannelRange(startHeight, continue } - node1Key, node2Key := computeEdgePolicyKeys(&edgeInfo) + node1Key, node2Key := computeEdgePolicyKeys(edgeInfo) rawPolicy := edges.Get(node1Key) if len(rawPolicy) != 0 { @@ -2936,7 +2936,7 @@ func (c *KVStore) fetchChanInfos(tx kvdb.RTx, chanIDs []uint64) ( } chanEdges = append(chanEdges, ChannelEdge{ - Info: &edgeInfo, + Info: edgeInfo, Policy1: edge1, Policy2: edge2, Node1: node1, @@ -3087,7 +3087,7 @@ func (c *KVStore) delChannelEdgeUnsafe(edges, edgeIndex, chanIndex, // being removed due to the channel becoming a zombie. We do this to // ensure we don't store unnecessary data for spent channels. if !isZombie { - return &edgeInfo, nil + return edgeInfo, nil } nodeKey1, nodeKey2 := edgeInfo.NodeKey1Bytes, edgeInfo.NodeKey2Bytes @@ -3106,7 +3106,7 @@ func (c *KVStore) delChannelEdgeUnsafe(edges, edgeIndex, chanIndex, ) } - return &edgeInfo, markEdgeZombie( + return edgeInfo, markEdgeZombie( zombieIndex, byteOrder.Uint64(chanID), nodeKey1, nodeKey2, ) } @@ -3551,7 +3551,7 @@ func nodeTraversal(tx kvdb.RTx, nodePub []byte, db kvdb.Backend, } // Finally, we execute the callback. - err = cb(tx, &edgeInfo, outgoingPolicy, incomingPolicy) + err = cb(tx, edgeInfo, outgoingPolicy, incomingPolicy) if err != nil { return err } @@ -3781,7 +3781,7 @@ func (c *KVStore) FetchChannelEdgesByOutpoint(op *wire.OutPoint) ( if err != nil { return fmt.Errorf("%w: chanID=%x", err, chanID) } - edgeInfo = &edge + edgeInfo = edge // Once we have the information about the channels' parameters, // we'll fetch the routing policies for each for the directed @@ -3887,7 +3887,7 @@ func (c *KVStore) FetchChannelEdgesByID(chanID uint64) ( return err } - edgeInfo = &edge + edgeInfo = edge // Then we'll attempt to fetch the accompanying policies of this // edge. @@ -4702,11 +4702,11 @@ func putChanEdgeInfo(edgeIndex kvdb.RwBucket, } func fetchChanEdgeInfo(edgeIndex kvdb.RBucket, - chanID []byte) (models.ChannelEdgeInfo, error) { + chanID []byte) (*models.ChannelEdgeInfo, error) { edgeInfoBytes := edgeIndex.Get(chanID) if edgeInfoBytes == nil { - return models.ChannelEdgeInfo{}, ErrEdgeNotFound + return nil, ErrEdgeNotFound } edgeInfoReader := bytes.NewReader(edgeInfoBytes) @@ -4714,34 +4714,34 @@ func fetchChanEdgeInfo(edgeIndex kvdb.RBucket, return deserializeChanEdgeInfo(edgeInfoReader) } -func deserializeChanEdgeInfo(r io.Reader) (models.ChannelEdgeInfo, error) { +func deserializeChanEdgeInfo(r io.Reader) (*models.ChannelEdgeInfo, error) { var ( err error edgeInfo models.ChannelEdgeInfo ) if _, err := io.ReadFull(r, edgeInfo.NodeKey1Bytes[:]); err != nil { - return models.ChannelEdgeInfo{}, err + return nil, err } if _, err := io.ReadFull(r, edgeInfo.NodeKey2Bytes[:]); err != nil { - return models.ChannelEdgeInfo{}, err + return nil, err } if _, err := io.ReadFull(r, edgeInfo.BitcoinKey1Bytes[:]); err != nil { - return models.ChannelEdgeInfo{}, err + return nil, err } if _, err := io.ReadFull(r, edgeInfo.BitcoinKey2Bytes[:]); err != nil { - return models.ChannelEdgeInfo{}, err + return nil, err } featureBytes, err := wire.ReadVarBytes(r, 0, 900, "features") if err != nil { - return models.ChannelEdgeInfo{}, err + return nil, err } features := lnwire.NewRawFeatureVector() err = features.Decode(bytes.NewReader(featureBytes)) if err != nil { - return models.ChannelEdgeInfo{}, fmt.Errorf("unable to decode "+ + return nil, fmt.Errorf("unable to decode "+ "features: %w", err) } edgeInfo.Features = lnwire.NewFeatureVector(features, lnwire.Features) @@ -4750,19 +4750,19 @@ func deserializeChanEdgeInfo(r io.Reader) (models.ChannelEdgeInfo, error) { proof.NodeSig1Bytes, err = wire.ReadVarBytes(r, 0, 80, "sigs") if err != nil { - return models.ChannelEdgeInfo{}, err + return nil, err } proof.NodeSig2Bytes, err = wire.ReadVarBytes(r, 0, 80, "sigs") if err != nil { - return models.ChannelEdgeInfo{}, err + return nil, err } proof.BitcoinSig1Bytes, err = wire.ReadVarBytes(r, 0, 80, "sigs") if err != nil { - return models.ChannelEdgeInfo{}, err + return nil, err } proof.BitcoinSig2Bytes, err = wire.ReadVarBytes(r, 0, 80, "sigs") if err != nil { - return models.ChannelEdgeInfo{}, err + return nil, err } if !proof.IsEmpty() { @@ -4771,17 +4771,17 @@ func deserializeChanEdgeInfo(r io.Reader) (models.ChannelEdgeInfo, error) { edgeInfo.ChannelPoint = wire.OutPoint{} if err := ReadOutpoint(r, &edgeInfo.ChannelPoint); err != nil { - return models.ChannelEdgeInfo{}, err + return nil, err } if err := binary.Read(r, byteOrder, &edgeInfo.Capacity); err != nil { - return models.ChannelEdgeInfo{}, err + return nil, err } if err := binary.Read(r, byteOrder, &edgeInfo.ChannelID); err != nil { - return models.ChannelEdgeInfo{}, err + return nil, err } if _, err := io.ReadFull(r, edgeInfo.ChainHash[:]); err != nil { - return models.ChannelEdgeInfo{}, err + return nil, err } // We'll try and see if there are any opaque bytes left, if not, then @@ -4793,10 +4793,10 @@ func deserializeChanEdgeInfo(r io.Reader) (models.ChannelEdgeInfo, error) { case errors.Is(err, io.ErrUnexpectedEOF): case errors.Is(err, io.EOF): case err != nil: - return models.ChannelEdgeInfo{}, err + return nil, err } - return edgeInfo, nil + return &edgeInfo, nil } func putChanEdgePolicy(edges kvdb.RwBucket, edge *models.ChannelEdgePolicy, diff --git a/graph/db/models/channel_auth_proof.go b/graph/db/models/channel_auth_proof.go index 134139467..daf120b10 100644 --- a/graph/db/models/channel_auth_proof.go +++ b/graph/db/models/channel_auth_proof.go @@ -1,7 +1,5 @@ package models -import "github.com/btcsuite/btcd/btcec/v2/ecdsa" - // ChannelAuthProof is the authentication proof (the signature portion) for a // channel. Using the four signatures contained in the struct, and some // auxiliary knowledge (the funding script, node identities, and outpoint) nodes @@ -10,117 +8,23 @@ import "github.com/btcsuite/btcd/btcec/v2/ecdsa" // nodeID1 || nodeID2 || bitcoinKey1|| bitcoinKey2 || 2-byte-feature-len || // features. type ChannelAuthProof struct { - // nodeSig1 is a cached instance of the first node signature. - nodeSig1 *ecdsa.Signature - // NodeSig1Bytes are the raw bytes of the first node signature encoded // in DER format. NodeSig1Bytes []byte - // nodeSig2 is a cached instance of the second node signature. - nodeSig2 *ecdsa.Signature - // NodeSig2Bytes are the raw bytes of the second node signature // encoded in DER format. NodeSig2Bytes []byte - // bitcoinSig1 is a cached instance of the first bitcoin signature. - bitcoinSig1 *ecdsa.Signature - // BitcoinSig1Bytes are the raw bytes of the first bitcoin signature // encoded in DER format. BitcoinSig1Bytes []byte - // bitcoinSig2 is a cached instance of the second bitcoin signature. - bitcoinSig2 *ecdsa.Signature - // BitcoinSig2Bytes are the raw bytes of the second bitcoin signature // encoded in DER format. BitcoinSig2Bytes []byte } -// Node1Sig is the signature using the identity key of the node that is first -// in a lexicographical ordering of the serialized public keys of the two nodes -// that created the channel. -// -// NOTE: By having this method to access an attribute, we ensure we only need -// to fully deserialize the signature if absolutely necessary. -func (c *ChannelAuthProof) Node1Sig() (*ecdsa.Signature, error) { - if c.nodeSig1 != nil { - return c.nodeSig1, nil - } - - sig, err := ecdsa.ParseSignature(c.NodeSig1Bytes) - if err != nil { - return nil, err - } - - c.nodeSig1 = sig - - return sig, nil -} - -// Node2Sig is the signature using the identity key of the node that is second -// in a lexicographical ordering of the serialized public keys of the two nodes -// that created the channel. -// -// NOTE: By having this method to access an attribute, we ensure we only need -// to fully deserialize the signature if absolutely necessary. -func (c *ChannelAuthProof) Node2Sig() (*ecdsa.Signature, error) { - if c.nodeSig2 != nil { - return c.nodeSig2, nil - } - - sig, err := ecdsa.ParseSignature(c.NodeSig2Bytes) - if err != nil { - return nil, err - } - - c.nodeSig2 = sig - - return sig, nil -} - -// BitcoinSig1 is the signature using the public key of the first node that was -// used in the channel's multi-sig output. -// -// NOTE: By having this method to access an attribute, we ensure we only need -// to fully deserialize the signature if absolutely necessary. -func (c *ChannelAuthProof) BitcoinSig1() (*ecdsa.Signature, error) { - if c.bitcoinSig1 != nil { - return c.bitcoinSig1, nil - } - - sig, err := ecdsa.ParseSignature(c.BitcoinSig1Bytes) - if err != nil { - return nil, err - } - - c.bitcoinSig1 = sig - - return sig, nil -} - -// BitcoinSig2 is the signature using the public key of the second node that -// was used in the channel's multi-sig output. -// -// NOTE: By having this method to access an attribute, we ensure we only need -// to fully deserialize the signature if absolutely necessary. -func (c *ChannelAuthProof) BitcoinSig2() (*ecdsa.Signature, error) { - if c.bitcoinSig2 != nil { - return c.bitcoinSig2, nil - } - - sig, err := ecdsa.ParseSignature(c.BitcoinSig2Bytes) - if err != nil { - return nil, err - } - - c.bitcoinSig2 = sig - - return sig, nil -} - // IsEmpty check is the authentication proof is empty Proof is empty if at // least one of the signatures are equal to nil. func (c *ChannelAuthProof) IsEmpty() bool { diff --git a/graph/db/models/channel_edge_info.go b/graph/db/models/channel_edge_info.go index d19287571..b86c140bc 100644 --- a/graph/db/models/channel_edge_info.go +++ b/graph/db/models/channel_edge_info.go @@ -26,9 +26,6 @@ type ChannelEdgeInfo struct { // ChainHash is the hash that uniquely identifies the chain that this // channel was opened within. - // - // TODO(roasbeef): need to modify db keying for multi-chain - // * must add chain hash to prefix as well ChainHash chainhash.Hash // NodeKey1Bytes is the raw public key of the first node. @@ -41,11 +38,9 @@ type ChannelEdgeInfo struct { // BitcoinKey1Bytes is the raw public key of the first node. BitcoinKey1Bytes [33]byte - bitcoinKey1 *btcec.PublicKey // BitcoinKey2Bytes is the raw public key of the first node. BitcoinKey2Bytes [33]byte - bitcoinKey2 *btcec.PublicKey // Features is the list of protocol features supported by this channel // edge. @@ -79,24 +74,6 @@ type ChannelEdgeInfo struct { ExtraOpaqueData []byte } -// AddNodeKeys is a setter-like method that can be used to replace the set of -// keys for the target ChannelEdgeInfo. -func (c *ChannelEdgeInfo) AddNodeKeys(nodeKey1, nodeKey2, bitcoinKey1, - bitcoinKey2 *btcec.PublicKey) { - - c.nodeKey1 = nodeKey1 - copy(c.NodeKey1Bytes[:], c.nodeKey1.SerializeCompressed()) - - c.nodeKey2 = nodeKey2 - copy(c.NodeKey2Bytes[:], nodeKey2.SerializeCompressed()) - - c.bitcoinKey1 = bitcoinKey1 - copy(c.BitcoinKey1Bytes[:], c.bitcoinKey1.SerializeCompressed()) - - c.bitcoinKey2 = bitcoinKey2 - copy(c.BitcoinKey2Bytes[:], bitcoinKey2.SerializeCompressed()) -} - // NodeKey1 is the identity public key of the "first" node that was involved in // the creation of this channel. A node is considered "first" if the // lexicographical ordering the its serialized public key is "smaller" than @@ -139,46 +116,6 @@ func (c *ChannelEdgeInfo) NodeKey2() (*btcec.PublicKey, error) { return key, nil } -// BitcoinKey1 is the Bitcoin multi-sig key belonging to the first node, that -// was involved in the funding transaction that originally created the channel -// that this struct represents. -// -// NOTE: By having this method to access an attribute, we ensure we only need -// to fully deserialize the pubkey if absolutely necessary. -func (c *ChannelEdgeInfo) BitcoinKey1() (*btcec.PublicKey, error) { - if c.bitcoinKey1 != nil { - return c.bitcoinKey1, nil - } - - key, err := btcec.ParsePubKey(c.BitcoinKey1Bytes[:]) - if err != nil { - return nil, err - } - c.bitcoinKey1 = key - - return key, nil -} - -// BitcoinKey2 is the Bitcoin multi-sig key belonging to the second node, that -// was involved in the funding transaction that originally created the channel -// that this struct represents. -// -// NOTE: By having this method to access an attribute, we ensure we only need -// to fully deserialize the pubkey if absolutely necessary. -func (c *ChannelEdgeInfo) BitcoinKey2() (*btcec.PublicKey, error) { - if c.bitcoinKey2 != nil { - return c.bitcoinKey2, nil - } - - key, err := btcec.ParsePubKey(c.BitcoinKey2Bytes[:]) - if err != nil { - return nil, err - } - c.bitcoinKey2 = key - - return key, nil -} - // OtherNodeKeyBytes returns the node key bytes of the other end of the channel. func (c *ChannelEdgeInfo) OtherNodeKeyBytes(thisNodeKey []byte) ( [33]byte, error) {