@@ -473,6 +473,60 @@ func (c *cachedReject) Size() (uint64, error) {
473473 return 1 , nil
474474}
475475
476+ // sentAnnSigsTracker tracks which announcement signatures we've sent to which
477+ // peers.
478+ type sentAnnSigsTracker struct {
479+ mu sync.Mutex
480+ sigs map [route.Vertex ]map [lnwire.ChannelID ]struct {}
481+ }
482+
483+ // newSentAnnSigsTracker creates a new sentAnnSigsTracker.
484+ func newSentAnnSigsTracker () * sentAnnSigsTracker {
485+ return & sentAnnSigsTracker {
486+ sigs : make (map [route.Vertex ]map [lnwire.ChannelID ]struct {}),
487+ }
488+ }
489+
490+ // deletePeer deletes all records of sent announcement signatures for a given
491+ // peer.
492+ func (s * sentAnnSigsTracker ) deletePeer (peer route.Vertex ) {
493+ s .mu .Lock ()
494+ defer s .mu .Unlock ()
495+ delete (s .sigs , peer )
496+ }
497+
498+ // sentToPeer returns true if we have already sent the announcement signature
499+ // for a given channel to a peer.
500+ func (s * sentAnnSigsTracker ) sentToPeer (peer route.Vertex ,
501+ cid lnwire.ChannelID ) bool {
502+
503+ s .mu .Lock ()
504+ defer s .mu .Unlock ()
505+
506+ sentChans , ok := s .sigs [peer ]
507+ if ! ok {
508+ return false
509+ }
510+
511+ _ , ok = sentChans [cid ]
512+
513+ return ok
514+ }
515+
516+ // addToPeer adds a record of sending an announcement signature for a given
517+ // channel to a peer.
518+ func (s * sentAnnSigsTracker ) addToPeer (peer route.Vertex ,
519+ cid lnwire.ChannelID ) {
520+
521+ s .mu .Lock ()
522+ defer s .mu .Unlock ()
523+
524+ if _ , ok := s .sigs [peer ]; ! ok {
525+ s .sigs [peer ] = make (map [lnwire.ChannelID ]struct {})
526+ }
527+ s.sigs [peer ][cid ] = struct {}{}
528+ }
529+
476530// AuthenticatedGossiper is a subsystem which is responsible for receiving
477531// announcements, validating them and applying the changes to router, syncing
478532// lightning network with newly connected nodes, broadcasting announcements
@@ -568,6 +622,11 @@ type AuthenticatedGossiper struct {
568622 // vb is used to enforce job dependency ordering of gossip messages.
569623 vb * ValidationBarrier
570624
625+ // sentAnnSigs tracks which announcement signatures we've sent to which
626+ // peers. We'll use this to ensure we don't re-send the same signatures
627+ // to a peer during a single connection.
628+ sentAnnSigs * sentAnnSigsTracker
629+
571630 sync.Mutex
572631
573632 cancel fn.Option [context.CancelFunc ]
@@ -595,6 +654,7 @@ func New(cfg Config, selfKeyDesc *keychain.KeyDescriptor) *AuthenticatedGossiper
595654 ),
596655 chanUpdateRateLimiter : make (map [uint64 ][2 ]* rate.Limiter ),
597656 banman : newBanman (cfg .BanThreshold ),
657+ sentAnnSigs : newSentAnnSigsTracker (),
598658 }
599659
600660 gossiper .vb = NewValidationBarrier (1000 , gossiper .quit )
@@ -1677,6 +1737,14 @@ func (d *AuthenticatedGossiper) handleNetworkMessages(ctx context.Context,
16771737// queries. We'll allocate a new gossip syncer for it, and start any goroutines
16781738// needed to handle new queries.
16791739func (d * AuthenticatedGossiper ) InitSyncState (syncPeer lnpeer.Peer ) {
1740+ peerVertex := route .NewVertex (syncPeer .IdentityKey ())
1741+
1742+ // We keep track if we already have sent an announcement signature to
1743+ // each peer during a connection, so we don't send it twice. If a peer
1744+ // dis- and reconnects we clear the record. If the peer connects for the
1745+ // first time this is a no-op.
1746+ d .sentAnnSigs .deletePeer (peerVertex )
1747+
16801748 d .syncMgr .InitSyncState (syncPeer )
16811749}
16821750
@@ -3542,12 +3610,26 @@ func (d *AuthenticatedGossiper) handleAnnSig(ctx context.Context,
35423610 if chanInfo .AuthProof != nil {
35433611 // If we already have the fully assembled proof, then the peer
35443612 // sending us their proof has probably not received our local
3545- // proof yet. So be kind and send them our proof.
3613+ // proof yet. So be kind and send them our proof, but only if we
3614+ // haven't done so since (re)connecting.
35463615 if nMsg .isRemote {
3547- peerID := nMsg .source .SerializeCompressed ()
3548- log .Debugf ("Got AnnounceSignatures for channel with " +
3549- "full proof." )
3616+ peerVertex := route .NewVertex (nMsg .source )
3617+
3618+ if d .sentAnnSigs .sentToPeer (peerVertex , ann .ChannelID ) {
3619+ log .Debugf ("Skipping sending " +
3620+ "announcement signatures " +
3621+ "since we already did during " +
3622+ "this connection." )
35503623
3624+ nMsg .err <- nil
3625+
3626+ return nil , true
3627+ }
3628+
3629+ peerID := nMsg .source .SerializeCompressed ()
3630+ peerIsFirstNode := bytes .Equal (
3631+ peerID , chanInfo .NodeKey1Bytes [:],
3632+ )
35513633 d .wg .Add (1 )
35523634 go func () {
35533635 defer d .wg .Done ()
@@ -3558,28 +3640,39 @@ func (d *AuthenticatedGossiper) handleAnnSig(ctx context.Context,
35583640 ann .ChannelID , peerID )
35593641
35603642 chanAP := chanInfo .AuthProof
3561- var remoteNSB []byte
3562- var remoteBSB []byte
3563- if isFirstNode {
3564- remoteNSB = chanAP .NodeSig2Bytes
3565- remoteBSB = chanAP .BitcoinSig2Bytes
3643+ // Pick the local signatures that the peer does
3644+ // NOT have yet. If the peer is node1, they sent
3645+ // us node1/bitcoin1 already, so we respond with
3646+ // node2/bitcoin2. Otherwise we respond with
3647+ // node1/bitcoin1.
3648+ var localNSB , localBSB []byte
3649+ if peerIsFirstNode {
3650+ localNSB = chanAP .NodeSig2Bytes
3651+ localBSB = chanAP .BitcoinSig2Bytes
35663652 } else {
3567- remoteNSB = chanAP .NodeSig1Bytes
3568- remoteBSB = chanAP .BitcoinSig1Bytes
3653+ localNSB = chanAP .NodeSig1Bytes
3654+ localBSB = chanAP .BitcoinSig1Bytes
35693655 }
35703656
3657+ // Construct an AnnounceSignatures message from
3658+ // the raw signature material. This gives the
3659+ // peer our half of the proof so they can
3660+ // assemble the full ChannelAnnouncement.
35713661 sigAnn , err := lnwire .NewAnnSigFromWireECDSARaw (
35723662 ann .ChannelID , ann .ShortChannelID ,
3573- remoteNSB , remoteBSB , nil ,
3663+ localNSB , localBSB , nil ,
35743664 )
3575-
35763665 if err != nil {
35773666 log .Errorf ("Failed to generate " +
35783667 "announcement signature: %v" ,
35793668 err )
35803669 return
35813670 }
35823671
3672+ // Send our half of the proof to the peer. If
3673+ // successful, we mark that we've sent the proof
3674+ // during this connection so we don't re-send it
3675+ // on subsequent half-proof messages.
35833676 err = nMsg .peer .SendMessage (false , sigAnn )
35843677 if err != nil {
35853678 log .Errorf ("Failed sending signature " +
@@ -3588,6 +3681,13 @@ func (d *AuthenticatedGossiper) handleAnnSig(ctx context.Context,
35883681 return
35893682 }
35903683
3684+ // With the announcement sent, we'll now mark
3685+ // that we've sent the proof to the peer for
3686+ // this connection.
3687+ d .sentAnnSigs .addToPeer (
3688+ peerVertex , ann .ChannelID ,
3689+ )
3690+
35913691 log .Debugf ("Signature announcement sent to " +
35923692 "peer=%x for chanID=%v" , peerID ,
35933693 ann .ChannelID )
0 commit comments