Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit fc25f3d

Browse files
committedDec 20, 2024
discovery: dont_forward bit in msg flag.
In case the __dont_forward__ is set in the ChanUpdate msg lnd will not forward this msg to the gossiper hence broadcasting it to all its peers. This makes sure we follow the network rules and dont forward ChanUpdates which do not signal it.
1 parent b49789f commit fc25f3d

File tree

2 files changed

+136
-35
lines changed

2 files changed

+136
-35
lines changed
 

‎discovery/gossiper.go

+117-33
Original file line numberDiff line numberDiff line change
@@ -1462,6 +1462,10 @@ func (d *AuthenticatedGossiper) networkHandler() {
14621462
sourceToPub(announcement.source),
14631463
) {
14641464

1465+
peer := sourceToPub(announcement.source)
1466+
log.Debugf("Throttling messages from peer=%v "+
1467+
"(recently rejected)", peer)
1468+
14651469
announcement.err <- fmt.Errorf("recently " +
14661470
"rejected")
14671471
continue
@@ -1927,17 +1931,24 @@ func (d *AuthenticatedGossiper) processRejectedEdge(
19271931
msg: chanAnn,
19281932
})
19291933
if e1Ann != nil {
1930-
announcements = append(announcements, networkMsg{
1931-
source: d.selfKey,
1932-
msg: e1Ann,
1933-
})
1934+
// Only add the ChanUpdate to the gossiper if the
1935+
// __dont_forward__ bit signals it.
1936+
if !e1Ann.MessageFlags.HasDontForward() {
1937+
announcements = append(announcements, networkMsg{
1938+
source: d.selfKey,
1939+
msg: e1Ann,
1940+
})
1941+
}
19341942
}
19351943
if e2Ann != nil {
1936-
announcements = append(announcements, networkMsg{
1937-
source: d.selfKey,
1938-
msg: e2Ann,
1939-
})
1940-
1944+
// Only add the ChanUpdate to the gossiper if the
1945+
// __dont_forward__ bit signals it.
1946+
if !e2Ann.MessageFlags.HasDontForward() {
1947+
announcements = append(announcements, networkMsg{
1948+
source: d.selfKey,
1949+
msg: e2Ann,
1950+
})
1951+
}
19411952
}
19421953

19431954
return announcements, nil
@@ -2347,6 +2358,18 @@ func IsKeepAliveUpdate(update *lnwire.ChannelUpdate1,
23472358
if update.MessageFlags.HasMaxHtlc() && !prev.MessageFlags.HasMaxHtlc() {
23482359
return false
23492360
}
2361+
2362+
// Every public channel starts with the dont_forward bit set before the
2363+
// mandatory six confirmations are reached. We will see 2 different
2364+
// ChanUpdates before a public channel is announced to the broader
2365+
// network. We need to make sure we don't consider the second one as a
2366+
// keepalive msg.
2367+
if !update.MessageFlags.HasDontForward() &&
2368+
prev.MessageFlags.HasDontForward() {
2369+
2370+
return false
2371+
}
2372+
23502373
if update.HtlcMaximumMsat != prev.MaxHTLC {
23512374
return false
23522375
}
@@ -2459,6 +2482,10 @@ func (d *AuthenticatedGossiper) handleChanAnnouncement(nMsg *networkMsg,
24592482
)
24602483
_, _ = d.recentRejects.Put(key, &cachedReject{})
24612484

2485+
log.Debugf("Adding msg short_chan_id(%v) from "+
2486+
"peer=%x to RejectCache", key.chanID,
2487+
key.pubkey)
2488+
24622489
nMsg.err <- err
24632490
return nil, false
24642491
}
@@ -2476,6 +2503,10 @@ func (d *AuthenticatedGossiper) handleChanAnnouncement(nMsg *networkMsg,
24762503
)
24772504
_, _ = d.recentRejects.Put(key, &cachedReject{})
24782505

2506+
log.Debugf("Adding msg short_chan_id(%v) from "+
2507+
"peer=%x to RejectCache", key.chanID,
2508+
key.pubkey)
2509+
24792510
nMsg.err <- err
24802511
return nil, false
24812512
}
@@ -2560,6 +2591,10 @@ func (d *AuthenticatedGossiper) handleChanAnnouncement(nMsg *networkMsg,
25602591
)
25612592
_, _ = d.recentRejects.Put(key, &cachedReject{})
25622593

2594+
log.Debugf("Adding msg short_chan_id(%v) from "+
2595+
"peer=%x to RejectCache", key.chanID,
2596+
key.pubkey)
2597+
25632598
log.Error(err)
25642599
nMsg.err <- err
25652600
return nil, false
@@ -2673,6 +2708,10 @@ func (d *AuthenticatedGossiper) handleChanAnnouncement(nMsg *networkMsg,
26732708
)
26742709
_, _ = d.recentRejects.Put(key, &cachedReject{})
26752710

