multi: add new method to generate fresh node announcments
This commit is contained in:
parent
6307f7243e
commit
43b736225b
@ -75,7 +75,7 @@ type Config struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new AuthenticatedGossiper instance, initialized with the
|
// New creates a new AuthenticatedGossiper instance, initialized with the
|
||||||
// passed configuration paramters.
|
// passed configuration parameters.
|
||||||
func New(cfg Config) (*AuthenticatedGossiper, error) {
|
func New(cfg Config) (*AuthenticatedGossiper, error) {
|
||||||
storage, err := channeldb.NewWaitingProofStore(cfg.DB)
|
storage, err := channeldb.NewWaitingProofStore(cfg.DB)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -439,9 +439,9 @@ func (d *AuthenticatedGossiper) processNetworkAnnouncement(nMsg *networkMsg) []l
|
|||||||
|
|
||||||
switch msg := nMsg.msg.(type) {
|
switch msg := nMsg.msg.(type) {
|
||||||
|
|
||||||
// A new node announcement has arrived which either presents new information
|
// A new node announcement has arrived which either presents new
|
||||||
// about a node in one of the channels we know about, or a updating
|
// information about a node in one of the channels we know about, or a
|
||||||
// previously advertised information.
|
// updating previously advertised information.
|
||||||
case *lnwire.NodeAnnouncement:
|
case *lnwire.NodeAnnouncement:
|
||||||
if nMsg.isRemote {
|
if nMsg.isRemote {
|
||||||
if err := d.validateNodeAnn(msg); err != nil {
|
if err := d.validateNodeAnn(msg); err != nil {
|
||||||
@ -464,7 +464,9 @@ func (d *AuthenticatedGossiper) processNetworkAnnouncement(nMsg *networkMsg) []l
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err := d.cfg.Router.AddNode(node); err != nil {
|
if err := d.cfg.Router.AddNode(node); err != nil {
|
||||||
if routing.IsError(err, routing.ErrOutdated, routing.ErrIgnored) {
|
if routing.IsError(err, routing.ErrOutdated,
|
||||||
|
routing.ErrIgnored) {
|
||||||
|
|
||||||
log.Debug(err)
|
log.Debug(err)
|
||||||
} else {
|
} else {
|
||||||
log.Error(err)
|
log.Error(err)
|
||||||
@ -504,8 +506,8 @@ func (d *AuthenticatedGossiper) processNetworkAnnouncement(nMsg *networkMsg) []l
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this is a remote channel annoucement, then we'll validate
|
// If this is a remote channel announcement, then we'll validate
|
||||||
// all the signatues within the proof as it should be well
|
// all the signatures within the proof as it should be well
|
||||||
// formed.
|
// formed.
|
||||||
var proof *channeldb.ChannelAuthProof
|
var proof *channeldb.ChannelAuthProof
|
||||||
if nMsg.isRemote {
|
if nMsg.isRemote {
|
||||||
|
@ -161,9 +161,9 @@ type fundingConfig struct {
|
|||||||
// distinct sub-system?
|
// distinct sub-system?
|
||||||
SignMessage func(pubKey *btcec.PublicKey, msg []byte) (*btcec.Signature, error)
|
SignMessage func(pubKey *btcec.PublicKey, msg []byte) (*btcec.Signature, error)
|
||||||
|
|
||||||
// SignNodeAnnouncement is used by the fundingManager to sign the
|
// CurrentNodeAnnouncement should return the latest, fully signed node
|
||||||
// updated self node announcements sent after each channel announcement.
|
// announcement from the backing Lighting Network node.
|
||||||
SignNodeAnnouncement func(nodeAnn *lnwire.NodeAnnouncement) (*btcec.Signature, error)
|
CurrentNodeAnnouncement func() (*lnwire.NodeAnnouncement, error)
|
||||||
|
|
||||||
// SendAnnouncement is used by the FundingManager to announce newly
|
// SendAnnouncement is used by the FundingManager to announce newly
|
||||||
// created channels to the rest of the Lightning Network.
|
// created channels to the rest of the Lightning Network.
|
||||||
@ -1359,58 +1359,36 @@ func (f *fundingManager) newChanAnnouncement(localPubKey, remotePubKey *btcec.Pu
|
|||||||
func (f *fundingManager) announceChannel(localIDKey, remoteIDKey, localFundingKey,
|
func (f *fundingManager) announceChannel(localIDKey, remoteIDKey, localFundingKey,
|
||||||
remoteFundingKey *btcec.PublicKey, shortChanID lnwire.ShortChannelID,
|
remoteFundingKey *btcec.PublicKey, shortChanID lnwire.ShortChannelID,
|
||||||
chanID lnwire.ChannelID) {
|
chanID lnwire.ChannelID) {
|
||||||
ann, err := f.newChanAnnouncement(localIDKey, remoteIDKey, localFundingKey,
|
|
||||||
remoteFundingKey, shortChanID, chanID)
|
// First, we'll create the batch of announcements to be sent upon
|
||||||
|
// initial channel creation. This includes the channel announcement
|
||||||
|
// itself, the channel update announcement, and our half of the channel
|
||||||
|
// proof needed to fully authenticate the channel.
|
||||||
|
ann, err := f.newChanAnnouncement(localIDKey, remoteIDKey,
|
||||||
|
localFundingKey, remoteFundingKey, shortChanID, chanID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fndgLog.Errorf("can't generate channel announcement: %v", err)
|
fndgLog.Errorf("can't generate channel announcement: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// With the announcements crafted, we'll now send the announcements to
|
||||||
|
// the rest of the network.
|
||||||
|
//
|
||||||
// TODO(roasbeef): add flag that indicates if should be announced or
|
// TODO(roasbeef): add flag that indicates if should be announced or
|
||||||
// not
|
// not
|
||||||
|
|
||||||
f.cfg.SendAnnouncement(ann.chanAnn)
|
f.cfg.SendAnnouncement(ann.chanAnn)
|
||||||
f.cfg.SendAnnouncement(ann.chanUpdateAnn)
|
f.cfg.SendAnnouncement(ann.chanUpdateAnn)
|
||||||
f.cfg.SendAnnouncement(ann.chanProof)
|
f.cfg.SendAnnouncement(ann.chanProof)
|
||||||
|
|
||||||
// Now that the channel is announced to the network, we will also create
|
// Now that the channel is announced to the network, we will also
|
||||||
// and send a node announcement. This is done since a node announcement
|
// obtain and send a node announcement. This is done since a node
|
||||||
// is only accepted after a channel is known for that particular node,
|
// announcement is only accepted after a channel is known for that
|
||||||
// and this might be our first channel.
|
// particular node, and this might be our first channel.
|
||||||
graph := f.cfg.Wallet.Cfg.Database.ChannelGraph()
|
nodeAnn, err := f.cfg.CurrentNodeAnnouncement()
|
||||||
self, err := graph.FetchLightningNode(f.cfg.IDKey)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fndgLog.Errorf("unable to fetch own lightning node from "+
|
fndgLog.Errorf("can't generate node announcement: %v", err)
|
||||||
"channel graph: %v", err)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create node announcement with updated timestamp to make sure it gets
|
|
||||||
// propagated in the network, in particular by our local announcement
|
|
||||||
// process logic. In case we just sent one, add one second to the time,
|
|
||||||
// to make sure it gets propagated.
|
|
||||||
timestamp := time.Now().Unix()
|
|
||||||
if timestamp <= self.LastUpdate.Unix() {
|
|
||||||
timestamp = self.LastUpdate.Unix() + 1
|
|
||||||
}
|
|
||||||
nodeAnn := &lnwire.NodeAnnouncement{
|
|
||||||
Timestamp: uint32(timestamp),
|
|
||||||
Addresses: self.Addresses,
|
|
||||||
NodeID: self.PubKey,
|
|
||||||
Alias: lnwire.NewAlias(self.Alias),
|
|
||||||
Features: self.Features,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Since the timestamp is changed, we cannot reuse the old signature
|
|
||||||
// and must re-sign the announcement.
|
|
||||||
sign, err := f.cfg.SignNodeAnnouncement(nodeAnn)
|
|
||||||
if err != nil {
|
|
||||||
fndgLog.Errorf("unable to generate signature for self node "+
|
|
||||||
"announcement: %v", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
nodeAnn.Signature = sign
|
|
||||||
f.cfg.SendAnnouncement(nodeAnn)
|
f.cfg.SendAnnouncement(nodeAnn)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
12
lnd.go
12
lnd.go
@ -20,7 +20,6 @@ import (
|
|||||||
flags "github.com/btcsuite/go-flags"
|
flags "github.com/btcsuite/go-flags"
|
||||||
proxy "github.com/grpc-ecosystem/grpc-gateway/runtime"
|
proxy "github.com/grpc-ecosystem/grpc-gateway/runtime"
|
||||||
"github.com/lightningnetwork/lnd/channeldb"
|
"github.com/lightningnetwork/lnd/channeldb"
|
||||||
"github.com/lightningnetwork/lnd/discovery"
|
|
||||||
"github.com/lightningnetwork/lnd/lnrpc"
|
"github.com/lightningnetwork/lnd/lnrpc"
|
||||||
"github.com/lightningnetwork/lnd/lnwallet"
|
"github.com/lightningnetwork/lnd/lnwallet"
|
||||||
"github.com/lightningnetwork/lnd/lnwire"
|
"github.com/lightningnetwork/lnd/lnwire"
|
||||||
@ -137,15 +136,8 @@ func lndMain() error {
|
|||||||
pubKey, msg,
|
pubKey, msg,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
SignNodeAnnouncement: func(nodeAnn *lnwire.NodeAnnouncement) (*btcec.Signature, error) {
|
CurrentNodeAnnouncement: func() (*lnwire.NodeAnnouncement, error) {
|
||||||
sig, err := discovery.SignAnnouncement(nodeSigner,
|
return server.genNodeAnnouncement(true)
|
||||||
server.identityPriv.PubKey(),
|
|
||||||
nodeAnn,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return sig, nil
|
|
||||||
},
|
},
|
||||||
SendAnnouncement: func(msg lnwire.Message) error {
|
SendAnnouncement: func(msg lnwire.Message) error {
|
||||||
server.discoverSrv.ProcessLocalAnnouncement(msg,
|
server.discoverSrv.ProcessLocalAnnouncement(msg,
|
||||||
|
@ -3528,6 +3528,9 @@ type ForceCloseSummary struct {
|
|||||||
|
|
||||||
// SelfOutputSignDesc is a fully populated sign descriptor capable of
|
// SelfOutputSignDesc is a fully populated sign descriptor capable of
|
||||||
// generating a valid signature to sweep the self output.
|
// generating a valid signature to sweep the self output.
|
||||||
|
//
|
||||||
|
// NOTE: If the commitment delivery output of the force closing party
|
||||||
|
// is below the dust limit, then this will be nil.
|
||||||
SelfOutputSignDesc *SignDescriptor
|
SelfOutputSignDesc *SignDescriptor
|
||||||
|
|
||||||
// SelfOutputMaturity is the relative maturity period before the above
|
// SelfOutputMaturity is the relative maturity period before the above
|
||||||
|
@ -12,7 +12,6 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -247,14 +246,14 @@ func (l *lightningNode) Start(lndError chan error) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait until TLS certificate is created before using it, up to 10 sec.
|
// Wait until TLS certificate is created before using it, up to 20 sec.
|
||||||
tlsTimeout := time.After(10 * time.Second)
|
tlsTimeout := time.After(20 * time.Second)
|
||||||
for !fileExists(l.cfg.TLSCertPath) {
|
for !fileExists(l.cfg.TLSCertPath) {
|
||||||
time.Sleep(100 * time.Millisecond)
|
time.Sleep(100 * time.Millisecond)
|
||||||
select {
|
select {
|
||||||
case <-tlsTimeout:
|
case <-tlsTimeout:
|
||||||
panic(fmt.Errorf("timeout waiting for TLS cert file " +
|
panic(fmt.Errorf("timeout waiting for TLS cert file " +
|
||||||
"to be created after 10 seconds"))
|
"to be created after 20 seconds"))
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -395,12 +394,6 @@ type chanWatchRequest struct {
|
|||||||
func (l *lightningNode) lightningNetworkWatcher() {
|
func (l *lightningNode) lightningNetworkWatcher() {
|
||||||
defer l.wg.Done()
|
defer l.wg.Done()
|
||||||
|
|
||||||
// If the channel router is shutting down, then we won't consider it as
|
|
||||||
// a real error. This just indicates the daemon itself is quitting.
|
|
||||||
isShutdownError := func(err error) bool {
|
|
||||||
return strings.Contains(err.Error(), "shutting down")
|
|
||||||
}
|
|
||||||
|
|
||||||
graphUpdates := make(chan *lnrpc.GraphTopologyUpdate)
|
graphUpdates := make(chan *lnrpc.GraphTopologyUpdate)
|
||||||
l.wg.Add(1)
|
l.wg.Add(1)
|
||||||
go func() {
|
go func() {
|
||||||
@ -422,25 +415,7 @@ func (l *lightningNode) lightningNetworkWatcher() {
|
|||||||
if err == io.EOF {
|
if err == io.EOF {
|
||||||
return
|
return
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
// If the node has been signalled to quit, then
|
return
|
||||||
// we'll exit early.
|
|
||||||
select {
|
|
||||||
case <-l.quit:
|
|
||||||
return
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise, if the node is shutting down on
|
|
||||||
// it's own, then we'll also bail out early.
|
|
||||||
if isShutdownError(err) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Similar to the case above, we also panic
|
|
||||||
// here (and end the tests) as these
|
|
||||||
// notifications are critical to the success of
|
|
||||||
// many tests.
|
|
||||||
panic(fmt.Errorf("unable read update ntfn: %v", err))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
|
2
peer.go
2
peer.go
@ -1502,7 +1502,7 @@ func waitForChanToClose(bestHeight uint32, notifier chainntnfs.ChainNotifier,
|
|||||||
|
|
||||||
// The channel has been closed, remove it from any active indexes, and
|
// The channel has been closed, remove it from any active indexes, and
|
||||||
// the database state.
|
// the database state.
|
||||||
srvrLog.Infof("ChannelPoint(%v) is now closed at "+
|
peerLog.Infof("ChannelPoint(%v) is now closed at "+
|
||||||
"height %v", chanPoint, height.BlockHeight)
|
"height %v", chanPoint, height.BlockHeight)
|
||||||
|
|
||||||
// Finally, execute the closure call back to mark the confirmation of
|
// Finally, execute the closure call back to mark the confirmation of
|
||||||
|
53
server.go
53
server.go
@ -94,6 +94,12 @@ type server struct {
|
|||||||
// only affect the protocol between these two nodes.
|
// only affect the protocol between these two nodes.
|
||||||
localFeatures *lnwire.FeatureVector
|
localFeatures *lnwire.FeatureVector
|
||||||
|
|
||||||
|
// currentNodeAnn is the node announcement that has been broadcast to
|
||||||
|
// the network upon startup, if the attributes of the node (us) has
|
||||||
|
// changed since last start.
|
||||||
|
annMtx sync.Mutex
|
||||||
|
currentNodeAnn *lnwire.NodeAnnouncement
|
||||||
|
|
||||||
wg sync.WaitGroup
|
wg sync.WaitGroup
|
||||||
quit chan struct{}
|
quit chan struct{}
|
||||||
}
|
}
|
||||||
@ -208,7 +214,7 @@ func newServer(listenAddrs []string, chanDB *channeldb.DB, cc *chainControl,
|
|||||||
|
|
||||||
// TODO(roasbeef): make alias configurable
|
// TODO(roasbeef): make alias configurable
|
||||||
alias := lnwire.NewAlias(hex.EncodeToString(serializedPubKey[:10]))
|
alias := lnwire.NewAlias(hex.EncodeToString(serializedPubKey[:10]))
|
||||||
self := &channeldb.LightningNode{
|
selfNode := &channeldb.LightningNode{
|
||||||
HaveNodeAnnouncement: true,
|
HaveNodeAnnouncement: true,
|
||||||
LastUpdate: time.Now(),
|
LastUpdate: time.Now(),
|
||||||
Addresses: selfAddrs,
|
Addresses: selfAddrs,
|
||||||
@ -220,25 +226,30 @@ func newServer(listenAddrs []string, chanDB *channeldb.DB, cc *chainControl,
|
|||||||
// If our information has changed since our last boot, then we'll
|
// If our information has changed since our last boot, then we'll
|
||||||
// re-sign our node announcement so a fresh authenticated version of it
|
// re-sign our node announcement so a fresh authenticated version of it
|
||||||
// can be propagated throughout the network upon startup.
|
// can be propagated throughout the network upon startup.
|
||||||
|
//
|
||||||
// TODO(roasbeef): don't always set timestamp above to _now.
|
// TODO(roasbeef): don't always set timestamp above to _now.
|
||||||
self.AuthSig, err = discovery.SignAnnouncement(s.nodeSigner,
|
nodeAnn := &lnwire.NodeAnnouncement{
|
||||||
s.identityPriv.PubKey(),
|
Timestamp: uint32(selfNode.LastUpdate.Unix()),
|
||||||
&lnwire.NodeAnnouncement{
|
Addresses: selfNode.Addresses,
|
||||||
Timestamp: uint32(self.LastUpdate.Unix()),
|
NodeID: selfNode.PubKey,
|
||||||
Addresses: self.Addresses,
|
Alias: alias,
|
||||||
NodeID: self.PubKey,
|
Features: selfNode.Features,
|
||||||
Alias: alias,
|
}
|
||||||
Features: self.Features,
|
selfNode.AuthSig, err = discovery.SignAnnouncement(s.nodeSigner,
|
||||||
},
|
s.identityPriv.PubKey(), nodeAnn,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("unable to generate signature for "+
|
return nil, fmt.Errorf("unable to generate signature for "+
|
||||||
"self node announcement: %v", err)
|
"self node announcement: %v", err)
|
||||||
}
|
}
|
||||||
if err := chanGraph.SetSourceNode(self); err != nil {
|
|
||||||
|
if err := chanGraph.SetSourceNode(selfNode); err != nil {
|
||||||
return nil, fmt.Errorf("can't set self node: %v", err)
|
return nil, fmt.Errorf("can't set self node: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nodeAnn.Signature = selfNode.AuthSig
|
||||||
|
s.currentNodeAnn = nodeAnn
|
||||||
|
|
||||||
s.chanRouter, err = routing.New(routing.Config{
|
s.chanRouter, err = routing.New(routing.Config{
|
||||||
Graph: chanGraph,
|
Graph: chanGraph,
|
||||||
Chain: cc.chainIO,
|
Chain: cc.chainIO,
|
||||||
@ -380,6 +391,26 @@ func (s *server) Stop() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// genNodeAnnouncement generates and returns the current fully signed node
|
||||||
|
// 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) (*lnwire.NodeAnnouncement, error) {
|
||||||
|
s.annMtx.Lock()
|
||||||
|
defer s.annMtx.Unlock()
|
||||||
|
|
||||||
|
if !refresh {
|
||||||
|
return s.currentNodeAnn, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
s.currentNodeAnn.Timestamp = uint32(time.Now().Unix())
|
||||||
|
s.currentNodeAnn.Signature, err = discovery.SignAnnouncement(s.nodeSigner,
|
||||||
|
s.identityPriv.PubKey(), s.currentNodeAnn,
|
||||||
|
)
|
||||||
|
|
||||||
|
return s.currentNodeAnn, err
|
||||||
|
}
|
||||||
|
|
||||||
// establishPersistentConnections attempts to establish persistent connections
|
// establishPersistentConnections attempts to establish persistent connections
|
||||||
// to all our direct channel collaborators. In order to promote liveness of
|
// to all our direct channel collaborators. In order to promote liveness of
|
||||||
// our active channels, we instruct the connection manager to attempt to
|
// our active channels, we instruct the connection manager to attempt to
|
||||||
|
Loading…
Reference in New Issue
Block a user