From cd9d2d7e6fada29b00b2ade6094a6fa704442dc4 Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Tue, 30 Jan 2018 20:23:14 -0800 Subject: [PATCH] discovery: update graph API usage to match recent API changes --- discovery/ann_validation.go | 61 ++++++++++-- discovery/gossiper.go | 187 +++++++++++++++++++++++------------- discovery/gossiper_test.go | 141 ++++++++++++++++++++------- discovery/utils.go | 52 +++++++--- 4 files changed, 319 insertions(+), 122 deletions(-) diff --git a/discovery/ann_validation.go b/discovery/ann_validation.go index 058bf7c18..e93559bf2 100644 --- a/discovery/ann_validation.go +++ b/discovery/ann_validation.go @@ -26,23 +26,56 @@ func ValidateChannelAnn(a *lnwire.ChannelAnnouncement) error { // First we'll verify that the passed bitcoin key signature is indeed a // 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") } // If that checks out, then we'll verify that the second bitcoin // signature is a valid signature of the bitcoin public key over hash // 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") } // Both node signatures attached should indeed be a valid 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") } - 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") } @@ -61,17 +94,26 @@ func ValidateNodeAnn(a *lnwire.NodeAnnouncement) error { 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 // return an error so this node announcement can be rejected. dataHash := chainhash.DoubleHashB(data) - if !a.Signature.Verify(dataHash, copyPubKey(a.NodeID)) { + if !nodeSig.Verify(dataHash, nodeKey) { var msgBuf bytes.Buffer if _, err := lnwire.WriteMessage(&msgBuf, a, 0); err != nil { return err } return errors.Errorf("signature on NodeAnnouncement(%x) is "+ - "invalid: %x", a.NodeID.SerializeCompressed(), + "invalid: %x", nodeKey.SerializeCompressed(), msgBuf.Bytes()) } @@ -90,7 +132,12 @@ func ValidateChannelUpdateAnn(pubKey *btcec.PublicKey, } 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 "+ "update %v", spew.Sdump(a)) } diff --git a/discovery/gossiper.go b/discovery/gossiper.go index e49907d72..5d722caf2 100644 --- a/discovery/gossiper.go +++ b/discovery/gossiper.go @@ -157,17 +157,17 @@ type AuthenticatedGossiper struct { // TODO(roasbeef): limit premature networkMsgs to N prematureAnnouncements map[uint32][]*networkMsg - // prematureChannelUpdates is a map of ChannelUpdates we have - // received that wasn't associated with any channel we know about. - // We store them temporarily, such that we can reprocess them when - // a ChannelAnnouncement for the channel is received. + // prematureChannelUpdates is a map of ChannelUpdates we have received + // that wasn't associated with any channel we know about. We store + // them temporarily, such that we can reprocess them when a + // ChannelAnnouncement for the channel is received. prematureChannelUpdates map[uint64][]*networkMsg pChanUpdMtx sync.Mutex // waitingProofs is a persistent storage of partial channel proof // announcement messages. We use it to buffer half of the material - // needed to reconstruct a full authenticated channel announcement. Once - // we receive the other half the channel proof, we'll be able to + // needed to reconstruct a full authenticated channel announcement. + // 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. waitingProofs *channeldb.WaitingProofStore @@ -176,8 +176,8 @@ type AuthenticatedGossiper struct { // networkHandler. networkMsgs chan *networkMsg - // chanPolicyUpdates is a channel that requests to update the forwarding - // policy of a set of channels is sent over. + // chanPolicyUpdates is a channel that requests to update the + // forwarding policy of a set of channels is sent over. chanPolicyUpdates chan *chanPolicyUpdateRequest // 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. var announceMessages []lnwire.Message - makeNodeAnn := func(n *channeldb.LightningNode) *lnwire.NodeAnnouncement { + makeNodeAnn := func(n *channeldb.LightningNode) (*lnwire.NodeAnnouncement, error) { alias, _ := lnwire.NewNodeAlias(n.Alias) + + wireSig, err := lnwire.NewSigFromRawSignature(n.AuthSigBytes) + if err != nil { + return nil, err + } return &lnwire.NodeAnnouncement{ - Signature: n.AuthSig, + Signature: wireSig, Timestamp: uint32(n.LastUpdate.Unix()), Addresses: n.Addresses, - NodeID: n.PubKey, + NodeID: n.PubKeyBytes, Features: n.Features.RawFeatureVector, RGBColor: n.Color, Alias: alias, - } + }, nil } // 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 // well. if chanInfo.AuthProof != nil { - chanAnn, e1Ann, e2Ann := createChanAnnouncement( - chanInfo.AuthProof, chanInfo, e1, e2) + chanAnn, e1Ann, e2Ann, err := createChanAnnouncement( + chanInfo.AuthProof, chanInfo, e1, e2, + ) + if err != nil { + return err + } announceMessages = append(announceMessages, chanAnn) if e1Ann != nil { @@ -272,7 +281,10 @@ func (d *AuthenticatedGossiper) SynchronizeNode(pub *btcec.PublicKey) error { // If this edge has a validated node // announcement, then we'll send that as well. if e1.Node.HaveNodeAnnouncement { - nodeAnn := makeNodeAnn(e1.Node) + nodeAnn, err := makeNodeAnn(e1.Node) + if err != nil { + return err + } announceMessages = append( announceMessages, nodeAnn, ) @@ -285,7 +297,10 @@ func (d *AuthenticatedGossiper) SynchronizeNode(pub *btcec.PublicKey) error { // If this edge has a validated node // announcement, then we'll send that as well. if e2.Node.HaveNodeAnnouncement { - nodeAnn := makeNodeAnn(e2.Node) + nodeAnn, err := makeNodeAnn(e2.Node) + if err != nil { + return err + } announceMessages = append( announceMessages, nodeAnn, ) @@ -588,7 +603,7 @@ func (d *deDupedAnnouncements) addMsg(message networkMsg) { // NodeID to create the corresponding Vertex. case *lnwire.NodeAnnouncement: 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 // 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 // announcement. - chanAnn, e1Ann, e2Ann := createChanAnnouncement( + chanAnn, e1Ann, e2Ann, err := createChanAnnouncement( proof, chanInfo, e1, e2, ) + if err != nil { + return nil, err + } err = ValidateChannelAnn(chanAnn) if err != nil { err := errors.Errorf("assembled channel announcement proof "+ @@ -1265,9 +1283,9 @@ func (d *AuthenticatedGossiper) processNetworkAnnouncement(nMsg *networkMsg) []n HaveNodeAnnouncement: true, LastUpdate: time.Unix(int64(msg.Timestamp), 0), Addresses: msg.Addresses, - PubKey: msg.NodeID, + PubKeyBytes: msg.NodeID, Alias: msg.Alias.String(), - AuthSig: msg.Signature, + AuthSigBytes: msg.Signature.ToSignatureBytes(), Features: features, 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 // gossiping with other nodes. proof = &channeldb.ChannelAuthProof{ - NodeSig1: msg.NodeSig1, - NodeSig2: msg.NodeSig2, - BitcoinSig1: msg.BitcoinSig1, - BitcoinSig2: msg.BitcoinSig2, + NodeSig1Bytes: msg.NodeSig1.ToSignatureBytes(), + NodeSig2Bytes: msg.NodeSig2.ToSignatureBytes(), + BitcoinSig1Bytes: msg.BitcoinSig1.ToSignatureBytes(), + BitcoinSig2Bytes: msg.BitcoinSig2.ToSignatureBytes(), } } @@ -1365,14 +1383,14 @@ func (d *AuthenticatedGossiper) processNetworkAnnouncement(nMsg *networkMsg) []n } edge := &channeldb.ChannelEdgeInfo{ - ChannelID: msg.ShortChannelID.ToUint64(), - ChainHash: msg.ChainHash, - NodeKey1: msg.NodeID1, - NodeKey2: msg.NodeID2, - BitcoinKey1: msg.BitcoinKey1, - BitcoinKey2: msg.BitcoinKey2, - AuthProof: proof, - Features: featureBuf.Bytes(), + ChannelID: msg.ShortChannelID.ToUint64(), + ChainHash: msg.ChainHash, + NodeKey1Bytes: msg.NodeID1, + NodeKey2Bytes: msg.NodeID2, + BitcoinKey1Bytes: msg.BitcoinKey1, + BitcoinKey2Bytes: msg.BitcoinKey2, + AuthProof: proof, + Features: featureBuf.Bytes(), } // We will add the edge to the channel router. If the nodes @@ -1560,7 +1578,7 @@ func (d *AuthenticatedGossiper) processNetworkAnnouncement(nMsg *networkMsg) []n d.prematureChannelUpdates[shortChanID], nMsg) d.pChanUpdMtx.Unlock() - log.Infof("Got ChannelUpdate for edge not "+ + log.Debugf("Got ChannelUpdate for edge not "+ "found in graph(shortChanID=%v), "+ "saving for reprocessing later", shortChanID) @@ -1582,9 +1600,9 @@ func (d *AuthenticatedGossiper) processNetworkAnnouncement(nMsg *networkMsg) []n var pubKey *btcec.PublicKey switch { case msg.Flags&lnwire.ChanUpdateDirection == 0: - pubKey = chanInfo.NodeKey1 + pubKey, _ = chanInfo.NodeKey1() case msg.Flags&lnwire.ChanUpdateDirection == 1: - pubKey = chanInfo.NodeKey2 + pubKey, _ = chanInfo.NodeKey2() } // Validate the channel announcement with the expected public @@ -1601,7 +1619,7 @@ func (d *AuthenticatedGossiper) processNetworkAnnouncement(nMsg *networkMsg) []n } update := &channeldb.ChannelEdgePolicy{ - Signature: msg.Signature, + SigBytes: msg.Signature.ToSignatureBytes(), ChannelID: shortChanID, LastUpdate: time.Unix(int64(msg.Timestamp), 0), Flags: msg.Flags, @@ -1632,9 +1650,9 @@ func (d *AuthenticatedGossiper) processNetworkAnnouncement(nMsg *networkMsg) []n var remotePeer *btcec.PublicKey switch { case msg.Flags&lnwire.ChanUpdateDirection == 0: - remotePeer = chanInfo.NodeKey2 + remotePeer, _ = chanInfo.NodeKey2() case msg.Flags&lnwire.ChanUpdateDirection == 1: - remotePeer = chanInfo.NodeKey1 + remotePeer, _ = chanInfo.NodeKey1() } // Send ChannelUpdate directly to remotePeer. @@ -1726,9 +1744,9 @@ func (d *AuthenticatedGossiper) processNetworkAnnouncement(nMsg *networkMsg) []n } isFirstNode := bytes.Equal(nMsg.peer.SerializeCompressed(), - chanInfo.NodeKey1.SerializeCompressed()) + chanInfo.NodeKey1Bytes[:]) isSecondNode := bytes.Equal(nMsg.peer.SerializeCompressed(), - chanInfo.NodeKey2.SerializeCompressed()) + chanInfo.NodeKey2Bytes[:]) // Ensure that channel that was retrieved belongs to the peer // which sent the proof announcement. @@ -1748,9 +1766,9 @@ func (d *AuthenticatedGossiper) processNetworkAnnouncement(nMsg *networkMsg) []n if !nMsg.isRemote { var remotePeer *btcec.PublicKey if isFirstNode { - remotePeer = chanInfo.NodeKey2 + remotePeer, _ = chanInfo.NodeKey2() } else { - remotePeer = chanInfo.NodeKey1 + remotePeer, _ = chanInfo.NodeKey1() } // Since the remote peer might not be online // we'll call a method that will attempt to @@ -1786,9 +1804,14 @@ func (d *AuthenticatedGossiper) processNetworkAnnouncement(nMsg *networkMsg) []n msg.ChannelID, peerID) - chanAnn, _, _ := createChanAnnouncement( - chanInfo.AuthProof, chanInfo, e1, e2) - err := d.cfg.SendToPeer(nMsg.peer, chanAnn) + chanAnn, _, _, err := createChanAnnouncement( + chanInfo.AuthProof, chanInfo, e1, e2, + ) + if err != nil { + log.Error("unable to gen ann: %v", err) + return + } + err = d.cfg.SendToPeer(nMsg.peer, chanAnn) if err != nil { log.Errorf("Failed sending "+ "full proof to "+ @@ -1846,17 +1869,22 @@ func (d *AuthenticatedGossiper) processNetworkAnnouncement(nMsg *networkMsg) []n // validate it shortly below. var dbProof channeldb.ChannelAuthProof if isFirstNode { - dbProof.NodeSig1 = msg.NodeSignature - dbProof.NodeSig2 = oppositeProof.NodeSignature - dbProof.BitcoinSig1 = msg.BitcoinSignature - dbProof.BitcoinSig2 = oppositeProof.BitcoinSignature + dbProof.NodeSig1Bytes = msg.NodeSignature.ToSignatureBytes() + dbProof.NodeSig2Bytes = oppositeProof.NodeSignature.ToSignatureBytes() + dbProof.BitcoinSig1Bytes = msg.BitcoinSignature.ToSignatureBytes() + dbProof.BitcoinSig2Bytes = oppositeProof.BitcoinSignature.ToSignatureBytes() } else { - dbProof.NodeSig1 = oppositeProof.NodeSignature - dbProof.NodeSig2 = msg.NodeSignature - dbProof.BitcoinSig1 = oppositeProof.BitcoinSignature - dbProof.BitcoinSig2 = msg.BitcoinSignature + dbProof.NodeSig1Bytes = oppositeProof.NodeSignature.ToSignatureBytes() + dbProof.NodeSig2Bytes = msg.NodeSignature.ToSignatureBytes() + dbProof.BitcoinSig1Bytes = oppositeProof.BitcoinSignature.ToSignatureBytes() + 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 // full channel announcement proof. @@ -2017,6 +2045,8 @@ func (d *AuthenticatedGossiper) sendAnnSigReliably( func (d *AuthenticatedGossiper) updateChannel(info *channeldb.ChannelEdgeInfo, edge *channeldb.ChannelEdgePolicy) (*lnwire.ChannelAnnouncement, *lnwire.ChannelUpdate, error) { + var err error + // Make sure timestamp is always increased, such that our update // gets propagated. timestamp := time.Now().Unix() @@ -2025,7 +2055,6 @@ func (d *AuthenticatedGossiper) updateChannel(info *channeldb.ChannelEdgeInfo, } edge.LastUpdate = time.Unix(timestamp, 0) chanUpdate := &lnwire.ChannelUpdate{ - Signature: edge.Signature, ChainHash: info.ChainHash, ShortChannelID: lnwire.NewShortChanIDFromInt(edge.ChannelID), Timestamp: uint32(timestamp), @@ -2035,6 +2064,10 @@ func (d *AuthenticatedGossiper) updateChannel(info *channeldb.ChannelEdgeInfo, BaseFee: uint32(edge.FeeBaseMSat), 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 // 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 // in the backing slice. - edge.Signature = sig - chanUpdate.Signature = sig + edge.SigBytes = sig.Serialize() + 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 // 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. - edge.Node.PubKey.Curve = nil if err := d.cfg.Router.UpdateEdge(edge); err != nil { return nil, nil, err } @@ -2069,17 +2104,37 @@ func (d *AuthenticatedGossiper) updateChannel(info *channeldb.ChannelEdgeInfo, if info.AuthProof != nil { chanID := lnwire.NewShortChanIDFromInt(info.ChannelID) chanAnn = &lnwire.ChannelAnnouncement{ - NodeSig1: info.AuthProof.NodeSig1, - NodeSig2: info.AuthProof.NodeSig2, ShortChannelID: chanID, - BitcoinSig1: info.AuthProof.BitcoinSig1, - BitcoinSig2: info.AuthProof.BitcoinSig2, - NodeID1: info.NodeKey1, - NodeID2: info.NodeKey2, + NodeID1: info.NodeKey1Bytes, + NodeID2: info.NodeKey2Bytes, ChainHash: info.ChainHash, - BitcoinKey1: info.BitcoinKey1, + BitcoinKey1: info.BitcoinKey1Bytes, 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 } } diff --git a/discovery/gossiper_test.go b/discovery/gossiper_test.go index 6bfe9867d..4a8502d42 100644 --- a/discovery/gossiper_test.go +++ b/discovery/gossiper_test.go @@ -305,10 +305,6 @@ func createAnnouncements(blockHeight uint32) (*annBatch, error) { if err != nil { return nil, err } - batch.localChanAnn.BitcoinSig1 = nil - batch.localChanAnn.BitcoinSig2 = nil - batch.localChanAnn.NodeSig1 = nil - batch.localChanAnn.NodeSig2 = nil batch.chanUpdAnn1, err = createUpdateAnnouncement( blockHeight, 0, nodeKeyPriv1, timestamp, @@ -342,13 +338,18 @@ func createNodeAnnouncement(priv *btcec.PrivateKey, a := &lnwire.NodeAnnouncement{ Timestamp: timestamp, Addresses: testAddrs, - NodeID: priv.PubKey(), Alias: alias, Features: testFeatures, } + copy(a.NodeID[:], priv.PubKey().SerializeCompressed()) 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 { return nil, err } @@ -376,7 +377,13 @@ func createUpdateAnnouncement(blockHeight uint32, flags lnwire.ChanUpdateFlag, pub := nodeKey.PubKey() 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 } @@ -392,34 +399,54 @@ func createRemoteChannelAnnouncement(blockHeight uint32) (*lnwire.ChannelAnnounc TxIndex: 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() 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 } pub = nodeKeyPriv2.PubKey() 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 } pub = bitcoinKeyPriv1.PubKey() 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 } pub = bitcoinKeyPriv2.PubKey() 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 } @@ -521,8 +548,10 @@ func TestProcessAnnouncement(t *testing.T) { t.Fatalf("can't create node announcement: %v", err) } + nodePub := nodeKeyPriv1.PubKey() + select { - case err = <-ctx.gossiper.ProcessRemoteAnnouncement(na, na.NodeID): + case err = <-ctx.gossiper.ProcessRemoteAnnouncement(na, nodePub): case <-time.After(2 * time.Second): t.Fatal("remote announcement not processed") } @@ -532,7 +561,7 @@ func TestProcessAnnouncement(t *testing.T) { select { case msg := <-ctx.broadcastedMessage: - assertSenderExistence(na.NodeID, msg) + assertSenderExistence(nodePub, msg) case <-time.After(2 * trickleDelay): t.Fatal("announcement wasn't proceeded") } @@ -550,7 +579,7 @@ func TestProcessAnnouncement(t *testing.T) { } select { - case err = <-ctx.gossiper.ProcessRemoteAnnouncement(ca, na.NodeID): + case err = <-ctx.gossiper.ProcessRemoteAnnouncement(ca, nodePub): case <-time.After(2 * time.Second): t.Fatal("remote announcement not processed") } @@ -560,7 +589,7 @@ func TestProcessAnnouncement(t *testing.T) { select { case msg := <-ctx.broadcastedMessage: - assertSenderExistence(na.NodeID, msg) + assertSenderExistence(nodePub, msg) case <-time.After(2 * trickleDelay): t.Fatal("announcement wasn't proceeded") } @@ -578,7 +607,7 @@ func TestProcessAnnouncement(t *testing.T) { } select { - case err = <-ctx.gossiper.ProcessRemoteAnnouncement(ua, na.NodeID): + case err = <-ctx.gossiper.ProcessRemoteAnnouncement(ua, nodePub): case <-time.After(2 * time.Second): t.Fatal("remote announcement not processed") } @@ -588,7 +617,7 @@ func TestProcessAnnouncement(t *testing.T) { select { case msg := <-ctx.broadcastedMessage: - assertSenderExistence(na.NodeID, msg) + assertSenderExistence(nodePub, msg) case <-time.After(2 * trickleDelay): t.Fatal("announcement wasn't proceeded") } @@ -612,11 +641,13 @@ func TestPrematureAnnouncement(t *testing.T) { } defer cleanup() - na, err := createNodeAnnouncement(nodeKeyPriv1, timestamp) + _, err = createNodeAnnouncement(nodeKeyPriv1, timestamp) if err != nil { t.Fatalf("can't create node announcement: %v", err) } + nodePub := nodeKeyPriv1.PubKey() + // Pretending that we receive the valid channel announcement from // remote side, but block height of this announcement is greater than // highest know to us, for that reason it should be added to the @@ -627,7 +658,7 @@ func TestPrematureAnnouncement(t *testing.T) { } select { - case <-ctx.gossiper.ProcessRemoteAnnouncement(ca, na.NodeID): + case <-ctx.gossiper.ProcessRemoteAnnouncement(ca, nodePub): t.Fatal("announcement was proceeded") case <-time.After(100 * time.Millisecond): } @@ -646,7 +677,7 @@ func TestPrematureAnnouncement(t *testing.T) { } select { - case <-ctx.gossiper.ProcessRemoteAnnouncement(ua, na.NodeID): + case <-ctx.gossiper.ProcessRemoteAnnouncement(ua, nodePub): t.Fatal("announcement was proceeded") case <-time.After(100 * time.Millisecond): } @@ -709,8 +740,14 @@ func TestSignatureAnnouncementLocalFirst(t *testing.T) { t.Fatalf("can't generate announcements: %v", err) } - localKey := batch.nodeAnn1.NodeID - remoteKey := batch.nodeAnn2.NodeID + localKey, err := btcec.ParsePubKey(batch.nodeAnn1.NodeID[:], btcec.S256()) + 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 // between two nodes. @@ -865,8 +902,14 @@ func TestOrphanSignatureAnnouncement(t *testing.T) { t.Fatalf("can't generate announcements: %v", err) } - localKey := batch.nodeAnn1.NodeID - remoteKey := batch.nodeAnn2.NodeID + localKey, err := btcec.ParsePubKey(batch.nodeAnn1.NodeID[:], btcec.S256()) + 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 // 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) } - localKey := batch.nodeAnn1.NodeID - remoteKey := batch.nodeAnn2.NodeID + localKey, err := btcec.ParsePubKey(batch.nodeAnn1.NodeID[:], btcec.S256()) + 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 // between two nodes. @@ -1203,8 +1252,14 @@ func TestSignatureAnnouncementRetryAtStartup(t *testing.T) { t.Fatalf("can't generate announcements: %v", err) } - localKey := batch.nodeAnn1.NodeID - remoteKey := batch.nodeAnn2.NodeID + localKey, err := btcec.ParsePubKey(batch.nodeAnn1.NodeID[:], btcec.S256()) + 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 // between two nodes. @@ -1422,8 +1477,14 @@ func TestSignatureAnnouncementFullProofWhenRemoteProof(t *testing.T) { t.Fatalf("can't generate announcements: %v", err) } - localKey := batch.nodeAnn1.NodeID - remoteKey := batch.nodeAnn2.NodeID + localKey, err := btcec.ParsePubKey(batch.nodeAnn1.NodeID[:], btcec.S256()) + 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 // between two nodes. @@ -1819,8 +1880,14 @@ func TestReceiveRemoteChannelUpdateFirst(t *testing.T) { t.Fatalf("can't generate announcements: %v", err) } - localKey := batch.nodeAnn1.NodeID - remoteKey := batch.nodeAnn2.NodeID + localKey, err := btcec.ParsePubKey(batch.nodeAnn1.NodeID[:], btcec.S256()) + 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 // before we have been able to process our own ChannelAnnouncement and diff --git a/discovery/utils.go b/discovery/utils.go index 3b52403b1..c9f85a8e7 100644 --- a/discovery/utils.go +++ b/discovery/utils.go @@ -16,24 +16,46 @@ import ( func createChanAnnouncement(chanProof *channeldb.ChannelAuthProof, chanInfo *channeldb.ChannelEdgeInfo, 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 // authentication chanProof, we'll create re-create the original // authenticated channel announcement. chanID := lnwire.NewShortChanIDFromInt(chanInfo.ChannelID) chanAnn := &lnwire.ChannelAnnouncement{ - NodeSig1: chanProof.NodeSig1, - NodeSig2: chanProof.NodeSig2, ShortChannelID: chanID, - BitcoinSig1: chanProof.BitcoinSig1, - BitcoinSig2: chanProof.BitcoinSig2, - NodeID1: chanInfo.NodeKey1, - NodeID2: chanInfo.NodeKey2, + NodeID1: chanInfo.NodeKey1Bytes, + NodeID2: chanInfo.NodeKey2Bytes, ChainHash: chanInfo.ChainHash, - BitcoinKey1: chanInfo.BitcoinKey1, + BitcoinKey1: chanInfo.BitcoinKey1Bytes, + BitcoinKey2: chanInfo.BitcoinKey2Bytes, 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 @@ -46,7 +68,6 @@ func createChanAnnouncement(chanProof *channeldb.ChannelAuthProof, var edge1Ann, edge2Ann *lnwire.ChannelUpdate if e1 != nil { edge1Ann = &lnwire.ChannelUpdate{ - Signature: e1.Signature, ChainHash: chanInfo.ChainHash, ShortChannelID: chanID, Timestamp: uint32(e1.LastUpdate.Unix()), @@ -56,10 +77,13 @@ func createChanAnnouncement(chanProof *channeldb.ChannelAuthProof, BaseFee: uint32(e1.FeeBaseMSat), FeeRate: uint32(e1.FeeProportionalMillionths), } + edge1Ann.Signature, err = lnwire.NewSigFromRawSignature(e1.SigBytes) + if err != nil { + return nil, nil, nil, err + } } if e2 != nil { edge2Ann = &lnwire.ChannelUpdate{ - Signature: e2.Signature, ChainHash: chanInfo.ChainHash, ShortChannelID: chanID, Timestamp: uint32(e2.LastUpdate.Unix()), @@ -69,9 +93,13 @@ func createChanAnnouncement(chanProof *channeldb.ChannelAuthProof, BaseFee: uint32(e2.FeeBaseMSat), 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