fundingmanager: send NodeAnnouncement to unadvertised channel counterparty

In this commit, we modify the funding manager to send our
NodeAnnouncement to our channel counterparty in the event of an
unadvertised channel. We do this to ensure that our counterparty learns
about some information about us that may aid them in one way or another
(e.g., addresses to reconnect, features supported, etc.).
This commit is contained in:
Wilmer Paulino 2018-10-17 15:59:02 -07:00
parent 748da2f50a
commit 85cdb18b73
No known key found for this signature in database
GPG Key ID: 6DF57B9F9514972F
2 changed files with 96 additions and 18 deletions

View File

@ -15,9 +15,6 @@ import (
"github.com/coreos/bbolt"
"github.com/davecgh/go-spew/spew"
"github.com/go-errors/errors"
"golang.org/x/crypto/salsa20"
"google.golang.org/grpc"
"github.com/lightningnetwork/lnd/chainntnfs"
"github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/htlcswitch"
@ -27,6 +24,8 @@ import (
"github.com/lightningnetwork/lnd/lnwallet"
"github.com/lightningnetwork/lnd/lnwire"
"github.com/lightningnetwork/lnd/routing"
"golang.org/x/crypto/salsa20"
"google.golang.org/grpc"
)
const (
@ -2149,16 +2148,44 @@ func (f *fundingManager) addToRouterGraph(completeChan *channeldb.OpenChannel,
func (f *fundingManager) annAfterSixConfs(completeChan *channeldb.OpenChannel,
shortChanID *lnwire.ShortChannelID) error {
// If this channel is meant to be announced to the greater network,
// wait until the funding tx has reached 6 confirmations before
// announcing it.
// If this channel is not meant to be announced to the greater network,
// we'll only send our NodeAnnouncement to our counterparty to ensure we
// don't leak any of our information.
announceChan := completeChan.ChannelFlags&lnwire.FFAnnounceChannel != 0
if !announceChan {
fndgLog.Debugf("Will not announce private channel %v.",
shortChanID.ToUint64())
peerChan := make(chan lnpeer.Peer, 1)
f.cfg.NotifyWhenOnline(completeChan.IdentityPub, peerChan)
var peer lnpeer.Peer
select {
case peer = <-peerChan:
case <-f.quit:
return ErrFundingManagerShuttingDown
}
nodeAnn, err := f.cfg.CurrentNodeAnnouncement()
if err != nil {
return fmt.Errorf("unable to retrieve current node "+
"announcement: %v", err)
}
chanID := lnwire.NewChanIDFromOutPoint(
&completeChan.FundingOutpoint,
)
pubKey := peer.PubKey()
fndgLog.Debugf("Sending our NodeAnnouncement for "+
"ChannelID(%v) to %x", chanID, pubKey)
if err := peer.SendMessage(true, &nodeAnn); err != nil {
return fmt.Errorf("unable to send node announcement "+
"to peer %x: %v", pubKey, err)
}
} else {
// Register with the ChainNotifier for a notification once the
// funding transaction reaches at least 6 confirmations.
// Otherwise, we'll wait until the funding transaction has
// reached 6 confirmations before announcing it.
numConfs := uint32(completeChan.NumConfsRequired)
if numConfs < 6 {
numConfs = 6
@ -2176,8 +2203,11 @@ func (f *fundingManager) annAfterSixConfs(completeChan *channeldb.OpenChannel,
completeChan.FundingOutpoint, err)
}
// Register with the ChainNotifier for a notification once the
// funding transaction reaches at least 6 confirmations.
confNtfn, err := f.cfg.Notifier.RegisterConfirmationsNtfn(
&txid, fundingScript, numConfs, completeChan.FundingBroadcastHeight,
&txid, fundingScript, numConfs,
completeChan.FundingBroadcastHeight,
)
if err != nil {
return fmt.Errorf("Unable to register for "+

View File

@ -1933,7 +1933,7 @@ func TestFundingManagerPrivateChannel(t *testing.T) {
bob.mockNotifier.sixConfChannel <- &chainntnfs.TxConfirmation{}
// Since this is a private channel, we shouldn't receive the
// announcement signatures or node announcement messages.
// announcement signatures.
select {
case ann := <-alice.announceChan:
t.Fatalf("unexpectedly got channel announcement message: %v", ann)
@ -1948,6 +1948,25 @@ func TestFundingManagerPrivateChannel(t *testing.T) {
// Expected
}
// We should however receive each side's node announcement.
select {
case msg := <-alice.msgChan:
if _, ok := msg.(*lnwire.NodeAnnouncement); !ok {
t.Fatalf("expected to receive node announcement")
}
case <-time.After(time.Second):
t.Fatalf("expected to receive node announcement")
}
select {
case msg := <-bob.msgChan:
if _, ok := msg.(*lnwire.NodeAnnouncement); !ok {
t.Fatalf("expected to receive node announcement")
}
case <-time.After(time.Second):
t.Fatalf("expected to receive node announcement")
}
// The internal state-machine should now have deleted the channelStates
// from the database, as the channel is announced.
assertNoChannelState(t, alice, bob, fundingOutPoint)
@ -2013,19 +2032,48 @@ func TestFundingManagerPrivateRestart(t *testing.T) {
// channel.
assertHandleFundingLocked(t, alice, bob)
// Restart Alice's fundingManager so we can prove that the public
// channel announcements are not sent upon restart and that the private
// setting persists upon restart.
recreateAliceFundingManager(t, alice)
time.Sleep(300 * time.Millisecond)
// Notify that six confirmations has been reached on funding transaction.
alice.mockNotifier.sixConfChannel <- &chainntnfs.TxConfirmation{}
bob.mockNotifier.sixConfChannel <- &chainntnfs.TxConfirmation{}
// Since this is a private channel, we shouldn't receive the public
// channel announcement messages announcement signatures or
// node announcement.
// channel announcement messages.
select {
case ann := <-alice.announceChan:
t.Fatalf("unexpectedly got channel announcement message: %v", ann)
case <-time.After(300 * time.Millisecond):
}
select {
case ann := <-bob.announceChan:
t.Fatalf("unexpectedly got channel announcement message: %v", ann)
case <-time.After(300 * time.Millisecond):
}
// We should however receive each side's node announcement.
select {
case msg := <-alice.msgChan:
if _, ok := msg.(*lnwire.NodeAnnouncement); !ok {
t.Fatalf("expected to receive node announcement")
}
case <-time.After(time.Second):
t.Fatalf("expected to receive node announcement")
}
select {
case msg := <-bob.msgChan:
if _, ok := msg.(*lnwire.NodeAnnouncement); !ok {
t.Fatalf("expected to receive node announcement")
}
case <-time.After(time.Second):
t.Fatalf("expected to receive node announcement")
}
// Restart Alice's fundingManager so we can prove that the public
// channel announcements are not sent upon restart and that the private
// setting persists upon restart.
recreateAliceFundingManager(t, alice)
select {
case ann := <-alice.announceChan:
t.Fatalf("unexpectedly got channel announcement message: %v", ann)