Browse Source

netann/node_announcement: consolidate signing logic

master
Conner Fromknecht 4 years ago
parent
commit
f6c194c3cd
No known key found for this signature in database
GPG Key ID: E7D737B67FA592C7
  1. 8
      lnwire/node_announcement.go
  2. 60
      netann/node_announcement.go
  3. 33
      server.go

8
lnwire/node_announcement.go

@ -101,14 +101,6 @@ type NodeAnnouncement struct {
ExtraOpaqueData []byte
}
// UpdateNodeAnnAddrs is a functional option that allows updating the addresses
// of the given node announcement.
func UpdateNodeAnnAddrs(addrs []net.Addr) func(*NodeAnnouncement) {
return func(nodeAnn *NodeAnnouncement) {
nodeAnn.Addresses = addrs
}
}
// A compile time check to ensure NodeAnnouncement implements the
// lnwire.Message interface.
var _ Message = (*NodeAnnouncement)(nil)

60
netann/node_announcement.go

@ -0,0 +1,60 @@
package netann
import (
"net"
"time"
"github.com/btcsuite/btcd/btcec"
"github.com/lightningnetwork/lnd/lnwallet"
"github.com/lightningnetwork/lnd/lnwire"
)
// NodeAnnModifier is a closure that makes in-place modifications to an
// lnwire.NodeAnnouncement.
type NodeAnnModifier func(*lnwire.NodeAnnouncement)
// NodeAnnSetAddrs is a functional option that allows updating the addresses of
// the given node announcement.
func NodeAnnSetAddrs(addrs []net.Addr) func(*lnwire.NodeAnnouncement) {
return func(nodeAnn *lnwire.NodeAnnouncement) {
nodeAnn.Addresses = addrs
}
}
// NodeAnnSetTimestamp is a functional option that sets the timestamp of the
// announcement to the current time, or increments it if the timestamp is
// already in the future.
func NodeAnnSetTimestamp(nodeAnn *lnwire.NodeAnnouncement) {
newTimestamp := uint32(time.Now().Unix())
if newTimestamp <= nodeAnn.Timestamp {
// Increment the prior value to ensure the timestamp
// monotonically increases, otherwise the announcement won't
// propagate.
newTimestamp = nodeAnn.Timestamp + 1
}
nodeAnn.Timestamp = newTimestamp
}
// SignNodeAnnouncement applies the given modifies to the passed
// lnwire.NodeAnnouncement, then signs the resulting announcement. The provided
// update should be the most recent, valid update, otherwise the timestamp may
// not monotonically increase from the prior.
func SignNodeAnnouncement(signer lnwallet.MessageSigner,
pubKey *btcec.PublicKey, nodeAnn *lnwire.NodeAnnouncement,
mods ...NodeAnnModifier) error {
// Apply the requested changes to the node announcement.
for _, modifier := range mods {
modifier(nodeAnn)
}
// Create the DER-encoded ECDSA signature over the message digest.
sig, err := SignAnnouncement(signer, pubKey, nodeAnn)
if err != nil {
return err
}
// Parse the DER-encoded signature into a fixed-size 64-byte array.
nodeAnn.Signature, err = lnwire.NewSigFromSignature(sig)
return err
}

33
server.go

@ -1657,7 +1657,7 @@ out:
// announcement with the updated addresses and broadcast
// it to our peers.
newNodeAnn, err := s.genNodeAnnouncement(
true, lnwire.UpdateNodeAnnAddrs(newAddrs),
true, netann.NodeAnnSetAddrs(newAddrs),
)
if err != nil {
srvrLog.Debugf("Unable to generate new node "+
@ -2039,7 +2039,7 @@ func (s *server) initTorController() error {
// announcement. If refresh is true, then the time stamp of the announcement
// will be updated in order to ensure it propagates through the network.
func (s *server) genNodeAnnouncement(refresh bool,
updates ...func(*lnwire.NodeAnnouncement)) (lnwire.NodeAnnouncement, error) {
modifiers ...netann.NodeAnnModifier) (lnwire.NodeAnnouncement, error) {
s.mu.Lock()
defer s.mu.Unlock()
@ -2050,34 +2050,19 @@ func (s *server) genNodeAnnouncement(refresh bool,
return *s.currentNodeAnn, nil
}
// Now that we know we need to update our copy, we'll apply all the
// function updates that'll mutate the current version of our node
// announcement.
for _, update := range updates {
update(s.currentNodeAnn)
}
// We'll now update the timestamp, ensuring that with each update, the
// timestamp monotonically increases.
newStamp := uint32(time.Now().Unix())
if newStamp <= s.currentNodeAnn.Timestamp {
newStamp = s.currentNodeAnn.Timestamp + 1
}
s.currentNodeAnn.Timestamp = newStamp
// Always update the timestamp when refreshing to ensure the update
// propagates.
modifiers = append(modifiers, netann.NodeAnnSetTimestamp)
// Now that the announcement is fully updated, we'll generate a new
// signature over the announcement to ensure nodes on the network
// accepted the new authenticated announcement.
sig, err := netann.SignAnnouncement(
// Otherwise, we'll sign a new update after applying all of the passed
// modifiers.
err := netann.SignNodeAnnouncement(
s.nodeSigner, s.identityPriv.PubKey(), s.currentNodeAnn,
modifiers...,
)
if err != nil {
return lnwire.NodeAnnouncement{}, err
}
s.currentNodeAnn.Signature, err = lnwire.NewSigFromSignature(sig)
if err != nil {
return lnwire.NodeAnnouncement{}, err
}
return *s.currentNodeAnn, nil
}

Loading…
Cancel
Save