channeldb: use raw pub keys and signatures directly in vertex/edge structs

In this commit, we make an API change that’s meant to reduce the amount
of garbage we generate when doing pathfinding or syncing nodes with our
latest graph state. Before this commit, we would always have to fully
decode the public key and signatures when reading a edge or vertex
struct. For the edges, we may need several EC operations to fully
decode all the pubkeys. This has been seen to generate a ton of
garbage, as well as slow down path finding a good bit.

To remedy this, we’ll now only ever read the *raw* bytes from disk. In
the event that we actually need to verify a signature (or w/e), only
*then* will we fully decode everything.
This commit is contained in:
Olaoluwa Osuntokun 2018-01-30 20:19:40 -08:00
parent 850abbbeb5
commit 5e9166e478
No known key found for this signature in database
GPG Key ID: 964EA263DD637C21
4 changed files with 461 additions and 219 deletions

@ -81,6 +81,8 @@ var (
Index: 0, Index: 0,
} }
privKey, pubKey = btcec.PrivKeyFromBytes(btcec.S256(), key[:]) privKey, pubKey = btcec.PrivKeyFromBytes(btcec.S256(), key[:])
wireSig, _ = lnwire.NewSigFromSignature(testSig)
) )
// makeTestDB creates a new instance of the ChannelDB for testing purposes. A // makeTestDB creates a new instance of the ChannelDB for testing purposes. A
@ -428,10 +430,10 @@ func TestChannelStateTransition(t *testing.T) {
Commitment: remoteCommit, Commitment: remoteCommit,
CommitSig: &lnwire.CommitSig{ CommitSig: &lnwire.CommitSig{
ChanID: lnwire.ChannelID(key), ChanID: lnwire.ChannelID(key),
CommitSig: testSig, CommitSig: wireSig,
HtlcSigs: []*btcec.Signature{ HtlcSigs: []lnwire.Sig{
testSig, wireSig,
testSig, wireSig,
}, },
}, },
LogUpdates: []LogUpdate{ LogUpdates: []LogUpdate{

@ -309,7 +309,8 @@ func (c *ChannelGraph) SourceNode() (*LightningNode, error) {
// node is to be used as the center of a star-graph within path finding // node is to be used as the center of a star-graph within path finding
// algorithms. // algorithms.
func (c *ChannelGraph) SetSourceNode(node *LightningNode) error { func (c *ChannelGraph) SetSourceNode(node *LightningNode) error {
nodePub := node.PubKey.SerializeCompressed() nodePubBytes := node.PubKeyBytes[:]
return c.db.Update(func(tx *bolt.Tx) error { return c.db.Update(func(tx *bolt.Tx) error {
// First grab the nodes bucket which stores the mapping from // First grab the nodes bucket which stores the mapping from
// pubKey to node information. // pubKey to node information.
@ -320,7 +321,7 @@ func (c *ChannelGraph) SetSourceNode(node *LightningNode) error {
// Next we create the mapping from source to the targeted // Next we create the mapping from source to the targeted
// public key. // public key.
if err := nodes.Put(sourceKey, nodePub); err != nil { if err := nodes.Put(sourceKey, nodePubBytes); err != nil {
return err return err
} }
@ -976,13 +977,13 @@ func (c *ChannelGraph) UpdateEdgePolicy(edge *ChannelEdgePolicy) error {
// from it. As the graph is directed, a node will also have an incoming edge // from it. As the graph is directed, a node will also have an incoming edge
// attached to it for each outgoing edge. // attached to it for each outgoing edge.
type LightningNode struct { type LightningNode struct {
// PubKey is the node's long-term identity public key. This key will be // PubKeyBytes is the raw bytes of the public key of the target node.
// used to authenticated any advertisements/updates sent by the node. PubKeyBytes [33]byte
PubKey *btcec.PublicKey pubKey *btcec.PublicKey
// HaveNodeAnnouncement indicates whether we received a node announcement // HaveNodeAnnouncement indicates whether we received a node
// for this particular node. If true, the remaining fields will be set, // announcement for this particular node. If true, the remaining fields
// if false only the PubKey is known for this node. // will be set, if false only the PubKey is known for this node.
HaveNodeAnnouncement bool HaveNodeAnnouncement bool
// LastUpdate is the last time the vertex information for this node has // LastUpdate is the last time the vertex information for this node has
@ -999,11 +1000,9 @@ type LightningNode struct {
// a node's identity or to serve as a short ID for an address book. // a node's identity or to serve as a short ID for an address book.
Alias string Alias string
// AuthSig is a signature under the advertised public key which serves // AuthSigBytes is the raw signature under the advertised public key
// to authenticate the attributes announced by this node. // which serves to authenticate the attributes announced by this node.
// AuthSigBytes []byte
// TODO(roasbeef): hook into serialization once full verification is in
AuthSig *btcec.Signature
// Features is the list of protocol features supported by this node. // Features is the list of protocol features supported by this node.
Features *lnwire.FeatureVector Features *lnwire.FeatureVector
@ -1016,6 +1015,42 @@ type LightningNode struct {
// TODO(roasbeef): add update method and fetch? // 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 (c *LightningNode) PubKey() (*btcec.PublicKey, error) {
if c.pubKey != nil {
return c.pubKey, nil
}
key, err := btcec.ParsePubKey(c.PubKeyBytes[:], btcec.S256())
if err != nil {
return nil, err
}
c.pubKey = key
c.pubKey.Curve = nil
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 (c *LightningNode) AuthSig() (*btcec.Signature, error) {
return btcec.ParseSignature(c.AuthSigBytes, btcec.S256())
}
// AddPubKey is a setter-link method that can be used to swap out the public
// key for a node.
func (c *LightningNode) AddPubKey(key *btcec.PublicKey) {
c.pubKey = key
copy(c.PubKeyBytes[:], key.SerializeCompressed())
}
// FetchLightningNode attempts to look up a target node by its identity public // 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 // key. If the node isn't found in the database, then ErrGraphNodeNotFound is
// returned. // returned.
@ -1062,13 +1097,12 @@ func (c *ChannelGraph) FetchLightningNode(pub *btcec.PublicKey) (*LightningNode,
// timestamp of when the data for the node was lasted updated is returned along // 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 // with a true boolean. Otherwise, an empty time.Time is returned with a false
// boolean. // boolean.
func (c *ChannelGraph) HasLightningNode(pub *btcec.PublicKey) (time.Time, bool, error) { func (c *ChannelGraph) HasLightningNode(nodePub [33]byte) (time.Time, bool, error) {
var ( var (
updateTime time.Time updateTime time.Time
exists bool exists bool
) )
nodePub := pub.SerializeCompressed()
err := c.db.View(func(tx *bolt.Tx) error { err := c.db.View(func(tx *bolt.Tx) error {
// First grab the nodes bucket which stores the mapping from // First grab the nodes bucket which stores the mapping from
// pubKey to node information. // pubKey to node information.
@ -1079,7 +1113,7 @@ func (c *ChannelGraph) HasLightningNode(pub *btcec.PublicKey) (time.Time, bool,
// If a key for this serialized public key isn't found, we can // If a key for this serialized public key isn't found, we can
// exit early. // exit early.
nodeBytes := nodes.Get(nodePub) nodeBytes := nodes.Get(nodePub[:])
if nodeBytes == nil { if nodeBytes == nil {
exists = false exists = false
return nil return nil
@ -1119,7 +1153,11 @@ func (c *ChannelGraph) HasLightningNode(pub *btcec.PublicKey) (time.Time, bool,
func (l *LightningNode) ForEachChannel(tx *bolt.Tx, func (l *LightningNode) ForEachChannel(tx *bolt.Tx,
cb func(*bolt.Tx, *ChannelEdgeInfo, *ChannelEdgePolicy, *ChannelEdgePolicy) error) error { cb func(*bolt.Tx, *ChannelEdgeInfo, *ChannelEdgePolicy, *ChannelEdgePolicy) error) error {
nodePub := l.PubKey.SerializeCompressed() pub, err := l.PubKey()
if err != nil {
return err
}
nodePub := pub.SerializeCompressed()
traversal := func(tx *bolt.Tx) error { traversal := func(tx *bolt.Tx) error {
nodes := tx.Bucket(nodeBucket) nodes := tx.Bucket(nodeBucket)
@ -1172,7 +1210,12 @@ func (l *LightningNode) ForEachChannel(tx *bolt.Tx,
// We'll also fetch the incoming edge so this // We'll also fetch the incoming edge so this
// information can be available to the caller. // information can be available to the caller.
incomingNode := toEdgePolicy.Node.PubKey.SerializeCompressed() incomingNodeKey, err := toEdgePolicy.Node.PubKey()
if err != nil {
return err
}
incomingNode := incomingNodeKey.SerializeCompressed()
fromEdgePolicy, err := fetchChanEdgePolicy( fromEdgePolicy, err := fetchChanEdgePolicy(
edges, chanID, incomingNode, nodes, edges, chanID, incomingNode, nodes,
) )
@ -1227,29 +1270,21 @@ type ChannelEdgeInfo struct {
// * must add chain hash to prefix as well // * must add chain hash to prefix as well
ChainHash chainhash.Hash ChainHash chainhash.Hash
// NodeKey1 is the identity public key of the "first" node that was // NodeKey1Bytes is the raw public key of the first node.
// involved in the creation of this channel. A node is considered NodeKey1Bytes [33]byte
// "first" if the lexicographical ordering the its serialized public nodeKey1 *btcec.PublicKey
// key is "smaller" than that of the other node involved in channel
// creation.
NodeKey1 *btcec.PublicKey
// NodeKey2 is the identity public key of the "second" node that was // NodeKey2Bytes is the raw public key of the first node.
// involved in the creation of this channel. A node is considered NodeKey2Bytes [33]byte
// "second" if the lexicographical ordering the its serialized public nodeKey2 *btcec.PublicKey
// key is "larger" than that of the other node involved in channel
// creation.
NodeKey2 *btcec.PublicKey
// BitcoinKey1 is the Bitcoin multi-sig key belonging to the first // BitcoinKey1Bytes is the raw public key of the first node.
// node, that was involved in the funding transaction that originally BitcoinKey1Bytes [33]byte
// created the channel that this struct represents. bitcoinKey1 *btcec.PublicKey
BitcoinKey1 *btcec.PublicKey
// BitcoinKey2 is the Bitcoin multi-sig key belonging to the second // BitcoinKey2Bytes is the raw public key of the first node.
// node, that was involved in the funding transaction that originally BitcoinKey2Bytes [33]byte
// created the channel that this struct represents. bitcoinKey2 *btcec.PublicKey
BitcoinKey2 *btcec.PublicKey
// Features is an opaque byte slice that encodes the set of channel // Features is an opaque byte slice that encodes the set of channel
// specific features that this channel edge supports. // specific features that this channel edge supports.
@ -1269,6 +1304,107 @@ type ChannelEdgeInfo struct {
Capacity btcutil.Amount Capacity btcutil.Amount
} }
// 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
// that of the other node involved in channel creation.
//
// 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) NodeKey1() (*btcec.PublicKey, error) {
if c.nodeKey1 != nil {
return c.nodeKey1, nil
}
key, err := btcec.ParsePubKey(c.NodeKey1Bytes[:], btcec.S256())
if err != nil {
return nil, err
}
c.nodeKey1 = key
return key, nil
}
// NodeKey2 is the identity public key of the "second" node that was
// involved in the creation of this channel. A node is considered
// "second" if the lexicographical ordering the its serialized public
// key is "larger" than that of the other node involved in channel
// creation.
//
// 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) NodeKey2() (*btcec.PublicKey, error) {
if c.nodeKey2 != nil {
return c.nodeKey2, nil
}
key, err := btcec.ParsePubKey(c.NodeKey2Bytes[:], btcec.S256())
if err != nil {
return nil, err
}
c.nodeKey2 = key
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[:], btcec.S256())
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[:], btcec.S256())
if err != nil {
return nil, err
}
c.bitcoinKey2 = key
return key, nil
}
// ChannelAuthProof is the authentication proof (the signature portion) for a // ChannelAuthProof is the authentication proof (the signature portion) for a
// channel. Using the four signatures contained in the struct, and some // channel. Using the four signatures contained in the struct, and some
// auxillary knowledge (the funding script, node identities, and outpoint) nodes // auxillary knowledge (the funding script, node identities, and outpoint) nodes
@ -1277,32 +1413,124 @@ type ChannelEdgeInfo struct {
// nodeID1 || nodeID2 || bitcoinKey1|| bitcoinKey2 || 2-byte-feature-len || // nodeID1 || nodeID2 || bitcoinKey1|| bitcoinKey2 || 2-byte-feature-len ||
// features. // features.
type ChannelAuthProof struct { type ChannelAuthProof struct {
// NodeSig1 is the signature using the identity key of the node that is // nodeSig1 is a cached instance of the first node signature.
// first in a lexicographical ordering of the serialized public keys of nodeSig1 *btcec.Signature
// the two nodes that created the channel.
NodeSig1 *btcec.Signature
// NodeSig2 is the signature using the identity key of the node that is // NodeSig1Bytes are the raw bytes of the first node signature encoded
// second in a lexicographical ordering of the serialized public keys // in DER format.
// of the two nodes that created the channel. NodeSig1Bytes []byte
NodeSig2 *btcec.Signature
// BitcoinSig1 is the signature using the public key of the first node // nodeSig2 is a cached instance of the second node signature.
// that was used in the channel's multi-sig output. nodeSig2 *btcec.Signature
BitcoinSig1 *btcec.Signature
// BitcoinSig2 is the signature using the public key of the second node // NodeSig2Bytes are the raw bytes of the second node signature
// that was used in the channel's multi-sig output. // encoded in DER format.
BitcoinSig2 *btcec.Signature NodeSig2Bytes []byte
// bitcoinSig1 is a cached instance of the first bitcoin signature.
bitcoinSig1 *btcec.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 *btcec.Signature
// BitcoinSig2Bytes are the raw bytes of the second bitcoin signature
// encoded in DER format.
BitcoinSig2Bytes []byte
}
// NodeSig1 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() (*btcec.Signature, error) {
if c.nodeSig1 != nil {
return c.nodeSig1, nil
}
sig, err := btcec.ParseSignature(c.NodeSig1Bytes, btcec.S256())
if err != nil {
return nil, err
}
c.nodeSig1 = sig
return sig, nil
}
// NodeSig2 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() (*btcec.Signature, error) {
if c.nodeSig2 != nil {
return c.nodeSig2, nil
}
sig, err := btcec.ParseSignature(c.NodeSig2Bytes, btcec.S256())
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() (*btcec.Signature, error) {
if c.bitcoinSig1 != nil {
return c.bitcoinSig1, nil
}
sig, err := btcec.ParseSignature(c.BitcoinSig1Bytes, btcec.S256())
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() (*btcec.Signature, error) {
if c.bitcoinSig2 != nil {
return c.bitcoinSig2, nil
}
sig, err := btcec.ParseSignature(c.BitcoinSig2Bytes, btcec.S256())
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 // IsEmpty check is the authentication proof is empty Proof is empty if at
// least one of the signatures are equal to nil. // least one of the signatures are equal to nil.
func (p *ChannelAuthProof) IsEmpty() bool { func (p *ChannelAuthProof) IsEmpty() bool {
return p.NodeSig1 == nil || return len(p.NodeSig1Bytes) == 0 ||
p.NodeSig2 == nil || len(p.NodeSig2Bytes) == 0 ||
p.BitcoinSig1 == nil || len(p.BitcoinSig1Bytes) == 0 ||
p.BitcoinSig2 == nil len(p.BitcoinSig2Bytes) == 0
} }
// ChannelEdgePolicy represents a *directed* edge within the channel graph. For // ChannelEdgePolicy represents a *directed* edge within the channel graph. For
@ -1311,9 +1539,13 @@ func (p *ChannelAuthProof) IsEmpty() bool {
// information concerning fees, and minimum time-lock information which is // information concerning fees, and minimum time-lock information which is
// utilized during path finding. // utilized during path finding.
type ChannelEdgePolicy struct { type ChannelEdgePolicy struct {
// Signature is a channel announcement signature, which is needed for // SigBytes is the raw bytes of the signature of the channel edge
// proper edge policy announcement. // policy. We'll only parse these if the caller needs to access the
Signature *btcec.Signature // signature for validation purposes.
SigBytes []byte
// sig is a cached fully parsed signature.
sig *btcec.Signature
// ChannelID is the unique channel ID for the channel. The first 3 // ChannelID is the unique channel ID for the channel. The first 3
// bytes are the block height, the next 3 the index within the block, // bytes are the block height, the next 3 the index within the block,
@ -1352,6 +1584,26 @@ type ChannelEdgePolicy struct {
db *DB db *DB
} }
// Signature is a channel announcement signature, which is needed for proper
// edge policy announcement.
//
// NOTE: By having this method to access an attribute, we ensure we only need
// to fully deserialize the signature if absolutely necessary.
func (c *ChannelEdgePolicy) Signature() (*btcec.Signature, error) {
if c.sig != nil {
return c.sig, nil
}
sig, err := btcec.ParseSignature(c.SigBytes, btcec.S256())
if err != nil {
return nil, err
}
c.sig = sig
return sig, nil
}
// FetchChannelEdgesByOutpoint attempts to lookup the two directed edges for // FetchChannelEdgesByOutpoint attempts to lookup the two directed edges for
// the channel identified by the funding outpoint. If the channel can't be // the channel identified by the funding outpoint. If the channel can't be
// found, then ErrEdgeNotFound is returned. A struct which houses the general // found, then ErrEdgeNotFound is returned. A struct which houses the general
@ -1539,7 +1791,11 @@ func putLightningNode(nodeBucket *bolt.Bucket, aliasBucket *bolt.Bucket, node *L
b bytes.Buffer b bytes.Buffer
) )
nodePub := node.PubKey.SerializeCompressed() pub, err := node.PubKey()
if err != nil {
return err
}
nodePub := pub.SerializeCompressed()
// If the node has the update time set, write it, else write 0. // If the node has the update time set, write it, else write 0.
updateUnix := uint64(0) updateUnix := uint64(0)
@ -1604,7 +1860,7 @@ func putLightningNode(nodeBucket *bolt.Bucket, aliasBucket *bolt.Bucket, node *L
} }
} }
err := wire.WriteVarBytes(&b, 0, node.AuthSig.Serialize()) err = wire.WriteVarBytes(&b, 0, node.AuthSigBytes)
if err != nil { if err != nil {
return err return err
} }
@ -1630,8 +1886,12 @@ func fetchLightningNode(nodeBucket *bolt.Bucket,
} }
func deserializeLightningNode(r io.Reader) (*LightningNode, error) { func deserializeLightningNode(r io.Reader) (*LightningNode, error) {
var (
scratch [8]byte
err error
)
node := &LightningNode{} node := &LightningNode{}
var scratch [8]byte
if _, err := r.Read(scratch[:]); err != nil { if _, err := r.Read(scratch[:]); err != nil {
return nil, err return nil, err
@ -1640,13 +1900,7 @@ func deserializeLightningNode(r io.Reader) (*LightningNode, error) {
unix := int64(byteOrder.Uint64(scratch[:])) unix := int64(byteOrder.Uint64(scratch[:]))
node.LastUpdate = time.Unix(unix, 0) node.LastUpdate = time.Unix(unix, 0)
var pub [33]byte if _, err := io.ReadFull(r, node.PubKeyBytes[:]); err != nil {
if _, err := r.Read(pub[:]); err != nil {
return nil, err
}
var err error
node.PubKey, err = btcec.ParsePubKey(pub[:], btcec.S256())
if err != nil {
return nil, err return nil, err
} }
@ -1706,12 +1960,7 @@ func deserializeLightningNode(r io.Reader) (*LightningNode, error) {
} }
node.Addresses = addresses node.Addresses = addresses
sigBytes, err := wire.ReadVarBytes(r, 0, 80, "sig") node.AuthSigBytes, err = wire.ReadVarBytes(r, 0, 80, "sig")
if err != nil {
return nil, err
}
node.AuthSig, err = btcec.ParseSignature(sigBytes, btcec.S256())
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -1722,16 +1971,16 @@ func deserializeLightningNode(r io.Reader) (*LightningNode, error) {
func putChanEdgeInfo(edgeIndex *bolt.Bucket, edgeInfo *ChannelEdgeInfo, chanID [8]byte) error { func putChanEdgeInfo(edgeIndex *bolt.Bucket, edgeInfo *ChannelEdgeInfo, chanID [8]byte) error {
var b bytes.Buffer var b bytes.Buffer
if _, err := b.Write(edgeInfo.NodeKey1.SerializeCompressed()); err != nil { if _, err := b.Write(edgeInfo.NodeKey1Bytes[:]); err != nil {
return err return err
} }
if _, err := b.Write(edgeInfo.NodeKey2.SerializeCompressed()); err != nil { if _, err := b.Write(edgeInfo.NodeKey2Bytes[:]); err != nil {
return err return err
} }
if _, err := b.Write(edgeInfo.BitcoinKey1.SerializeCompressed()); err != nil { if _, err := b.Write(edgeInfo.BitcoinKey1Bytes[:]); err != nil {
return err return err
} }
if _, err := b.Write(edgeInfo.BitcoinKey2.SerializeCompressed()); err != nil { if _, err := b.Write(edgeInfo.BitcoinKey2Bytes[:]); err != nil {
return err return err
} }
@ -1742,10 +1991,10 @@ func putChanEdgeInfo(edgeIndex *bolt.Bucket, edgeInfo *ChannelEdgeInfo, chanID [
authProof := edgeInfo.AuthProof authProof := edgeInfo.AuthProof
var nodeSig1, nodeSig2, bitcoinSig1, bitcoinSig2 []byte var nodeSig1, nodeSig2, bitcoinSig1, bitcoinSig2 []byte
if authProof != nil { if authProof != nil {
nodeSig1 = authProof.NodeSig1.Serialize() nodeSig1 = authProof.NodeSig1Bytes
nodeSig2 = authProof.NodeSig2.Serialize() nodeSig2 = authProof.NodeSig2Bytes
bitcoinSig1 = authProof.BitcoinSig1.Serialize() bitcoinSig1 = authProof.BitcoinSig1Bytes
bitcoinSig2 = authProof.BitcoinSig2.Serialize() bitcoinSig2 = authProof.BitcoinSig2Bytes
} }
if err := wire.WriteVarBytes(&b, 0, nodeSig1); err != nil { if err := wire.WriteVarBytes(&b, 0, nodeSig1); err != nil {
@ -1792,32 +2041,19 @@ func fetchChanEdgeInfo(edgeIndex *bolt.Bucket,
func deserializeChanEdgeInfo(r io.Reader) (*ChannelEdgeInfo, error) { func deserializeChanEdgeInfo(r io.Reader) (*ChannelEdgeInfo, error) {
var ( var (
err error err error
pubKeyBytes [33]byte
edgeInfo = &ChannelEdgeInfo{} edgeInfo = &ChannelEdgeInfo{}
) )
readKey := func() (*btcec.PublicKey, error) { if _, err := io.ReadFull(r, edgeInfo.NodeKey1Bytes[:]); err != nil {
if _, err := io.ReadFull(r, pubKeyBytes[:]); err != nil {
return nil, err return nil, err
} }
if _, err := io.ReadFull(r, edgeInfo.NodeKey2Bytes[:]); err != nil {
return btcec.ParsePubKey(pubKeyBytes[:], btcec.S256())
}
edgeInfo.NodeKey1, err = readKey()
if err != nil {
return nil, err return nil, err
} }
edgeInfo.NodeKey2, err = readKey() if _, err := io.ReadFull(r, edgeInfo.BitcoinKey1Bytes[:]); err != nil {
if err != nil {
return nil, err return nil, err
} }
edgeInfo.BitcoinKey1, err = readKey() if _, err := io.ReadFull(r, edgeInfo.BitcoinKey2Bytes[:]); err != nil {
if err != nil {
return nil, err
}
edgeInfo.BitcoinKey2, err = readKey()
if err != nil {
return nil, err return nil, err
} }
@ -1828,32 +2064,23 @@ func deserializeChanEdgeInfo(r io.Reader) (*ChannelEdgeInfo, error) {
proof := &ChannelAuthProof{} proof := &ChannelAuthProof{}
readSig := func() (*btcec.Signature, error) { readSig := func() ([]byte, error) {
sigBytes, err := wire.ReadVarBytes(r, 0, 80, "sigs") return wire.ReadVarBytes(r, 0, 80, "sigs")
if err != nil {
return nil, err
} }
if len(sigBytes) != 0 { proof.NodeSig1Bytes, err = readSig()
return btcec.ParseSignature(sigBytes, btcec.S256())
}
return nil, nil
}
proof.NodeSig1, err = readSig()
if err != nil { if err != nil {
return nil, err return nil, err
} }
proof.NodeSig2, err = readSig() proof.NodeSig2Bytes, err = readSig()
if err != nil { if err != nil {
return nil, err return nil, err
} }
proof.BitcoinSig1, err = readSig() proof.BitcoinSig1Bytes, err = readSig()
if err != nil { if err != nil {
return nil, err return nil, err
} }
proof.BitcoinSig2, err = readSig() proof.BitcoinSig2Bytes, err = readSig()
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -1887,7 +2114,7 @@ func putChanEdgePolicy(edges *bolt.Bucket, edge *ChannelEdgePolicy, from, to []b
var b bytes.Buffer var b bytes.Buffer
err := wire.WriteVarBytes(&b, 0, edge.Signature.Serialize()) err := wire.WriteVarBytes(&b, 0, edge.SigBytes)
if err != nil { if err != nil {
return err return err
} }
@ -1993,11 +2220,7 @@ func deserializeChanEdgePolicy(r io.Reader,
if err != nil { if err != nil {
return nil, err return nil, err
} }
edge.SigBytes = sigBytes
edge.Signature, err = btcec.ParseSignature(sigBytes, btcec.S256())
if err != nil {
return nil, err
}
if err := binary.Read(r, byteOrder, &edge.ChannelID); err != nil { if err := binary.Read(r, byteOrder, &edge.ChannelID); err != nil {
return nil, err return nil, err

@ -50,17 +50,19 @@ func createTestVertex(db *DB) (*LightningNode, error) {
} }
pub := priv.PubKey().SerializeCompressed() pub := priv.PubKey().SerializeCompressed()
return &LightningNode{ n := &LightningNode{
HaveNodeAnnouncement: true, HaveNodeAnnouncement: true,
AuthSig: testSig, AuthSigBytes: testSig.Serialize(),
LastUpdate: time.Unix(updateTime, 0), LastUpdate: time.Unix(updateTime, 0),
PubKey: priv.PubKey(),
Color: color.RGBA{1, 2, 3, 0}, Color: color.RGBA{1, 2, 3, 0},
Alias: "kek" + string(pub[:]), Alias: "kek" + string(pub[:]),
Features: testFeatures, Features: testFeatures,
Addresses: testAddrs, Addresses: testAddrs,
db: db, db: db,
}, nil }
copy(n.PubKeyBytes[:], priv.PubKey().SerializeCompressed())
return n, nil
} }
func TestNodeInsertionAndDeletion(t *testing.T) { func TestNodeInsertionAndDeletion(t *testing.T) {
@ -79,15 +81,15 @@ func TestNodeInsertionAndDeletion(t *testing.T) {
_, testPub := btcec.PrivKeyFromBytes(btcec.S256(), key[:]) _, testPub := btcec.PrivKeyFromBytes(btcec.S256(), key[:])
node := &LightningNode{ node := &LightningNode{
HaveNodeAnnouncement: true, HaveNodeAnnouncement: true,
AuthSig: testSig, AuthSigBytes: testSig.Serialize(),
LastUpdate: time.Unix(1232342, 0), LastUpdate: time.Unix(1232342, 0),
PubKey: testPub,
Color: color.RGBA{1, 2, 3, 0}, Color: color.RGBA{1, 2, 3, 0},
Alias: "kek", Alias: "kek",
Features: testFeatures, Features: testFeatures,
Addresses: testAddrs, Addresses: testAddrs,
db: db, db: db,
} }
copy(node.PubKeyBytes[:], testPub.SerializeCompressed())
// First, insert the node into the graph DB. This should succeed // First, insert the node into the graph DB. This should succeed
// without any errors. // without any errors.
@ -102,7 +104,7 @@ func TestNodeInsertionAndDeletion(t *testing.T) {
t.Fatalf("unable to locate node: %v", err) t.Fatalf("unable to locate node: %v", err)
} }
if _, exists, err := graph.HasLightningNode(testPub); err != nil { if _, exists, err := graph.HasLightningNode(dbNode.PubKeyBytes); err != nil {
t.Fatalf("unable to query for node: %v", err) t.Fatalf("unable to query for node: %v", err)
} else if !exists { } else if !exists {
t.Fatalf("node should be found but wasn't") t.Fatalf("node should be found but wasn't")
@ -144,9 +146,9 @@ func TestPartialNode(t *testing.T) {
// PubKey set. // PubKey set.
_, testPub := btcec.PrivKeyFromBytes(btcec.S256(), key[:]) _, testPub := btcec.PrivKeyFromBytes(btcec.S256(), key[:])
node := &LightningNode{ node := &LightningNode{
PubKey: testPub,
HaveNodeAnnouncement: false, HaveNodeAnnouncement: false,
} }
copy(node.PubKeyBytes[:], testPub.SerializeCompressed())
if err := graph.AddLightningNode(node); err != nil { if err := graph.AddLightningNode(node); err != nil {
t.Fatalf("unable to add node: %v", err) t.Fatalf("unable to add node: %v", err)
@ -159,7 +161,7 @@ func TestPartialNode(t *testing.T) {
t.Fatalf("unable to locate node: %v", err) t.Fatalf("unable to locate node: %v", err)
} }
if _, exists, err := graph.HasLightningNode(testPub); err != nil { if _, exists, err := graph.HasLightningNode(dbNode.PubKeyBytes); err != nil {
t.Fatalf("unable to query for node: %v", err) t.Fatalf("unable to query for node: %v", err)
} else if !exists { } else if !exists {
t.Fatalf("node should be found but wasn't") t.Fatalf("node should be found but wasn't")
@ -168,11 +170,11 @@ func TestPartialNode(t *testing.T) {
// The two nodes should match exactly! (with default values for // The two nodes should match exactly! (with default values for
// LastUpdate and db set to satisfy compareNodes()) // LastUpdate and db set to satisfy compareNodes())
node = &LightningNode{ node = &LightningNode{
PubKey: testPub,
HaveNodeAnnouncement: false, HaveNodeAnnouncement: false,
LastUpdate: time.Unix(0, 0), LastUpdate: time.Unix(0, 0),
db: db, db: db,
} }
copy(node.PubKeyBytes[:], testPub.SerializeCompressed())
if err := compareNodes(node, dbNode); err != nil { if err := compareNodes(node, dbNode); err != nil {
t.Fatalf("nodes don't match: %v", err) t.Fatalf("nodes don't match: %v", err)
@ -181,7 +183,7 @@ func TestPartialNode(t *testing.T) {
// Next, delete the node from the graph, this should purge all data // Next, delete the node from the graph, this should purge all data
// related to the node. // related to the node.
if err := graph.DeleteLightningNode(testPub); err != nil { if err := graph.DeleteLightningNode(testPub); err != nil {
t.Fatalf("unable to delete node; %v", err) t.Fatalf("unable to delete node: %v", err)
} }
// Finally, attempt to fetch the node again. This should fail as the // Finally, attempt to fetch the node again. This should fail as the
@ -218,7 +220,11 @@ func TestAliasLookup(t *testing.T) {
// Next, attempt to lookup the alias. The alias should exactly match // Next, attempt to lookup the alias. The alias should exactly match
// the one which the test node was assigned. // the one which the test node was assigned.
dbAlias, err := graph.LookupAlias(testNode.PubKey) nodePub, err := testNode.PubKey()
if err != nil {
t.Fatalf("unable to generate pubkey: %v", err)
}
dbAlias, err := graph.LookupAlias(nodePub)
if err != nil { if err != nil {
t.Fatalf("unable to find alias: %v", err) t.Fatalf("unable to find alias: %v", err)
} }
@ -232,7 +238,11 @@ func TestAliasLookup(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("unable to create test node: %v", err) t.Fatalf("unable to create test node: %v", err)
} }
_, err = graph.LookupAlias(node.PubKey) nodePub, err = node.PubKey()
if err != nil {
t.Fatalf("unable to generate pubkey: %v", err)
}
_, err = graph.LookupAlias(nodePub)
if err != ErrNodeAliasNotFound { if err != ErrNodeAliasNotFound {
t.Fatalf("alias lookup should fail for non-existent pubkey") t.Fatalf("alias lookup should fail for non-existent pubkey")
} }
@ -311,22 +321,30 @@ func TestEdgeInsertionDeletion(t *testing.T) {
// Add the new edge to the database, this should proceed without any // Add the new edge to the database, this should proceed without any
// errors. // errors.
node1Pub, err := node1.PubKey()
if err != nil {
t.Fatalf("unable to generate node key: %v", err)
}
node2Pub, err := node2.PubKey()
if err != nil {
t.Fatalf("unable to generate node key: %v", err)
}
edgeInfo := ChannelEdgeInfo{ edgeInfo := ChannelEdgeInfo{
ChannelID: chanID, ChannelID: chanID,
ChainHash: key, ChainHash: key,
NodeKey1: node1.PubKey,
NodeKey2: node2.PubKey,
BitcoinKey1: node1.PubKey,
BitcoinKey2: node2.PubKey,
AuthProof: &ChannelAuthProof{ AuthProof: &ChannelAuthProof{
NodeSig1: testSig, NodeSig1Bytes: testSig.Serialize(),
NodeSig2: testSig, NodeSig2Bytes: testSig.Serialize(),
BitcoinSig1: testSig, BitcoinSig1Bytes: testSig.Serialize(),
BitcoinSig2: testSig, BitcoinSig2Bytes: testSig.Serialize(),
}, },
ChannelPoint: outpoint, ChannelPoint: outpoint,
Capacity: 9000, Capacity: 9000,
} }
copy(edgeInfo.NodeKey1Bytes[:], node1Pub.SerializeCompressed())
copy(edgeInfo.NodeKey2Bytes[:], node2Pub.SerializeCompressed())
copy(edgeInfo.BitcoinKey1Bytes[:], node1Pub.SerializeCompressed())
copy(edgeInfo.BitcoinKey2Bytes[:], node2Pub.SerializeCompressed())
if err := graph.AddChannelEdge(&edgeInfo); err != nil { if err := graph.AddChannelEdge(&edgeInfo); err != nil {
t.Fatalf("unable to create channel edge: %v", err) t.Fatalf("unable to create channel edge: %v", err)
@ -413,22 +431,26 @@ func TestDisconnectBlockAtHeight(t *testing.T) {
Index: outPointIndex, Index: outPointIndex,
} }
node1Pub, _ := node1.PubKey()
node2Pub, _ := node2.PubKey()
edgeInfo := ChannelEdgeInfo{ edgeInfo := ChannelEdgeInfo{
ChannelID: shortChanID.ToUint64(), ChannelID: shortChanID.ToUint64(),
ChainHash: key, ChainHash: key,
NodeKey1: node1.PubKey,
NodeKey2: node2.PubKey,
BitcoinKey1: node1.PubKey,
BitcoinKey2: node2.PubKey,
AuthProof: &ChannelAuthProof{ AuthProof: &ChannelAuthProof{
NodeSig1: testSig, NodeSig1Bytes: testSig.Serialize(),
NodeSig2: testSig, NodeSig2Bytes: testSig.Serialize(),
BitcoinSig1: testSig, BitcoinSig1Bytes: testSig.Serialize(),
BitcoinSig2: testSig, BitcoinSig2Bytes: testSig.Serialize(),
}, },
ChannelPoint: outpoint, ChannelPoint: outpoint,
Capacity: 9000, Capacity: 9000,
} }
copy(edgeInfo.NodeKey1Bytes[:], node1Pub.SerializeCompressed())
copy(edgeInfo.NodeKey2Bytes[:], node2Pub.SerializeCompressed())
copy(edgeInfo.BitcoinKey1Bytes[:], node1Pub.SerializeCompressed())
copy(edgeInfo.BitcoinKey2Bytes[:], node2Pub.SerializeCompressed())
return edgeInfo return edgeInfo
} }
@ -530,16 +552,16 @@ func assertEdgeInfoEqual(t *testing.T, e1 *ChannelEdgeInfo,
e2.ChainHash) e2.ChainHash)
} }
if !e1.NodeKey1.IsEqual(e2.NodeKey1) { if !bytes.Equal(e1.NodeKey1Bytes[:], e2.NodeKey1Bytes[:]) {
t.Fatalf("nodekey1 doesn't match") t.Fatalf("nodekey1 doesn't match")
} }
if !e1.NodeKey2.IsEqual(e2.NodeKey2) { if !bytes.Equal(e1.NodeKey2Bytes[:], e2.NodeKey2Bytes[:]) {
t.Fatalf("nodekey2 doesn't match") t.Fatalf("nodekey2 doesn't match")
} }
if !e1.BitcoinKey1.IsEqual(e2.BitcoinKey1) { if !bytes.Equal(e1.BitcoinKey1Bytes[:], e2.BitcoinKey1Bytes[:]) {
t.Fatalf("bitcoinkey1 doesn't match") t.Fatalf("bitcoinkey1 doesn't match")
} }
if !e1.BitcoinKey2.IsEqual(e2.BitcoinKey2) { if !bytes.Equal(e1.BitcoinKey2Bytes[:], e2.BitcoinKey2Bytes[:]) {
t.Fatalf("bitcoinkey2 doesn't match") t.Fatalf("bitcoinkey2 doesn't match")
} }
@ -548,18 +570,18 @@ func assertEdgeInfoEqual(t *testing.T, e1 *ChannelEdgeInfo,
e2.Features) e2.Features)
} }
if !e1.AuthProof.NodeSig1.IsEqual(e2.AuthProof.NodeSig1) { if !bytes.Equal(e1.AuthProof.NodeSig1Bytes, e2.AuthProof.NodeSig1Bytes) {
t.Fatalf("nodesig1 doesn't match: %v vs %v", t.Fatalf("nodesig1 doesn't match: %v vs %v",
spew.Sdump(e1.AuthProof.NodeSig1), spew.Sdump(e1.AuthProof.NodeSig1Bytes),
spew.Sdump(e2.AuthProof.NodeSig1)) spew.Sdump(e2.AuthProof.NodeSig1Bytes))
} }
if !e1.AuthProof.NodeSig2.IsEqual(e2.AuthProof.NodeSig2) { if !bytes.Equal(e1.AuthProof.NodeSig2Bytes, e2.AuthProof.NodeSig2Bytes) {
t.Fatalf("nodesig2 doesn't match") t.Fatalf("nodesig2 doesn't match")
} }
if !e1.AuthProof.BitcoinSig1.IsEqual(e2.AuthProof.BitcoinSig1) { if !bytes.Equal(e1.AuthProof.BitcoinSig1Bytes, e2.AuthProof.BitcoinSig1Bytes) {
t.Fatalf("bitcoinsig1 doesn't match") t.Fatalf("bitcoinsig1 doesn't match")
} }
if !e1.AuthProof.BitcoinSig2.IsEqual(e2.AuthProof.BitcoinSig2) { if !bytes.Equal(e1.AuthProof.BitcoinSig2Bytes, e2.AuthProof.BitcoinSig2Bytes) {
t.Fatalf("bitcoinsig2 doesn't match") t.Fatalf("bitcoinsig2 doesn't match")
} }
@ -606,9 +628,7 @@ func TestEdgeInfoUpdates(t *testing.T) {
firstNode *LightningNode firstNode *LightningNode
secondNode *LightningNode secondNode *LightningNode
) )
node1Bytes := node1.PubKey.SerializeCompressed() if bytes.Compare(node1.PubKeyBytes[:], node2.PubKeyBytes[:]) == -1 {
node2Bytes := node2.PubKey.SerializeCompressed()
if bytes.Compare(node1Bytes, node2Bytes) == -1 {
firstNode = node1 firstNode = node1
secondNode = node2 secondNode = node2
} else { } else {
@ -629,19 +649,19 @@ func TestEdgeInfoUpdates(t *testing.T) {
edgeInfo := &ChannelEdgeInfo{ edgeInfo := &ChannelEdgeInfo{
ChannelID: chanID, ChannelID: chanID,
ChainHash: key, ChainHash: key,
NodeKey1: firstNode.PubKey,
NodeKey2: secondNode.PubKey,
BitcoinKey1: firstNode.PubKey,
BitcoinKey2: secondNode.PubKey,
AuthProof: &ChannelAuthProof{ AuthProof: &ChannelAuthProof{
NodeSig1: testSig, NodeSig1Bytes: testSig.Serialize(),
NodeSig2: testSig, NodeSig2Bytes: testSig.Serialize(),
BitcoinSig1: testSig, BitcoinSig1Bytes: testSig.Serialize(),
BitcoinSig2: testSig, BitcoinSig2Bytes: testSig.Serialize(),
}, },
ChannelPoint: outpoint, ChannelPoint: outpoint,
Capacity: 1000, Capacity: 1000,
} }
copy(edgeInfo.NodeKey1Bytes[:], firstNode.PubKeyBytes[:])
copy(edgeInfo.NodeKey2Bytes[:], secondNode.PubKeyBytes[:])
copy(edgeInfo.BitcoinKey1Bytes[:], firstNode.PubKeyBytes[:])
copy(edgeInfo.BitcoinKey2Bytes[:], secondNode.PubKeyBytes[:])
if err := graph.AddChannelEdge(edgeInfo); err != nil { if err := graph.AddChannelEdge(edgeInfo); err != nil {
t.Fatalf("unable to create channel edge: %v", err) t.Fatalf("unable to create channel edge: %v", err)
} }
@ -649,7 +669,7 @@ func TestEdgeInfoUpdates(t *testing.T) {
// With the edge added, we can now create some fake edge information to // With the edge added, we can now create some fake edge information to
// update for both edges. // update for both edges.
edge1 := &ChannelEdgePolicy{ edge1 := &ChannelEdgePolicy{
Signature: testSig, SigBytes: testSig.Serialize(),
ChannelID: chanID, ChannelID: chanID,
LastUpdate: time.Unix(433453, 0), LastUpdate: time.Unix(433453, 0),
Flags: 0, Flags: 0,
@ -661,7 +681,7 @@ func TestEdgeInfoUpdates(t *testing.T) {
db: db, db: db,
} }
edge2 := &ChannelEdgePolicy{ edge2 := &ChannelEdgePolicy{
Signature: testSig, SigBytes: testSig.Serialize(),
ChannelID: chanID, ChannelID: chanID,
LastUpdate: time.Unix(124234, 0), LastUpdate: time.Unix(124234, 0),
Flags: 1, Flags: 1,
@ -796,9 +816,7 @@ func TestGraphTraversal(t *testing.T) {
// Determine which node is "smaller", we'll need this in order to // Determine which node is "smaller", we'll need this in order to
// properly create the edges for the graph. // properly create the edges for the graph.
var firstNode, secondNode *LightningNode var firstNode, secondNode *LightningNode
node1Bytes := nodes[0].PubKey.SerializeCompressed() if bytes.Compare(nodes[0].PubKeyBytes[:], nodes[1].PubKeyBytes[:]) == -1 {
node2Bytes := nodes[1].PubKey.SerializeCompressed()
if bytes.Compare(node1Bytes, node2Bytes) == -1 {
firstNode = nodes[0] firstNode = nodes[0]
secondNode = nodes[1] secondNode = nodes[1]
} else { } else {
@ -820,19 +838,19 @@ func TestGraphTraversal(t *testing.T) {
edgeInfo := ChannelEdgeInfo{ edgeInfo := ChannelEdgeInfo{
ChannelID: chanID, ChannelID: chanID,
ChainHash: key, ChainHash: key,
NodeKey1: nodes[0].PubKey,
NodeKey2: nodes[1].PubKey,
BitcoinKey1: nodes[0].PubKey,
BitcoinKey2: nodes[1].PubKey,
AuthProof: &ChannelAuthProof{ AuthProof: &ChannelAuthProof{
NodeSig1: testSig, NodeSig1Bytes: testSig.Serialize(),
NodeSig2: testSig, NodeSig2Bytes: testSig.Serialize(),
BitcoinSig1: testSig, BitcoinSig1Bytes: testSig.Serialize(),
BitcoinSig2: testSig, BitcoinSig2Bytes: testSig.Serialize(),
}, },
ChannelPoint: op, ChannelPoint: op,
Capacity: 1000, Capacity: 1000,
} }
copy(edgeInfo.NodeKey1Bytes[:], nodes[0].PubKeyBytes[:])
copy(edgeInfo.NodeKey2Bytes[:], nodes[1].PubKeyBytes[:])
copy(edgeInfo.BitcoinKey1Bytes[:], nodes[0].PubKeyBytes[:])
copy(edgeInfo.BitcoinKey2Bytes[:], nodes[1].PubKeyBytes[:])
err := graph.AddChannelEdge(&edgeInfo) err := graph.AddChannelEdge(&edgeInfo)
if err != nil { if err != nil {
t.Fatalf("unable to add node: %v", err) t.Fatalf("unable to add node: %v", err)
@ -843,7 +861,7 @@ func TestGraphTraversal(t *testing.T) {
edge := randEdgePolicy(chanID, op, db) edge := randEdgePolicy(chanID, op, db)
edge.Flags = 0 edge.Flags = 0
edge.Node = secondNode edge.Node = secondNode
edge.Signature = testSig edge.SigBytes = testSig.Serialize()
if err := graph.UpdateEdgePolicy(edge); err != nil { if err := graph.UpdateEdgePolicy(edge); err != nil {
t.Fatalf("unable to update edge: %v", err) t.Fatalf("unable to update edge: %v", err)
} }
@ -853,7 +871,7 @@ func TestGraphTraversal(t *testing.T) {
edge = randEdgePolicy(chanID, op, db) edge = randEdgePolicy(chanID, op, db)
edge.Flags = 1 edge.Flags = 1
edge.Node = firstNode edge.Node = firstNode
edge.Signature = testSig edge.SigBytes = testSig.Serialize()
if err := graph.UpdateEdgePolicy(edge); err != nil { if err := graph.UpdateEdgePolicy(edge); err != nil {
t.Fatalf("unable to update edge: %v", err) t.Fatalf("unable to update edge: %v", err)
} }
@ -885,13 +903,13 @@ func TestGraphTraversal(t *testing.T) {
// Each each should indicate that it's outgoing (pointed // Each each should indicate that it's outgoing (pointed
// towards the second node). // towards the second node).
if !outEdge.Node.PubKey.IsEqual(secondNode.PubKey) { if !bytes.Equal(outEdge.Node.PubKeyBytes[:], secondNode.PubKeyBytes[:]) {
return fmt.Errorf("wrong outgoing edge") return fmt.Errorf("wrong outgoing edge")
} }
// The incoming edge should also indicate that it's pointing to // The incoming edge should also indicate that it's pointing to
// the origin node. // the origin node.
if !inEdge.Node.PubKey.IsEqual(firstNode.PubKey) { if !bytes.Equal(inEdge.Node.PubKeyBytes[:], firstNode.PubKeyBytes[:]) {
return fmt.Errorf("wrong outgoing edge") return fmt.Errorf("wrong outgoing edge")
} }
@ -1010,20 +1028,19 @@ func TestGraphPruning(t *testing.T) {
edgeInfo := ChannelEdgeInfo{ edgeInfo := ChannelEdgeInfo{
ChannelID: chanID, ChannelID: chanID,
ChainHash: key, ChainHash: key,
NodeKey1: graphNodes[i].PubKey,
NodeKey2: graphNodes[i+1].PubKey,
BitcoinKey1: graphNodes[i].PubKey,
BitcoinKey2: graphNodes[i+1].PubKey,
AuthProof: &ChannelAuthProof{ AuthProof: &ChannelAuthProof{
NodeSig1: testSig, NodeSig1Bytes: testSig.Serialize(),
NodeSig2: testSig, NodeSig2Bytes: testSig.Serialize(),
BitcoinSig1: testSig, BitcoinSig1Bytes: testSig.Serialize(),
BitcoinSig2: testSig, BitcoinSig2Bytes: testSig.Serialize(),
}, },
ChannelPoint: op, ChannelPoint: op,
Capacity: 1000, Capacity: 1000,
} }
copy(edgeInfo.NodeKey1Bytes[:], graphNodes[i].PubKeyBytes[:])
copy(edgeInfo.NodeKey2Bytes[:], graphNodes[i+1].PubKeyBytes[:])
copy(edgeInfo.BitcoinKey1Bytes[:], graphNodes[i].PubKeyBytes[:])
copy(edgeInfo.BitcoinKey2Bytes[:], graphNodes[i+1].PubKeyBytes[:])
if err := graph.AddChannelEdge(&edgeInfo); err != nil { if err := graph.AddChannelEdge(&edgeInfo); err != nil {
t.Fatalf("unable to add node: %v", err) t.Fatalf("unable to add node: %v", err)
} }
@ -1033,7 +1050,7 @@ func TestGraphPruning(t *testing.T) {
edge := randEdgePolicy(chanID, op, db) edge := randEdgePolicy(chanID, op, db)
edge.Flags = 0 edge.Flags = 0
edge.Node = graphNodes[i] edge.Node = graphNodes[i]
edge.Signature = testSig edge.SigBytes = testSig.Serialize()
if err := graph.UpdateEdgePolicy(edge); err != nil { if err := graph.UpdateEdgePolicy(edge); err != nil {
t.Fatalf("unable to update edge: %v", err) t.Fatalf("unable to update edge: %v", err)
} }
@ -1043,7 +1060,7 @@ func TestGraphPruning(t *testing.T) {
edge = randEdgePolicy(chanID, op, db) edge = randEdgePolicy(chanID, op, db)
edge.Flags = 1 edge.Flags = 1
edge.Node = graphNodes[i] edge.Node = graphNodes[i]
edge.Signature = testSig edge.SigBytes = testSig.Serialize()
if err := graph.UpdateEdgePolicy(edge); err != nil { if err := graph.UpdateEdgePolicy(edge); err != nil {
t.Fatalf("unable to update edge: %v", err) t.Fatalf("unable to update edge: %v", err)
} }
@ -1159,9 +1176,9 @@ func compareNodes(a, b *LightningNode) error {
return fmt.Errorf("Addresses doesn't match: expected %#v, \n "+ return fmt.Errorf("Addresses doesn't match: expected %#v, \n "+
"got %#v", a.Addresses, b.Addresses) "got %#v", a.Addresses, b.Addresses)
} }
if !reflect.DeepEqual(a.PubKey, b.PubKey) { if !reflect.DeepEqual(a.PubKeyBytes, b.PubKeyBytes) {
return fmt.Errorf("PubKey doesn't match: expected %#v, \n "+ return fmt.Errorf("PubKey doesn't match: expected %#v, \n "+
"got %#v", a.PubKey, b.PubKey) "got %#v", a.PubKeyBytes, b.PubKeyBytes)
} }
if !reflect.DeepEqual(a.Color, b.Color) { if !reflect.DeepEqual(a.Color, b.Color) {
return fmt.Errorf("Color doesn't match: expected %#v, \n "+ return fmt.Errorf("Color doesn't match: expected %#v, \n "+

@ -21,8 +21,8 @@ func TestWaitingProofStore(t *testing.T) {
defer cleanup() defer cleanup()
proof1 := NewWaitingProof(true, &lnwire.AnnounceSignatures{ proof1 := NewWaitingProof(true, &lnwire.AnnounceSignatures{
NodeSignature: testSig, NodeSignature: wireSig,
BitcoinSignature: testSig, BitcoinSignature: wireSig,
}) })
store, err := NewWaitingProofStore(db) store, err := NewWaitingProofStore(db)