2711+
log.Debugf("Adding msg short_chan_id(%v) from "+
2712+
"peer=%x to RejectCache", key.chanID,
2713+
key.pubkey)
2714+
26762715
// Increment the peer's ban score. We check isRemote
26772716
// so we don't actually ban the peer in case of a local
26782717
// bug.
@@ -2687,6 +2726,10 @@ func (d *AuthenticatedGossiper) handleChanAnnouncement(nMsg *networkMsg,
26872726
)
26882727
_, _ = d.recentRejects.Put(key, &cachedReject{})
26892728

2729+
log.Debugf("Adding msg short_chan_id(%v) from "+
2730+
"peer=%x to RejectCache", key.chanID,
2731+
key.pubkey)
2732+
26902733
// Since this channel has already been closed, we'll
26912734
// add it to the graph's closed channel index such that
26922735
// we won't attempt to do expensive validation checks
@@ -2717,6 +2760,10 @@ func (d *AuthenticatedGossiper) handleChanAnnouncement(nMsg *networkMsg,
27172760
sourceToPub(nMsg.source),
27182761
)
27192762
_, _ = d.recentRejects.Put(key, &cachedReject{})
2763+
2764+
log.Debugf("Adding msg short_chan_id(%v) from "+
2765+
"peer=%x to RejectCache", key.chanID,
2766+
key.pubkey)
27202767
}
27212768

27222769
if !nMsg.isRemote {
@@ -2847,6 +2894,10 @@ func (d *AuthenticatedGossiper) handleChanUpdate(nMsg *networkMsg,
28472894
)
28482895
_, _ = d.recentRejects.Put(key, &cachedReject{})
28492896

2897+
log.Debugf("Adding msg short_chan_id(%v) from "+
2898+
"peer=%x to RejectCache", key.chanID,
2899+
key.pubkey)
2900+
28502901
nMsg.err <- err
28512902
return nil, false
28522903
}
@@ -2956,9 +3007,9 @@ func (d *AuthenticatedGossiper) handleChanUpdate(nMsg *networkMsg,
29563007
// If the edge corresponding to this ChannelUpdate was not
29573008
// found in the graph, this might be a channel in the process
29583009
// of being opened, and we haven't processed our own
2959-
// ChannelAnnouncement yet, hence it is not not found in the
2960-
// graph. This usually gets resolved after the channel proofs
2961-
// are exchanged and the channel is broadcasted to the rest of
3010+
// ChannelAnnouncement yet, hence it is not found in the graph.
3011+
// This usually gets resolved after the channel proofs are
3012+
// exchanged and the channel is broadcasted to the rest of
29623013
// the network, but in case this is a private channel this
29633014
// won't ever happen. This can also happen in the case of a
29643015
// zombie channel with a fresh update for which we don't have a
@@ -3014,6 +3065,10 @@ func (d *AuthenticatedGossiper) handleChanUpdate(nMsg *networkMsg,
30143065
)
30153066
_, _ = d.recentRejects.Put(key, &cachedReject{})
30163067

3068+
log.Debugf("Adding msg short_chan_id(%v) from "+
3069+
"peer=%x to RejectCache", key.chanID,
3070+
key.pubkey)
3071+
30173072
return nil, false
30183073
}
30193074

@@ -3143,6 +3198,10 @@ func (d *AuthenticatedGossiper) handleChanUpdate(nMsg *networkMsg,
31433198
)
31443199
_, _ = d.recentRejects.Put(key, &cachedReject{})
31453200

3201+
log.Debugf("Adding msg short_chan_id(%v) from "+
3202+
"peer=%x to RejectCache", key.chanID,
3203+
key.pubkey)
3204+
31463205
log.Errorf("Update edge for short_chan_id(%v) got: %v",
31473206
shortChanID, err)
31483207
}
@@ -3151,6 +3210,11 @@ func (d *AuthenticatedGossiper) handleChanUpdate(nMsg *networkMsg,
31513210
return nil, false
31523211
}
31533212

3213+
// Get our peer's public key.
3214+
remotePubKey := remotePubFromChanInfo(
3215+
chanInfo, upd.ChannelFlags,
3216+
)
3217+
31543218
// If this is a local ChannelUpdate without an AuthProof, it means it
31553219
// is an update to a channel that is not (yet) supposed to be announced
31563220
// to the greater network. However, our channel counter party will need
@@ -3186,11 +3250,6 @@ func (d *AuthenticatedGossiper) handleChanUpdate(nMsg *networkMsg,
31863250
}
31873251
}
31883252

3189-
// Get our peer's public key.
3190-
remotePubKey := remotePubFromChanInfo(
3191-
chanInfo, upd.ChannelFlags,
3192-
)
3193-
31943253
log.Debugf("The message %v has no AuthProof, sending the "+
31953254
"update to remote peer %x", upd.MsgType(), remotePubKey)
31963255

