discovery: update graph API usage to match recent API changes

This commit is contained in:
Olaoluwa Osuntokun 2018-01-30 20:23:14 -08:00
parent 5e9166e478
commit cd9d2d7e6f
No known key found for this signature in database
GPG Key ID: 964EA263DD637C21
4 changed files with 319 additions and 122 deletions

@ -26,23 +26,56 @@ func ValidateChannelAnn(a *lnwire.ChannelAnnouncement) error {
// First we'll verify that the passed bitcoin key signature is indeed a // First we'll verify that the passed bitcoin key signature is indeed a
// signature over the computed hash digest. // signature over the computed hash digest.
if !a.BitcoinSig1.Verify(dataHash, copyPubKey(a.BitcoinKey1)) { bitcoinSig1, err := a.BitcoinSig1.ToSignature()
if err != nil {
return err
}
bitcoinKey1, err := btcec.ParsePubKey(a.BitcoinKey1[:], btcec.S256())
if err != nil {
return err
}
if !bitcoinSig1.Verify(dataHash, bitcoinKey1) {
return errors.New("can't verify first bitcoin signature") return errors.New("can't verify first bitcoin signature")
} }
// If that checks out, then we'll verify that the second bitcoin // If that checks out, then we'll verify that the second bitcoin
// signature is a valid signature of the bitcoin public key over hash // signature is a valid signature of the bitcoin public key over hash
// digest as well. // digest as well.
if !a.BitcoinSig2.Verify(dataHash, copyPubKey(a.BitcoinKey2)) { bitcoinSig2, err := a.BitcoinSig2.ToSignature()
if err != nil {
return err
}
bitcoinKey2, err := btcec.ParsePubKey(a.BitcoinKey2[:], btcec.S256())
if err != nil {
return err
}
if !bitcoinSig2.Verify(dataHash, bitcoinKey2) {
return errors.New("can't verify second bitcoin signature") return errors.New("can't verify second bitcoin signature")
} }
// Both node signatures attached should indeed be a valid signature // Both node signatures attached should indeed be a valid signature
// over the selected digest of the channel announcement signature. // over the selected digest of the channel announcement signature.
if !a.NodeSig1.Verify(dataHash, copyPubKey(a.NodeID1)) { nodeSig1, err := a.NodeSig1.ToSignature()
if err != nil {
return err
}
nodeKey1, err := btcec.ParsePubKey(a.NodeID1[:], btcec.S256())
if err != nil {
return err
}
if !nodeSig1.Verify(dataHash, nodeKey1) {
return errors.New("can't verify data in first node signature") return errors.New("can't verify data in first node signature")
} }
if !a.NodeSig2.Verify(dataHash, copyPubKey(a.NodeID2)) {
nodeSig2, err := a.NodeSig2.ToSignature()
if err != nil {
return err
}
nodeKey2, err := btcec.ParsePubKey(a.NodeID2[:], btcec.S256())
if err != nil {
return err
}
if !nodeSig2.Verify(dataHash, nodeKey2) {
return errors.New("can't verify data in second node signature") return errors.New("can't verify data in second node signature")
} }
@ -61,17 +94,26 @@ func ValidateNodeAnn(a *lnwire.NodeAnnouncement) error {
return err return err
} }
nodeSig, err := a.Signature.ToSignature()
if err != nil {
return err
}
nodeKey, err := btcec.ParsePubKey(a.NodeID[:], btcec.S256())
if err != nil {
return err
}
// Finally ensure that the passed signature is valid, if not we'll // Finally ensure that the passed signature is valid, if not we'll
// return an error so this node announcement can be rejected. // return an error so this node announcement can be rejected.
dataHash := chainhash.DoubleHashB(data) dataHash := chainhash.DoubleHashB(data)
if !a.Signature.Verify(dataHash, copyPubKey(a.NodeID)) { if !nodeSig.Verify(dataHash, nodeKey) {
var msgBuf bytes.Buffer var msgBuf bytes.Buffer
if _, err := lnwire.WriteMessage(&msgBuf, a, 0); err != nil { if _, err := lnwire.WriteMessage(&msgBuf, a, 0); err != nil {
return err return err
} }
return errors.Errorf("signature on NodeAnnouncement(%x) is "+ return errors.Errorf("signature on NodeAnnouncement(%x) is "+
"invalid: %x", a.NodeID.SerializeCompressed(), "invalid: %x", nodeKey.SerializeCompressed(),
msgBuf.Bytes()) msgBuf.Bytes())
} }
@ -90,7 +132,12 @@ func ValidateChannelUpdateAnn(pubKey *btcec.PublicKey,
} }
dataHash := chainhash.DoubleHashB(data) dataHash := chainhash.DoubleHashB(data)
if !a.Signature.Verify(dataHash, copyPubKey(pubKey)) { nodeSig, err := a.Signature.ToSignature()
if err != nil {
return err
}
if !nodeSig.Verify(dataHash, pubKey) {
return errors.Errorf("invalid signature for channel "+ return errors.Errorf("invalid signature for channel "+
"update %v", spew.Sdump(a)) "update %v", spew.Sdump(a))
} }