@@ -3214,12 +3273,29 @@ func (d *AuthenticatedGossiper) handleChanUpdate(nMsg *networkMsg,
32143273
// contains an alias because the network would reject this.
32153274
var announcements []networkMsg
32163275
if chanInfo.AuthProof != nil && !d.cfg.IsAlias(upd.ShortChannelID) {
3217-
announcements = append(announcements, networkMsg{
3218-
peer: nMsg.peer,
3219-
source: nMsg.source,
3220-
isRemote: nMsg.isRemote,
3221-
msg: upd,
3222-
})
3276+
// We log the case where the dont_forward bit is set although
3277+
// the channel is already announced to the network because we
3278+
// already have a AuthProof for it. In addition we do not add
3279+
// this msg to the gossip msg queue to make sure we follow the
3280+
// network rules.
3281+
if upd.MessageFlags.HasDontForward() {
3282+
log.Warnf("Received %v with the dont_forward bit set "+
3283+
"(msgflags=%s) for channel=%v from peer=%x "+
3284+
"for an announced channel, not forwarding to "+
3285+
"the broader network",
3286+
upd.MsgType().String(),
3287+
upd.MessageFlags.String(),
3288+
upd.ShortChannelID.ToUint64(),
3289+
remotePubKey,
3290+
)
3291+
} else {
3292+
announcements = append(announcements, networkMsg{
3293+
peer: nMsg.peer,
3294+
source: nMsg.source,
3295+
isRemote: nMsg.isRemote,
3296+
msg: upd,
3297+
})
3298+
}
32233299
}
32243300

32253301
nMsg.err <- nil
@@ -3495,18 +3571,26 @@ func (d *AuthenticatedGossiper) handleAnnSig(nMsg *networkMsg,
34953571
msg: chanAnn,
34963572
})
34973573
if src, err := chanInfo.NodeKey1(); err == nil && e1Ann != nil {
3498-
announcements = append(announcements, networkMsg{
3499-
peer: nMsg.peer,
3500-
source: src,
3501-
msg: e1Ann,
3502-
})
3574+
// Only add the ChanUpdate to the gossiper if the
3575+
// __dont_forward__ bit signals it.
3576+
if !e1Ann.MessageFlags.HasDontForward() {
3577+
announcements = append(announcements, networkMsg{
3578+
peer: nMsg.peer,
3579+
source: src,
3580+
msg: e1Ann,
3581+
})
3582+
}
35033583
}
35043584
if src, err := chanInfo.NodeKey2(); err == nil && e2Ann != nil {
3505-
announcements = append(announcements, networkMsg{
3506-
peer: nMsg.peer,
3507-
source: src,
3508-
msg: e2Ann,
3509-
})
3585+
// Only add the ChanUpdate to the gossiper if the
3586+
// __dont_forward__ bit signals it.
3587+
if !e2Ann.MessageFlags.HasDontForward() {
3588+
announcements = append(announcements, networkMsg{
3589+
peer: nMsg.peer,
3590+
source: src,
3591+
msg: e2Ann,
3592+
})
3593+
}
35103594
}
35113595

35123596
// We'll also send along the node announcements for each channel

‎discovery/gossiper_test.go

+19-2
Original file line numberDiff line numberDiff line change
@@ -3214,15 +3214,32 @@ func TestSendChannelUpdateReliably(t *testing.T) {
32143214
require.NoError(t, err, "unable to process remote channel proof")
32153215

32163216
// Now that we've constructed our full proof, we can assert that the
3217-
// channel has been announced.
3217+
// channel has been announced. We anticipate the local ChanAnnouncement
3218+
// and the local ChanUpdate.
3219+
gotChannelAnnouncement := false
3220+
gotChannelUpdate := false
32183221
for i := 0; i < 2; i++ {
32193222
select {
3220-
case <-ctx.broadcastedMessage:
3223+
case gossip := <-ctx.broadcastedMessage:
3224+
switch msg := gossip.msg.(type) {
3225+
case *lnwire.ChannelUpdate1:
3226+
gotChannelUpdate = true
3227+
case *lnwire.ChannelAnnouncement1:
3228+
gotChannelAnnouncement = true
3229+
default:
3230+
t.Fatalf("send unexpected %v "+
3231+
"message", msg.MsgType())
3232+
}
32213233
case <-time.After(2 * trickleDelay):
32223234
t.Fatal("expected channel to be announced")
32233235
}
32243236
}
32253237

3238+
require.Truef(
3239+
t, gotChannelAnnouncement, "did not receive ChanAnnouncement",
3240+
)
3241+
require.Truef(t, gotChannelUpdate, "did not receive ChanUpdate")
3242+
32263243
// With the channel announced, we'll generate a new channel update. This
32273244
// one won't take the path of the reliable sender, as the channel has
32283245
// already been announced. We'll keep track of the old message that is

0 commit comments

Comments
 (0)
Please sign in to comment.