@ -157,17 +157,17 @@ type AuthenticatedGossiper struct {
// TODO(roasbeef): limit premature networkMsgs to N // TODO(roasbeef): limit premature networkMsgs to N
prematureAnnouncements map[uint32][]*networkMsg prematureAnnouncements map[uint32][]*networkMsg
// prematureChannelUpdates is a map of ChannelUpdates we have // prematureChannelUpdates is a map of ChannelUpdates we have received
// received that wasn't associated with any channel we know about. // that wasn't associated with any channel we know about. We store
// We store them temporarily, such that we can reprocess them when // them temporarily, such that we can reprocess them when a
// a ChannelAnnouncement for the channel is received. // ChannelAnnouncement for the channel is received.
prematureChannelUpdates map[uint64][]*networkMsg prematureChannelUpdates map[uint64][]*networkMsg
pChanUpdMtx sync.Mutex pChanUpdMtx sync.Mutex
// waitingProofs is a persistent storage of partial channel proof // waitingProofs is a persistent storage of partial channel proof
// announcement messages. We use it to buffer half of the material // announcement messages. We use it to buffer half of the material
// needed to reconstruct a full authenticated channel announcement. Once // needed to reconstruct a full authenticated channel announcement.
// we receive the other half the channel proof, we'll be able to // Once we receive the other half the channel proof, we'll be able to
// properly validate it an re-broadcast it out to the network. // properly validate it an re-broadcast it out to the network.
waitingProofs *channeldb.WaitingProofStore waitingProofs *channeldb.WaitingProofStore
@ -176,8 +176,8 @@ type AuthenticatedGossiper struct {
// networkHandler. // networkHandler.
networkMsgs chan *networkMsg networkMsgs chan *networkMsg
// chanPolicyUpdates is a channel that requests to update the forwarding // chanPolicyUpdates is a channel that requests to update the
// policy of a set of channels is sent over. // forwarding policy of a set of channels is sent over.
chanPolicyUpdates chan *chanPolicyUpdateRequest chanPolicyUpdates chan *chanPolicyUpdateRequest
// bestHeight is the height of the block at the tip of the main chain // bestHeight is the height of the block at the tip of the main chain
@ -232,17 +232,22 @@ func (d *AuthenticatedGossiper) SynchronizeNode(pub *btcec.PublicKey) error {
// containing all the messages to be sent to the target peer. // containing all the messages to be sent to the target peer.
var announceMessages []lnwire.Message var announceMessages []lnwire.Message
makeNodeAnn := func(n *channeldb.LightningNode) *lnwire.NodeAnnouncement { makeNodeAnn := func(n *channeldb.LightningNode) (*lnwire.NodeAnnouncement, error) {
alias, _ := lnwire.NewNodeAlias(n.Alias) alias, _ := lnwire.NewNodeAlias(n.Alias)
wireSig, err := lnwire.NewSigFromRawSignature(n.AuthSigBytes)
if err != nil {
return nil, err
}
return &lnwire.NodeAnnouncement{ return &lnwire.NodeAnnouncement{
Signature: n.AuthSig, Signature: wireSig,
Timestamp: uint32(n.LastUpdate.Unix()), Timestamp: uint32(n.LastUpdate.Unix()),
Addresses: n.Addresses, Addresses: n.Addresses,
NodeID: n.PubKey, NodeID: n.PubKeyBytes,
Features: n.Features.RawFeatureVector, Features: n.Features.RawFeatureVector,
RGBColor: n.Color, RGBColor: n.Color,
Alias: alias, Alias: alias,
} }, nil
} }
// As peers are expecting channel announcements before node // As peers are expecting channel announcements before node
@ -262,8 +267,12 @@ func (d *AuthenticatedGossiper) SynchronizeNode(pub *btcec.PublicKey) error {
// also has known validated nodes, then we'll send that as // also has known validated nodes, then we'll send that as
// well. // well.
if chanInfo.AuthProof != nil { if chanInfo.AuthProof != nil {
chanAnn, e1Ann, e2Ann := createChanAnnouncement( chanAnn, e1Ann, e2Ann, err := createChanAnnouncement(
chanInfo.AuthProof, chanInfo, e1, e2) chanInfo.AuthProof, chanInfo, e1, e2,
)
if err != nil {
return err
}
announceMessages = append(announceMessages, chanAnn) announceMessages = append(announceMessages, chanAnn)
if e1Ann != nil { if e1Ann != nil {
@ -272,7 +281,10 @@ func (d *AuthenticatedGossiper) SynchronizeNode(pub *btcec.PublicKey) error {
// If this edge has a validated node // If this edge has a validated node
// announcement, then we'll send that as well. // announcement, then we'll send that as well.
if e1.Node.HaveNodeAnnouncement { if e1.Node.HaveNodeAnnouncement {
nodeAnn := makeNodeAnn(e1.Node) nodeAnn, err := makeNodeAnn(e1.Node)
if err != nil {
return err
}
announceMessages = append( announceMessages = append(
announceMessages, nodeAnn, announceMessages, nodeAnn,
) )
@ -285,7 +297,10 @@ func (d *AuthenticatedGossiper) SynchronizeNode(pub *btcec.PublicKey) error {
// If this edge has a validated node // If this edge has a validated node
// announcement, then we'll send that as well. // announcement, then we'll send that as well.
if e2.Node.HaveNodeAnnouncement { if e2.Node.HaveNodeAnnouncement {
nodeAnn := makeNodeAnn(e2.Node) nodeAnn, err := makeNodeAnn(e2.Node)
if err != nil {
return err
}
announceMessages = append( announceMessages = append(
announceMessages, nodeAnn, announceMessages, nodeAnn,
) )
@ -588,7 +603,7 @@ func (d *deDupedAnnouncements) addMsg(message networkMsg) {
// NodeID to create the corresponding Vertex. // NodeID to create the corresponding Vertex.
case *lnwire.NodeAnnouncement: case *lnwire.NodeAnnouncement:
sender := routing.NewVertex(message.peer) sender := routing.NewVertex(message.peer)
deDupKey := routing.NewVertex(msg.NodeID) deDupKey := routing.Vertex(msg.NodeID)
// We do the same for node announcements as we did for channel // We do the same for node announcements as we did for channel
// updates, as they also carry a timestamp. // updates, as they also carry a timestamp.
@ -1182,9 +1197,12 @@ func (d *AuthenticatedGossiper) processRejectedEdge(chanAnnMsg *lnwire.ChannelAn
// We'll then create then validate the new fully assembled // We'll then create then validate the new fully assembled
// announcement. // announcement.
chanAnn, e1Ann, e2Ann := createChanAnnouncement( chanAnn, e1Ann, e2Ann, err := createChanAnnouncement(
proof, chanInfo, e1, e2, proof, chanInfo, e1, e2,
) )
if err != nil {
return nil, err
}
err = ValidateChannelAnn(chanAnn) err = ValidateChannelAnn(chanAnn)
if err != nil { if err != nil {
err := errors.Errorf("assembled channel announcement proof "+ err := errors.Errorf("assembled channel announcement proof "+
@ -1265,9 +1283,9 @@ func (d *AuthenticatedGossiper) processNetworkAnnouncement(nMsg *networkMsg) []n
HaveNodeAnnouncement: true, HaveNodeAnnouncement: true,
LastUpdate: time.Unix(int64(msg.Timestamp), 0), LastUpdate: time.Unix(int64(msg.Timestamp), 0),
Addresses: msg.Addresses, Addresses: msg.Addresses,
PubKey: msg.NodeID, PubKeyBytes: msg.NodeID,
Alias: msg.Alias.String(), Alias: msg.Alias.String(),
AuthSig: msg.Signature, AuthSigBytes: msg.Signature.ToSignatureBytes(),
Features: features, Features: features,
Color: msg.RGBColor, Color: msg.RGBColor,
} }
@ -1348,10 +1366,10 @@ func (d *AuthenticatedGossiper) processNetworkAnnouncement(nMsg *networkMsg) []n
// itself to the database so we can fetch it later when // itself to the database so we can fetch it later when
// gossiping with other nodes. // gossiping with other nodes.
proof = &channeldb.ChannelAuthProof{ proof = &channeldb.ChannelAuthProof{
NodeSig1: msg.NodeSig1, NodeSig1Bytes: msg.NodeSig1.ToSignatureBytes(),
NodeSig2: msg.NodeSig2, NodeSig2Bytes: msg.NodeSig2.ToSignatureBytes(),
BitcoinSig1: msg.BitcoinSig1, BitcoinSig1Bytes: msg.BitcoinSig1.ToSignatureBytes(),
BitcoinSig2: msg.BitcoinSig2, BitcoinSig2Bytes: msg.BitcoinSig2.ToSignatureBytes(),
} }
} }
@ -1367,10 +1385,10 @@ func (d *AuthenticatedGossiper) processNetworkAnnouncement(nMsg *networkMsg) []n
edge := &channeldb.ChannelEdgeInfo{ edge := &channeldb.ChannelEdgeInfo{
ChannelID: msg.ShortChannelID.ToUint64(), ChannelID: msg.ShortChannelID.ToUint64(),
ChainHash: msg.ChainHash, ChainHash: msg.ChainHash,
NodeKey1: msg.NodeID1, NodeKey1Bytes: msg.NodeID1,
NodeKey2: msg.NodeID2, NodeKey2Bytes: msg.NodeID2,
BitcoinKey1: msg.BitcoinKey1, BitcoinKey1Bytes: msg.BitcoinKey1,
BitcoinKey2: msg.BitcoinKey2, BitcoinKey2Bytes: msg.BitcoinKey2,
AuthProof: proof, AuthProof: proof,
Features: featureBuf.Bytes(), Features: featureBuf.Bytes(),
} }
@ -1560,7 +1578,7 @@ func (d *AuthenticatedGossiper) processNetworkAnnouncement(nMsg *networkMsg) []n
d.prematureChannelUpdates[shortChanID], d.prematureChannelUpdates[shortChanID],
nMsg) nMsg)
d.pChanUpdMtx.Unlock() d.pChanUpdMtx.Unlock()
log.Infof("Got ChannelUpdate for edge not "+ log.Debugf("Got ChannelUpdate for edge not "+
"found in graph(shortChanID=%v), "+ "found in graph(shortChanID=%v), "+
"saving for reprocessing later", "saving for reprocessing later",
shortChanID) shortChanID)
@ -1582,9 +1600,9 @@ func (d *AuthenticatedGossiper) processNetworkAnnouncement(nMsg *networkMsg) []n
var pubKey *btcec.PublicKey var pubKey *btcec.PublicKey
switch { switch {
case msg.Flags&lnwire.ChanUpdateDirection == 0: case msg.Flags&lnwire.ChanUpdateDirection == 0:
pubKey = chanInfo.NodeKey1 pubKey, _ = chanInfo.NodeKey1()
case msg.Flags&lnwire.ChanUpdateDirection == 1: case msg.Flags&lnwire.ChanUpdateDirection == 1:
pubKey = chanInfo.NodeKey2 pubKey, _ = chanInfo.NodeKey2()
} }
// Validate the channel announcement with the expected public // Validate the channel announcement with the expected public
@ -1601,7 +1619,7 @@ func (d *AuthenticatedGossiper) processNetworkAnnouncement(nMsg *networkMsg) []n
} }
update := &channeldb.ChannelEdgePolicy{ update := &channeldb.ChannelEdgePolicy{
Signature: msg.Signature, SigBytes: msg.Signature.ToSignatureBytes(),
ChannelID: shortChanID, ChannelID: shortChanID,
LastUpdate: time.Unix(int64(msg.Timestamp), 0), LastUpdate: time.Unix(int64(msg.Timestamp), 0),
Flags: msg.Flags, Flags: msg.Flags,
@ -1632,9 +1650,9 @@ func (d *AuthenticatedGossiper) processNetworkAnnouncement(nMsg *networkMsg) []n
var remotePeer *btcec.PublicKey var remotePeer *btcec.PublicKey
switch { switch {
case msg.Flags&lnwire.ChanUpdateDirection == 0: case msg.Flags&lnwire.ChanUpdateDirection == 0:
remotePeer = chanInfo.NodeKey2 remotePeer, _ = chanInfo.NodeKey2()
case msg.Flags&lnwire.ChanUpdateDirection == 1: case msg.Flags&lnwire.ChanUpdateDirection == 1:
remotePeer = chanInfo.NodeKey1 remotePeer, _ = chanInfo.NodeKey1()
} }
// Send ChannelUpdate directly to remotePeer. // Send ChannelUpdate directly to remotePeer.
@ -1726,9 +1744,9 @@ func (d *AuthenticatedGossiper) processNetworkAnnouncement(nMsg *networkMsg) []n
} }
isFirstNode := bytes.Equal(nMsg.peer.SerializeCompressed(), isFirstNode := bytes.Equal(nMsg.peer.SerializeCompressed(),
chanInfo.NodeKey1.SerializeCompressed()) chanInfo.NodeKey1Bytes[:])
isSecondNode := bytes.Equal(nMsg.peer.SerializeCompressed(), isSecondNode := bytes.Equal(nMsg.peer.SerializeCompressed(),
chanInfo.NodeKey2.SerializeCompressed()) chanInfo.NodeKey2Bytes[:])
// Ensure that channel that was retrieved belongs to the peer // Ensure that channel that was retrieved belongs to the peer
// which sent the proof announcement. // which sent the proof announcement.
@ -1748,9 +1766,9 @@ func (d *AuthenticatedGossiper) processNetworkAnnouncement(nMsg *networkMsg) []n
if !nMsg.isRemote { if !nMsg.isRemote {
var remotePeer *btcec.PublicKey var remotePeer *btcec.PublicKey
if isFirstNode { if isFirstNode {
remotePeer = chanInfo.NodeKey2 remotePeer, _ = chanInfo.NodeKey2()
} else { } else {
remotePeer = chanInfo.NodeKey1 remotePeer, _ = chanInfo.NodeKey1()
} }
// Since the remote peer might not be online // Since the remote peer might not be online
// we'll call a method that will attempt to // we'll call a method that will attempt to
@ -1786,9 +1804,14 @@ func (d *AuthenticatedGossiper) processNetworkAnnouncement(nMsg *networkMsg) []n
msg.ChannelID, msg.ChannelID,
peerID) peerID)
chanAnn, _, _ := createChanAnnouncement( chanAnn, _, _, err := createChanAnnouncement(
chanInfo.AuthProof, chanInfo, e1, e2) chanInfo.AuthProof, chanInfo, e1, e2,
err := d.cfg.SendToPeer(nMsg.peer, chanAnn) )
if err != nil {
log.Error("unable to gen ann: %v", err)
return
}
err = d.cfg.SendToPeer(nMsg.peer, chanAnn)
if err != nil { if err != nil {
log.Errorf("Failed sending "+ log.Errorf("Failed sending "+
"full proof to "+ "full proof to "+
@ -1846,17 +1869,22 @@ func (d *AuthenticatedGossiper) processNetworkAnnouncement(nMsg *networkMsg) []n
// validate it shortly below. // validate it shortly below.
var dbProof channeldb.ChannelAuthProof var dbProof channeldb.ChannelAuthProof
if isFirstNode { if isFirstNode {
dbProof.NodeSig1 = msg.NodeSignature dbProof.NodeSig1Bytes = msg.NodeSignature.ToSignatureBytes()
dbProof.NodeSig2 = oppositeProof.NodeSignature dbProof.NodeSig2Bytes = oppositeProof.NodeSignature.ToSignatureBytes()
dbProof.BitcoinSig1 = msg.BitcoinSignature dbProof.BitcoinSig1Bytes = msg.BitcoinSignature.ToSignatureBytes()
dbProof.BitcoinSig2 = oppositeProof.BitcoinSignature dbProof.BitcoinSig2Bytes = oppositeProof.BitcoinSignature.ToSignatureBytes()
} else { } else {
dbProof.NodeSig1 = oppositeProof.NodeSignature dbProof.NodeSig1Bytes = oppositeProof.NodeSignature.ToSignatureBytes()
dbProof.NodeSig2 = msg.NodeSignature dbProof.NodeSig2Bytes = msg.NodeSignature.ToSignatureBytes()
dbProof.BitcoinSig1 = oppositeProof.BitcoinSignature dbProof.BitcoinSig1Bytes = oppositeProof.BitcoinSignature.ToSignatureBytes()
dbProof.BitcoinSig2 = msg.BitcoinSignature dbProof.BitcoinSig2Bytes = msg.BitcoinSignature.ToSignatureBytes()
}
chanAnn, e1Ann, e2Ann, err := createChanAnnouncement(&dbProof, chanInfo, e1, e2)
if err != nil {
log.Error(err)
nMsg.err <- err
return nil
} }
chanAnn, e1Ann, e2Ann := createChanAnnouncement(&dbProof, chanInfo, e1, e2)
// With all the necessary components assembled validate the // With all the necessary components assembled validate the
// full channel announcement proof. // full channel announcement proof.
@ -2017,6 +2045,8 @@ func (d *AuthenticatedGossiper) sendAnnSigReliably(
func (d *AuthenticatedGossiper) updateChannel(info *channeldb.ChannelEdgeInfo, func (d *AuthenticatedGossiper) updateChannel(info *channeldb.ChannelEdgeInfo,
edge *channeldb.ChannelEdgePolicy) (*lnwire.ChannelAnnouncement, *lnwire.ChannelUpdate, error) { edge *channeldb.ChannelEdgePolicy) (*lnwire.ChannelAnnouncement, *lnwire.ChannelUpdate, error) {
var err error
// Make sure timestamp is always increased, such that our update // Make sure timestamp is always increased, such that our update
// gets propagated. // gets propagated.
timestamp := time.Now().Unix() timestamp := time.Now().Unix()
@ -2025,7 +2055,6 @@ func (d *AuthenticatedGossiper) updateChannel(info *channeldb.ChannelEdgeInfo,
} }
edge.LastUpdate = time.Unix(timestamp, 0) edge.LastUpdate = time.Unix(timestamp, 0)
chanUpdate := &lnwire.ChannelUpdate{ chanUpdate := &lnwire.ChannelUpdate{
Signature: edge.Signature,
ChainHash: info.ChainHash, ChainHash: info.ChainHash,
ShortChannelID: lnwire.NewShortChanIDFromInt(edge.ChannelID), ShortChannelID: lnwire.NewShortChanIDFromInt(edge.ChannelID),
Timestamp: uint32(timestamp), Timestamp: uint32(timestamp),
@ -2035,6 +2064,10 @@ func (d *AuthenticatedGossiper) updateChannel(info *channeldb.ChannelEdgeInfo,
BaseFee: uint32(edge.FeeBaseMSat), BaseFee: uint32(edge.FeeBaseMSat),
FeeRate: uint32(edge.FeeProportionalMillionths), FeeRate: uint32(edge.FeeProportionalMillionths),
} }
chanUpdate.Signature, err = lnwire.NewSigFromRawSignature(edge.SigBytes)
if err != nil {
return nil, nil, err
}
// With the update applied, we'll generate a new signature over a // With the update applied, we'll generate a new signature over a
// digest of the channel announcement itself. // digest of the channel announcement itself.
@ -2045,8 +2078,11 @@ func (d *AuthenticatedGossiper) updateChannel(info *channeldb.ChannelEdgeInfo,
// Next, we'll set the new signature in place, and update the reference // Next, we'll set the new signature in place, and update the reference
// in the backing slice. // in the backing slice.
edge.Signature = sig edge.SigBytes = sig.Serialize()
chanUpdate.Signature = sig chanUpdate.Signature, err = lnwire.NewSigFromSignature(sig)
if err != nil {
return nil, nil, err
}
// To ensure that our signature is valid, we'll verify it ourself // To ensure that our signature is valid, we'll verify it ourself
// before committing it to the slice returned. // before committing it to the slice returned.
@ -2057,7 +2093,6 @@ func (d *AuthenticatedGossiper) updateChannel(info *channeldb.ChannelEdgeInfo,
} }
// Finally, we'll write the new edge policy to disk. // Finally, we'll write the new edge policy to disk.
edge.Node.PubKey.Curve = nil
if err := d.cfg.Router.UpdateEdge(edge); err != nil { if err := d.cfg.Router.UpdateEdge(edge); err != nil {
return nil, nil, err return nil, nil, err
} }
@ -2069,17 +2104,37 @@ func (d *AuthenticatedGossiper) updateChannel(info *channeldb.ChannelEdgeInfo,
if info.AuthProof != nil { if info.AuthProof != nil {
chanID := lnwire.NewShortChanIDFromInt(info.ChannelID) chanID := lnwire.NewShortChanIDFromInt(info.ChannelID)
chanAnn = &lnwire.ChannelAnnouncement{ chanAnn = &lnwire.ChannelAnnouncement{
NodeSig1: info.AuthProof.NodeSig1,
NodeSig2: info.AuthProof.NodeSig2,
ShortChannelID: chanID, ShortChannelID: chanID,
BitcoinSig1: info.AuthProof.BitcoinSig1, NodeID1: info.NodeKey1Bytes,
BitcoinSig2: info.AuthProof.BitcoinSig2, NodeID2: info.NodeKey2Bytes,
NodeID1: info.NodeKey1,
NodeID2: info.NodeKey2,
ChainHash: info.ChainHash, ChainHash: info.ChainHash,
BitcoinKey1: info.BitcoinKey1, BitcoinKey1: info.BitcoinKey1Bytes,
Features: lnwire.NewRawFeatureVector(), Features: lnwire.NewRawFeatureVector(),
BitcoinKey2: info.BitcoinKey2, BitcoinKey2: info.BitcoinKey2Bytes,
}
chanAnn.NodeSig1, err = lnwire.NewSigFromRawSignature(
info.AuthProof.NodeSig1Bytes,
)
if err != nil {
return nil, nil, err
}
chanAnn.NodeSig2, err = lnwire.NewSigFromRawSignature(
info.AuthProof.NodeSig2Bytes,
)
if err != nil {
return nil, nil, err
}
chanAnn.BitcoinSig1, err = lnwire.NewSigFromRawSignature(
info.AuthProof.BitcoinSig1Bytes,
)
if err != nil {
return nil, nil, err
}
chanAnn.BitcoinSig2, err = lnwire.NewSigFromRawSignature(
info.AuthProof.BitcoinSig2Bytes,
)
if err != nil {
return nil, nil, err
} }
} }

@ -305,10 +305,6 @@ func createAnnouncements(blockHeight uint32) (*annBatch, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
batch.localChanAnn.BitcoinSig1 = nil
batch.localChanAnn.BitcoinSig2 = nil
batch.localChanAnn.NodeSig1 = nil
batch.localChanAnn.NodeSig2 = nil
batch.chanUpdAnn1, err = createUpdateAnnouncement( batch.chanUpdAnn1, err = createUpdateAnnouncement(
blockHeight, 0, nodeKeyPriv1, timestamp, blockHeight, 0, nodeKeyPriv1, timestamp,
@ -342,13 +338,18 @@ func createNodeAnnouncement(priv *btcec.PrivateKey,
a := &lnwire.NodeAnnouncement{ a := &lnwire.NodeAnnouncement{
Timestamp: timestamp, Timestamp: timestamp,
Addresses: testAddrs, Addresses: testAddrs,
NodeID: priv.PubKey(),
Alias: alias, Alias: alias,
Features: testFeatures, Features: testFeatures,
} }
copy(a.NodeID[:], priv.PubKey().SerializeCompressed())
signer := mockSigner{priv} signer := mockSigner{priv}
a.Signature, err = SignAnnouncement(&signer, priv.PubKey(), a) sig, err := SignAnnouncement(&signer, priv.PubKey(), a)
if err != nil {
return nil, err
}
a.Signature, err = lnwire.NewSigFromSignature(sig)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -376,7 +377,13 @@ func createUpdateAnnouncement(blockHeight uint32, flags lnwire.ChanUpdateFlag,
pub := nodeKey.PubKey() pub := nodeKey.PubKey()
signer := mockSigner{nodeKey} signer := mockSigner{nodeKey}
if a.Signature, err = SignAnnouncement(&signer, pub, a); err != nil { sig, err := SignAnnouncement(&signer, pub, a)
if err != nil {
return nil, err
}
a.Signature, err = lnwire.NewSigFromSignature(sig)
if err != nil {
return nil, err return nil, err
} }
@ -392,34 +399,54 @@ func createRemoteChannelAnnouncement(blockHeight uint32) (*lnwire.ChannelAnnounc
TxIndex: 0, TxIndex: 0,
TxPosition: 0, TxPosition: 0,
}, },
NodeID1: nodeKeyPub1,
NodeID2: nodeKeyPub2,
BitcoinKey1: bitcoinKeyPub1,
BitcoinKey2: bitcoinKeyPub2,
Features: testFeatures, Features: testFeatures,
} }
copy(a.NodeID1[:], nodeKeyPub1.SerializeCompressed())
copy(a.NodeID2[:], nodeKeyPub2.SerializeCompressed())
copy(a.BitcoinKey1[:], bitcoinKeyPub1.SerializeCompressed())
copy(a.BitcoinKey2[:], bitcoinKeyPub2.SerializeCompressed())
pub := nodeKeyPriv1.PubKey() pub := nodeKeyPriv1.PubKey()
signer := mockSigner{nodeKeyPriv1} signer := mockSigner{nodeKeyPriv1}
if a.NodeSig1, err = SignAnnouncement(&signer, pub, a); err != nil { sig, err := SignAnnouncement(&signer, pub, a)
if err != nil {
return nil, err
}
a.NodeSig1, err = lnwire.NewSigFromSignature(sig)
if err != nil {
return nil, err return nil, err
} }
pub = nodeKeyPriv2.PubKey() pub = nodeKeyPriv2.PubKey()
signer = mockSigner{nodeKeyPriv2} signer = mockSigner{nodeKeyPriv2}
if a.NodeSig2, err = SignAnnouncement(&signer, pub, a); err != nil { sig, err = SignAnnouncement(&signer, pub, a)
if err != nil {
return nil, err
}
a.NodeSig2, err = lnwire.NewSigFromSignature(sig)
if err != nil {
return nil, err return nil, err
} }
pub = bitcoinKeyPriv1.PubKey() pub = bitcoinKeyPriv1.PubKey()
signer = mockSigner{bitcoinKeyPriv1} signer = mockSigner{bitcoinKeyPriv1}
if a.BitcoinSig1, err = SignAnnouncement(&signer, pub, a); err != nil { sig, err = SignAnnouncement(&signer, pub, a)
if err != nil {
return nil, err
}
a.BitcoinSig1, err = lnwire.NewSigFromSignature(sig)
if err != nil {
return nil, err return nil, err
} }
pub = bitcoinKeyPriv2.PubKey() pub = bitcoinKeyPriv2.PubKey()
signer = mockSigner{bitcoinKeyPriv2} signer = mockSigner{bitcoinKeyPriv2}
if a.BitcoinSig2, err = SignAnnouncement(&signer, pub, a); err != nil { sig, err = SignAnnouncement(&signer, pub, a)
if err != nil {
return nil, err
}
a.BitcoinSig2, err = lnwire.NewSigFromSignature(sig)
if err != nil {
return nil, err return nil, err
} }
@ -521,8 +548,10 @@ func TestProcessAnnouncement(t *testing.T) {
t.Fatalf("can't create node announcement: %v", err) t.Fatalf("can't create node announcement: %v", err)
} }
nodePub := nodeKeyPriv1.PubKey()
select { select {
case err = <-ctx.gossiper.ProcessRemoteAnnouncement(na, na.NodeID): case err = <-ctx.gossiper.ProcessRemoteAnnouncement(na, nodePub):
case <-time.After(2 * time.Second): case <-time.After(2 * time.Second):
t.Fatal("remote announcement not processed") t.Fatal("remote announcement not processed")
} }
@ -532,7 +561,7 @@ func TestProcessAnnouncement(t *testing.T) {
select { select {
case msg := <-ctx.broadcastedMessage: case msg := <-ctx.broadcastedMessage:
assertSenderExistence(na.NodeID, msg) assertSenderExistence(nodePub, msg)
case <-time.After(2 * trickleDelay): case <-time.After(2 * trickleDelay):
t.Fatal("announcement wasn't proceeded") t.Fatal("announcement wasn't proceeded")
} }
@ -550,7 +579,7 @@ func TestProcessAnnouncement(t *testing.T) {
} }
select { select {
case err = <-ctx.gossiper.ProcessRemoteAnnouncement(ca, na.NodeID): case err = <-ctx.gossiper.ProcessRemoteAnnouncement(ca, nodePub):
case <-time.After(2 * time.Second): case <-time.After(2 * time.Second):
t.Fatal("remote announcement not processed") t.Fatal("remote announcement not processed")
} }
@ -560,7 +589,7 @@ func TestProcessAnnouncement(t *testing.T) {
select { select {
case msg := <-ctx.broadcastedMessage: case msg := <-ctx.broadcastedMessage:
assertSenderExistence(na.NodeID, msg) assertSenderExistence(nodePub, msg)
case <-time.After(2 * trickleDelay): case <-time.After(2 * trickleDelay):
t.Fatal("announcement wasn't proceeded") t.Fatal("announcement wasn't proceeded")
} }
@ -578,7 +607,7 @@ func TestProcessAnnouncement(t *testing.T) {
} }
select { select {
case err = <-ctx.gossiper.ProcessRemoteAnnouncement(ua, na.NodeID): case err = <-ctx.gossiper.ProcessRemoteAnnouncement(ua, nodePub):
case <-time.After(2 * time.Second): case <-time.After(2 * time.Second):
t.Fatal("remote announcement not processed") t.Fatal("remote announcement not processed")
} }
@ -588,7 +617,7 @@ func TestProcessAnnouncement(t *testing.T) {
select { select {
case msg := <-ctx.broadcastedMessage: case msg := <-ctx.broadcastedMessage:
assertSenderExistence(na.NodeID, msg) assertSenderExistence(nodePub, msg)
case <-time.After(2 * trickleDelay): case <-time.After(2 * trickleDelay):
t.Fatal("announcement wasn't proceeded") t.Fatal("announcement wasn't proceeded")
} }
@ -612,11 +641,13 @@ func TestPrematureAnnouncement(t *testing.T) {
} }
defer cleanup() defer cleanup()
na, err := createNodeAnnouncement(nodeKeyPriv1, timestamp) _, err = createNodeAnnouncement(nodeKeyPriv1, timestamp)
if err != nil { if err != nil {
t.Fatalf("can't create node announcement: %v", err) t.Fatalf("can't create node announcement: %v", err)
} }
nodePub := nodeKeyPriv1.PubKey()
// Pretending that we receive the valid channel announcement from // Pretending that we receive the valid channel announcement from
// remote side, but block height of this announcement is greater than // remote side, but block height of this announcement is greater than
// highest know to us, for that reason it should be added to the // highest know to us, for that reason it should be added to the
@ -627,7 +658,7 @@ func TestPrematureAnnouncement(t *testing.T) {
} }
select { select {
case <-ctx.gossiper.ProcessRemoteAnnouncement(ca, na.NodeID): case <-ctx.gossiper.ProcessRemoteAnnouncement(ca, nodePub):
t.Fatal("announcement was proceeded") t.Fatal("announcement was proceeded")
case <-time.After(100 * time.Millisecond): case <-time.After(100 * time.Millisecond):
} }
@ -646,7 +677,7 @@ func TestPrematureAnnouncement(t *testing.T) {
} }
select { select {
case <-ctx.gossiper.ProcessRemoteAnnouncement(ua, na.NodeID): case <-ctx.gossiper.ProcessRemoteAnnouncement(ua, nodePub):
t.Fatal("announcement was proceeded") t.Fatal("announcement was proceeded")
case <-time.After(100 * time.Millisecond): case <-time.After(100 * time.Millisecond):
} }
@ -709,8 +740,14 @@ func TestSignatureAnnouncementLocalFirst(t *testing.T) {
t.Fatalf("can't generate announcements: %v", err) t.Fatalf("can't generate announcements: %v", err)
} }
localKey := batch.nodeAnn1.NodeID localKey, err := btcec.ParsePubKey(batch.nodeAnn1.NodeID[:], btcec.S256())
remoteKey := batch.nodeAnn2.NodeID if err != nil {
t.Fatalf("unable to parse pubkey: %v", err)
}
remoteKey, err := btcec.ParsePubKey(batch.nodeAnn2.NodeID[:], btcec.S256())
if err != nil {
t.Fatalf("unable to parse pubkey: %v", err)
}
// Recreate lightning network topology. Initialize router with channel // Recreate lightning network topology. Initialize router with channel
// between two nodes. // between two nodes.
@ -865,8 +902,14 @@ func TestOrphanSignatureAnnouncement(t *testing.T) {
t.Fatalf("can't generate announcements: %v", err) t.Fatalf("can't generate announcements: %v", err)
} }
localKey := batch.nodeAnn1.NodeID localKey, err := btcec.ParsePubKey(batch.nodeAnn1.NodeID[:], btcec.S256())
remoteKey := batch.nodeAnn2.NodeID if err != nil {
t.Fatalf("unable to parse pubkey: %v", err)
}
remoteKey, err := btcec.ParsePubKey(batch.nodeAnn2.NodeID[:], btcec.S256())
if err != nil {
t.Fatalf("unable to parse pubkey: %v", err)
}
// Pretending that we receive local channel announcement from funding // Pretending that we receive local channel announcement from funding
// manager, thereby kick off the announcement exchange process, in // manager, thereby kick off the announcement exchange process, in
@ -1021,8 +1064,14 @@ func TestSignatureAnnouncementRetry(t *testing.T) {
t.Fatalf("can't generate announcements: %v", err) t.Fatalf("can't generate announcements: %v", err)
} }
localKey := batch.nodeAnn1.NodeID localKey, err := btcec.ParsePubKey(batch.nodeAnn1.NodeID[:], btcec.S256())
remoteKey := batch.nodeAnn2.NodeID if err != nil {
t.Fatalf("unable to parse pubkey: %v", err)
}
remoteKey, err := btcec.ParsePubKey(batch.nodeAnn2.NodeID[:], btcec.S256())
if err != nil {
t.Fatalf("unable to parse pubkey: %v", err)
}
// Recreate lightning network topology. Initialize router with channel // Recreate lightning network topology. Initialize router with channel
// between two nodes. // between two nodes.
@ -1203,8 +1252,14 @@ func TestSignatureAnnouncementRetryAtStartup(t *testing.T) {
t.Fatalf("can't generate announcements: %v", err) t.Fatalf("can't generate announcements: %v", err)
} }
localKey := batch.nodeAnn1.NodeID localKey, err := btcec.ParsePubKey(batch.nodeAnn1.NodeID[:], btcec.S256())
remoteKey := batch.nodeAnn2.NodeID if err != nil {
t.Fatalf("unable to parse pubkey: %v", err)
}
remoteKey, err := btcec.ParsePubKey(batch.nodeAnn2.NodeID[:], btcec.S256())
if err != nil {
t.Fatalf("unable to parse pubkey: %v", err)
}
// Recreate lightning network topology. Initialize router with channel // Recreate lightning network topology. Initialize router with channel
// between two nodes. // between two nodes.
@ -1422,8 +1477,14 @@ func TestSignatureAnnouncementFullProofWhenRemoteProof(t *testing.T) {
t.Fatalf("can't generate announcements: %v", err) t.Fatalf("can't generate announcements: %v", err)
} }
localKey := batch.nodeAnn1.NodeID localKey, err := btcec.ParsePubKey(batch.nodeAnn1.NodeID[:], btcec.S256())
remoteKey := batch.nodeAnn2.NodeID if err != nil {
t.Fatalf("unable to parse pubkey: %v", err)
}
remoteKey, err := btcec.ParsePubKey(batch.nodeAnn2.NodeID[:], btcec.S256())
if err != nil {
t.Fatalf("unable to parse pubkey: %v", err)
}
// Recreate lightning network topology. Initialize router with channel // Recreate lightning network topology. Initialize router with channel
// between two nodes. // between two nodes.
@ -1819,8 +1880,14 @@ func TestReceiveRemoteChannelUpdateFirst(t *testing.T) {
t.Fatalf("can't generate announcements: %v", err) t.Fatalf("can't generate announcements: %v", err)
} }
localKey := batch.nodeAnn1.NodeID localKey, err := btcec.ParsePubKey(batch.nodeAnn1.NodeID[:], btcec.S256())
remoteKey := batch.nodeAnn2.NodeID if err != nil {
t.Fatalf("unable to parse pubkey: %v", err)
}
remoteKey, err := btcec.ParsePubKey(batch.nodeAnn2.NodeID[:], btcec.S256())
if err != nil {
t.Fatalf("unable to parse pubkey: %v", err)
}
// Recreate the case where the remote node is sending us its ChannelUpdate // Recreate the case where the remote node is sending us its ChannelUpdate
// before we have been able to process our own ChannelAnnouncement and // before we have been able to process our own ChannelAnnouncement and

@ -16,24 +16,46 @@ import (
func createChanAnnouncement(chanProof *channeldb.ChannelAuthProof, func createChanAnnouncement(chanProof *channeldb.ChannelAuthProof,
chanInfo *channeldb.ChannelEdgeInfo, chanInfo *channeldb.ChannelEdgeInfo,
e1, e2 *channeldb.ChannelEdgePolicy) (*lnwire.ChannelAnnouncement, e1, e2 *channeldb.ChannelEdgePolicy) (*lnwire.ChannelAnnouncement,
*lnwire.ChannelUpdate, *lnwire.ChannelUpdate) { *lnwire.ChannelUpdate, *lnwire.ChannelUpdate, error) {
// First, using the parameters of the channel, along with the channel // First, using the parameters of the channel, along with the channel
// authentication chanProof, we'll create re-create the original // authentication chanProof, we'll create re-create the original
// authenticated channel announcement. // authenticated channel announcement.
chanID := lnwire.NewShortChanIDFromInt(chanInfo.ChannelID) chanID := lnwire.NewShortChanIDFromInt(chanInfo.ChannelID)
chanAnn := &lnwire.ChannelAnnouncement{ chanAnn := &lnwire.ChannelAnnouncement{
NodeSig1: chanProof.NodeSig1,
NodeSig2: chanProof.NodeSig2,
ShortChannelID: chanID, ShortChannelID: chanID,
BitcoinSig1: chanProof.BitcoinSig1, NodeID1: chanInfo.NodeKey1Bytes,
BitcoinSig2: chanProof.BitcoinSig2, NodeID2: chanInfo.NodeKey2Bytes,
NodeID1: chanInfo.NodeKey1,
NodeID2: chanInfo.NodeKey2,
ChainHash: chanInfo.ChainHash, ChainHash: chanInfo.ChainHash,
BitcoinKey1: chanInfo.BitcoinKey1, BitcoinKey1: chanInfo.BitcoinKey1Bytes,
BitcoinKey2: chanInfo.BitcoinKey2Bytes,
Features: lnwire.NewRawFeatureVector(), Features: lnwire.NewRawFeatureVector(),
BitcoinKey2: chanInfo.BitcoinKey2, }
var err error
chanAnn.BitcoinSig1, err = lnwire.NewSigFromRawSignature(
chanProof.BitcoinSig1Bytes,
)
if err != nil {
return nil, nil, nil, err
}
chanAnn.BitcoinSig2, err = lnwire.NewSigFromRawSignature(
chanProof.BitcoinSig2Bytes,
)
if err != nil {
return nil, nil, nil, err
}
chanAnn.NodeSig1, err = lnwire.NewSigFromRawSignature(
chanProof.NodeSig1Bytes,
)
if err != nil {
return nil, nil, nil, err
}
chanAnn.NodeSig2, err = lnwire.NewSigFromRawSignature(
chanProof.NodeSig2Bytes,
)
if err != nil {
return nil, nil, nil, err
} }
// We'll unconditionally queue the channel's existence chanProof as it // We'll unconditionally queue the channel's existence chanProof as it
@ -46,7 +68,6 @@ func createChanAnnouncement(chanProof *channeldb.ChannelAuthProof,
var edge1Ann, edge2Ann *lnwire.ChannelUpdate var edge1Ann, edge2Ann *lnwire.ChannelUpdate
if e1 != nil { if e1 != nil {
edge1Ann = &lnwire.ChannelUpdate{ edge1Ann = &lnwire.ChannelUpdate{
Signature: e1.Signature,
ChainHash: chanInfo.ChainHash, ChainHash: chanInfo.ChainHash,
ShortChannelID: chanID, ShortChannelID: chanID,
Timestamp: uint32(e1.LastUpdate.Unix()), Timestamp: uint32(e1.LastUpdate.Unix()),
@ -56,10 +77,13 @@ func createChanAnnouncement(chanProof *channeldb.ChannelAuthProof,
BaseFee: uint32(e1.FeeBaseMSat), BaseFee: uint32(e1.FeeBaseMSat),
FeeRate: uint32(e1.FeeProportionalMillionths), FeeRate: uint32(e1.FeeProportionalMillionths),
} }
edge1Ann.Signature, err = lnwire.NewSigFromRawSignature(e1.SigBytes)
if err != nil {
return nil, nil, nil, err
}
} }
if e2 != nil { if e2 != nil {
edge2Ann = &lnwire.ChannelUpdate{ edge2Ann = &lnwire.ChannelUpdate{
Signature: e2.Signature,
ChainHash: chanInfo.ChainHash, ChainHash: chanInfo.ChainHash,
ShortChannelID: chanID, ShortChannelID: chanID,
Timestamp: uint32(e2.LastUpdate.Unix()), Timestamp: uint32(e2.LastUpdate.Unix()),
@ -69,9 +93,13 @@ func createChanAnnouncement(chanProof *channeldb.ChannelAuthProof,
BaseFee: uint32(e2.FeeBaseMSat), BaseFee: uint32(e2.FeeBaseMSat),
FeeRate: uint32(e2.FeeProportionalMillionths), FeeRate: uint32(e2.FeeProportionalMillionths),
} }
edge2Ann.Signature, err = lnwire.NewSigFromRawSignature(e2.SigBytes)
if err != nil {
return nil, nil, nil, err
}
} }
return chanAnn, edge1Ann, edge2Ann return chanAnn, edge1Ann, edge2Ann, nil
} }
// copyPubKey performs a copy of the target public key, setting a fresh curve // copyPubKey performs a copy of the target public key, setting a fresh curve