Skip to content

Commit df65430

Browse files
committed
discovery: use ChannelUpdate interface in handleChanUpdate
1 parent fa17a7b commit df65430

File tree

1 file changed

+125
-90
lines changed

1 file changed

+125
-90
lines changed

discovery/gossiper.go

+125-90
Original file line numberDiff line numberDiff line change
@@ -2084,7 +2084,7 @@ func (d *AuthenticatedGossiper) processNetworkAnnouncement(
20842084
// A new authenticated channel edge update has arrived. This indicates
20852085
// that the directional information for an already known channel has
20862086
// been updated.
2087-
case *lnwire.ChannelUpdate1:
2087+
case lnwire.ChannelUpdate:
20882088
return d.handleChanUpdate(nMsg, msg, schedulerOp)
20892089

20902090
// A new signature announcement has been received. This indicates
@@ -2843,40 +2843,45 @@ func (d *AuthenticatedGossiper) handleChanAnnouncement(nMsg *networkMsg,
28432843

28442844
// handleChanUpdate processes a new channel update.
28452845
func (d *AuthenticatedGossiper) handleChanUpdate(nMsg *networkMsg,
2846-
upd *lnwire.ChannelUpdate1,
2847-
ops []batch.SchedulerOption) ([]networkMsg, bool) {
2846+
upd lnwire.ChannelUpdate, ops []batch.SchedulerOption) ([]networkMsg,
2847+
bool) {
28482848

2849-
log.Debugf("Processing ChannelUpdate1: peer=%v, short_chan_id=%v, ",
2850-
nMsg.peer, upd.ShortChannelID.ToUint64())
2849+
var (
2850+
scid = upd.SCID()
2851+
chainHash = upd.GetChainHash()
2852+
)
2853+
2854+
log.Debugf("Processing ChannelUpdate: peer=%v, short_chan_id=%v, ",
2855+
nMsg.peer, scid)
28512856

28522857
// We'll ignore any channel updates that target any chain other than
28532858
// the set of chains we know of.
2854-
if !bytes.Equal(upd.ChainHash[:], d.cfg.ChainHash[:]) {
2855-
err := fmt.Errorf("ignoring ChannelUpdate1 from chain=%v, "+
2856-
"gossiper on chain=%v", upd.ChainHash, d.cfg.ChainHash)
2859+
if !bytes.Equal(chainHash[:], d.cfg.ChainHash[:]) {
2860+
err := fmt.Errorf("ignoring %s from chain=%v, "+
2861+
"gossiper on chain=%v", upd.MsgType(), chainHash,
2862+
d.cfg.ChainHash)
28572863
log.Errorf(err.Error())
28582864

28592865
key := newRejectCacheKey(
2860-
upd.ShortChannelID.ToUint64(),
2861-
sourceToPub(nMsg.source),
2866+
scid.ToUint64(), sourceToPub(nMsg.source),
28622867
)
28632868
_, _ = d.recentRejects.Put(key, &cachedReject{})
28642869

28652870
nMsg.err <- err
28662871
return nil, false
28672872
}
28682873

2869-
blockHeight := upd.ShortChannelID.BlockHeight
2870-
shortChanID := upd.ShortChannelID.ToUint64()
2874+
blockHeight := upd.SCID().BlockHeight
2875+
shortChanID := upd.SCID().ToUint64()
28712876

28722877
// If the advertised inclusionary block is beyond our knowledge of the
28732878
// chain tip, then we'll put the announcement in limbo to be fully
28742879
// verified once we advance forward in the chain. If the update has an
28752880
// alias SCID, we'll skip the isPremature check. This is necessary
28762881
// since aliases start at block height 16_000_000.
28772882
d.Lock()
2878-
if nMsg.isRemote && !d.cfg.IsAlias(upd.ShortChannelID) &&
2879-
d.isPremature(upd.ShortChannelID, 0, nMsg) {
2883+
if nMsg.isRemote && !d.cfg.IsAlias(scid) &&
2884+
d.isPremature(scid, 0, nMsg) {
28802885

28812886
log.Warnf("Update announcement for short_chan_id(%v), is "+
28822887
"premature: advertises height %v, only height %v is "+
@@ -2887,31 +2892,28 @@ func (d *AuthenticatedGossiper) handleChanUpdate(nMsg *networkMsg,
28872892
}
28882893
d.Unlock()
28892894

2890-
// Before we perform any of the expensive checks below, we'll check
2891-
// whether this update is stale or is for a zombie channel in order to
2892-
// quickly reject it.
2893-
timestamp := time.Unix(int64(upd.Timestamp), 0)
2894-
28952895
// Fetch the SCID we should be using to lock the channelMtx and make
28962896
// graph queries with.
2897-
graphScid, err := d.cfg.FindBaseByAlias(upd.ShortChannelID)
2897+
graphScid, err := d.cfg.FindBaseByAlias(scid)
28982898
if err != nil {
28992899
// Fallback and set the graphScid to the peer-provided SCID.
29002900
// This will occur for non-option-scid-alias channels and for
29012901
// public option-scid-alias channels after 6 confirmations.
29022902
// Once public option-scid-alias channels have 6 confs, we'll
29032903
// ignore ChannelUpdates with one of their aliases.
2904-
graphScid = upd.ShortChannelID
2904+
graphScid = scid
29052905
}
29062906

2907+
// Before we perform any of the expensive checks below, we'll check
2908+
// whether this update is stale or is for a zombie channel in order to
2909+
// quickly reject it.
29072910
if d.cfg.Router.IsStaleEdgePolicy(graphScid, upd) {
29082911
log.Debugf("Ignored stale edge policy for short_chan_id(%v): "+
29092912
"peer=%v, msg=%s, is_remote=%v", shortChanID,
29102913
nMsg.peer, nMsg.msg.MsgType(), nMsg.isRemote,
29112914
)
29122915

29132916
nMsg.err <- nil
2914-
29152917
return nil, true
29162918
}
29172919

@@ -2953,7 +2955,7 @@ func (d *AuthenticatedGossiper) handleChanUpdate(nMsg *networkMsg,
29532955
// If the edge corresponding to this ChannelUpdate1 was not
29542956
// found in the graph, this might be a channel in the process
29552957
// of being opened, and we haven't processed our own
2956-
// ChannelAnnouncement1 yet, hence it is not found in the
2958+
// ChannelAnnouncement yet, hence it is not found in the
29572959
// graph. This usually gets resolved after the channel proofs
29582960
// are exchanged and the channel is broadcasted to the rest of
29592961
// the network, but in case this is a private channel this
@@ -2990,7 +2992,7 @@ func (d *AuthenticatedGossiper) handleChanUpdate(nMsg *networkMsg,
29902992
})
29912993
}
29922994

2993-
log.Debugf("Got ChannelUpdate1 for edge not found in graph"+
2995+
log.Debugf("Got ChannelUpdate for edge not found in graph"+
29942996
"(shortChanID=%v), saving for reprocessing later",
29952997
shortChanID)
29962998

@@ -3006,7 +3008,7 @@ func (d *AuthenticatedGossiper) handleChanUpdate(nMsg *networkMsg,
30063008
nMsg.err <- err
30073009

30083010
key := newRejectCacheKey(
3009-
upd.ShortChannelID.ToUint64(),
3011+
scid.ToUint64(),
30103012
sourceToPub(nMsg.source),
30113013
)
30123014
_, _ = d.recentRejects.Put(key, &cachedReject{})
@@ -3020,21 +3022,20 @@ func (d *AuthenticatedGossiper) handleChanUpdate(nMsg *networkMsg,
30203022
var (
30213023
pubKey *btcec.PublicKey
30223024
edgeToUpdate models.ChannelEdgePolicy
3025+
direction int
30233026
)
3024-
direction := upd.ChannelFlags & lnwire.ChanUpdateDirection
3025-
switch direction {
3026-
case 0:
3027+
if upd.IsNode1() {
30273028
pubKey, _ = chanInfo.NodeKey1()
30283029
edgeToUpdate = e1
3029-
case 1:
3030+
direction = 0
3031+
} else {
30303032
pubKey, _ = chanInfo.NodeKey2()
30313033
edgeToUpdate = e2
3034+
direction = 1
30323035
}
30333036

3034-
var chanID = chanInfo.GetChanID()
3035-
30363037
log.Debugf("Validating ChannelUpdate1: channel=%v, from node=%x, has "+
3037-
"edge=%v", chanID, pubKey.SerializeCompressed(),
3038+
"edge=%v", chanInfo.GetChanID(), pubKey.SerializeCompressed(),
30383039
edgeToUpdate != nil)
30393040

30403041
// Validate the channel announcement with the expected public key and
@@ -3046,38 +3047,21 @@ func (d *AuthenticatedGossiper) handleChanUpdate(nMsg *networkMsg,
30463047
if err != nil {
30473048
rErr := fmt.Errorf("unable to validate channel update "+
30483049
"announcement for short_chan_id=%v: %v",
3049-
spew.Sdump(upd.ShortChannelID), err)
3050+
spew.Sdump(scid), err)
30503051

30513052
log.Error(rErr)
30523053
nMsg.err <- rErr
30533054
return nil, false
30543055
}
30553056

3056-
var edge *models.ChannelEdgePolicy1
3057-
if edgeToUpdate != nil {
3058-
var ok bool
3059-
edge, ok = edgeToUpdate.(*models.ChannelEdgePolicy1)
3060-
if !ok {
3061-
rErr := fmt.Errorf("expected "+
3062-
"*models.ChannelEdgePolicy1, got: %T",
3063-
edgeToUpdate)
3064-
3065-
log.Error(rErr)
3066-
nMsg.err <- rErr
3067-
3068-
return nil, false
3069-
}
3070-
}
3071-
30723057
// If we have a previous version of the edge being updated, we'll want
30733058
// to rate limit its updates to prevent spam throughout the network.
3074-
if nMsg.isRemote && edge != nil {
3059+
if nMsg.isRemote && edgeToUpdate != nil {
30753060
// If it's a keep-alive update, we'll only propagate one if
30763061
// it's been a day since the previous. This follows our own
30773062
// heuristic of sending keep-alive updates after the same
30783063
// duration (see retransmitStaleAnns).
3079-
timeSinceLastUpdate := timestamp.Sub(edge.LastUpdate)
3080-
isKeepAlive, err := IsKeepAliveUpdate(upd, edge)
3064+
isKeepAlive, err := IsKeepAliveUpdate(upd, edgeToUpdate)
30813065
if err != nil {
30823066
log.Errorf("Could not determine if update is "+
30833067
"keepalive: %v", err)
@@ -3087,7 +3071,18 @@ func (d *AuthenticatedGossiper) handleChanUpdate(nMsg *networkMsg,
30873071
}
30883072

30893073
if isKeepAlive {
3090-
if timeSinceLastUpdate < d.cfg.RebroadcastInterval {
3074+
within, err := d.updateWithinRebroadcastInterval(
3075+
upd, edgeToUpdate,
3076+
)
3077+
if err != nil {
3078+
log.Errorf("Could not determine if update is "+
3079+
"within rebroadcast interval: %v", err)
3080+
nMsg.err <- err
3081+
3082+
return nil, false
3083+
}
3084+
3085+
if !within {
30913086
log.Debugf("Ignoring keep alive update not "+
30923087
"within %v period for channel %v",
30933088
d.cfg.RebroadcastInterval, shortChanID)
@@ -3106,7 +3101,7 @@ func (d *AuthenticatedGossiper) handleChanUpdate(nMsg *networkMsg,
31063101
// multiple aliases for a channel and we may otherwise
31073102
// rate-limit only a single alias of the channel,
31083103
// instead of the whole channel.
3109-
baseScid := chanID
3104+
baseScid := chanInfo.GetChanID()
31103105
d.Lock()
31113106
rls, ok := d.chanUpdateRateLimiter[baseScid]
31123107
if !ok {
@@ -3137,18 +3132,23 @@ func (d *AuthenticatedGossiper) handleChanUpdate(nMsg *networkMsg,
31373132
// different alias. This might mean that SigBytes is incorrect as it
31383133
// signs a different SCID than the database SCID, but since there will
31393134
// only be a difference if AuthProof == nil, this is fine.
3140-
update := &models.ChannelEdgePolicy1{
3141-
SigBytes: upd.Signature.ToSignatureBytes(),
3142-
ChannelID: chanID,
3143-
LastUpdate: timestamp,
3144-
MessageFlags: upd.MessageFlags,
3145-
ChannelFlags: upd.ChannelFlags,
3146-
TimeLockDelta: upd.TimeLockDelta,
3147-
MinHTLC: upd.HtlcMinimumMsat,
3148-
MaxHTLC: upd.HtlcMaximumMsat,
3149-
FeeBaseMSat: lnwire.MilliSatoshi(upd.BaseFee),
3150-
FeeProportionalMillionths: lnwire.MilliSatoshi(upd.FeeRate),
3151-
ExtraOpaqueData: upd.ExtraOpaqueData,
3135+
update, err := models.EdgePolicyFromUpdate(upd)
3136+
if err != nil {
3137+
rErr := fmt.Errorf("unable to convert update to policy for "+
3138+
"short_chan_id=%v: %v", spew.Sdump(scid), err)
3139+
3140+
log.Error(rErr)
3141+
nMsg.err <- rErr
3142+
3143+
return nil, false
3144+
}
3145+
switch upd := update.(type) {
3146+
case *models.ChannelEdgePolicy1:
3147+
upd.ChannelID = chanInfo.GetChanID()
3148+
case *models.ChannelEdgePolicy2:
3149+
upd.ShortChannelID.Val = lnwire.NewShortChanIDFromInt(
3150+
chanInfo.GetChanID(),
3151+
)
31523152
}
31533153

31543154
if err := d.cfg.Router.UpdateEdge(update, ops...); err != nil {
@@ -3164,7 +3164,8 @@ func (d *AuthenticatedGossiper) handleChanUpdate(nMsg *networkMsg,
31643164
// Since we know the stored SCID in the graph, we'll
31653165
// cache that SCID.
31663166
key := newRejectCacheKey(
3167-
chanID, sourceToPub(nMsg.source),
3167+
chanInfo.GetChanID(),
3168+
sourceToPub(nMsg.source),
31683169
)
31693170
_, _ = d.recentRejects.Put(key, &cachedReject{})
31703171

@@ -3173,32 +3174,33 @@ func (d *AuthenticatedGossiper) handleChanUpdate(nMsg *networkMsg,
31733174
}
31743175

31753176
nMsg.err <- err
3177+
31763178
return nil, false
31773179
}
31783180

31793181
// If this is a local ChannelUpdate1 without an AuthProof, it means it
31803182
// is an update to a channel that is not (yet) supposed to be announced
3181-
// to the greater network. However, our channel counter party will need
3183+
// to the greater network. However, our channel counterparty will need
31823184
// to be given the update, so we'll try sending the update directly to
31833185
// the remote peer.
3184-
if !nMsg.isRemote && chanInfo.GetAuthProof() == nil { //nolint:nestif
3185-
if nMsg.optionalMsgFields != nil {
3186+
if !nMsg.isRemote && chanInfo.GetAuthProof() == nil {
3187+
if nMsg.optionalMsgFields != nil &&
3188+
nMsg.optionalMsgFields.remoteAlias != nil {
3189+
3190+
// The remoteAlias field was specified, meaning
3191+
// that we should replace the SCID in the
3192+
// update with the remote's alias. We'll also
3193+
// need to re-sign the channel update. This is
3194+
// required for option-scid-alias feature-bit
3195+
// negotiated channels.
31863196
remoteAlias := nMsg.optionalMsgFields.remoteAlias
3187-
if remoteAlias != nil {
3188-
// The remoteAlias field was specified, meaning
3189-
// that we should replace the SCID in the
3190-
// update with the remote's alias. We'll also
3191-
// need to re-sign the channel update. This is
3192-
// required for option-scid-alias feature-bit
3193-
// negotiated channels.
3194-
upd.ShortChannelID = *remoteAlias
3195-
3196-
err := d.cfg.SignAliasUpdate(upd)
3197-
if err != nil {
3198-
log.Error(err)
3199-
nMsg.err <- err
3200-
return nil, false
3201-
}
3197+
upd.SetSCID(*remoteAlias)
3198+
3199+
err := d.cfg.SignAliasUpdate(upd)
3200+
if err != nil {
3201+
log.Error(err)
3202+
nMsg.err <- err
3203+
return nil, false
32023204
}
32033205
}
32043206

@@ -3215,7 +3217,7 @@ func (d *AuthenticatedGossiper) handleChanUpdate(nMsg *networkMsg,
32153217
if err != nil {
32163218
err := fmt.Errorf("unable to reliably send %v for "+
32173219
"channel=%v to peer=%x: %v", upd.MsgType(),
3218-
upd.ShortChannelID, remotePubKey, err)
3220+
scid, remotePubKey, err)
32193221
nMsg.err <- err
32203222
return nil, false
32213223
}
@@ -3228,7 +3230,7 @@ func (d *AuthenticatedGossiper) handleChanUpdate(nMsg *networkMsg,
32283230
// contains an alias because the network would reject this.
32293231
var announcements []networkMsg
32303232
if chanInfo.GetAuthProof() != nil &&
3231-
!d.cfg.IsAlias(upd.ShortChannelID) {
3233+
!d.cfg.IsAlias(scid) {
32323234

32333235
announcements = append(announcements, networkMsg{
32343236
peer: nMsg.peer,
@@ -3240,9 +3242,9 @@ func (d *AuthenticatedGossiper) handleChanUpdate(nMsg *networkMsg,
32403242

32413243
nMsg.err <- nil
32423244

3243-
log.Debugf("Processed ChannelUpdate1: peer=%v, short_chan_id=%v, "+
3244-
"timestamp=%v", nMsg.peer, upd.ShortChannelID.ToUint64(),
3245-
timestamp)
3245+
log.Debugf("Processed %s: peer=%v, short_chan_id=%v, ", upd.MsgType(),
3246+
nMsg.peer, scid.ToUint64())
3247+
32463248
return announcements, true
32473249
}
32483250

@@ -3669,6 +3671,39 @@ func (d *AuthenticatedGossiper) handleAnnSig(nMsg *networkMsg,
36693671
return announcements, true
36703672
}
36713673

3674+
func (d *AuthenticatedGossiper) updateWithinRebroadcastInterval(
3675+
upd lnwire.ChannelUpdate, policy models.ChannelEdgePolicy) (bool,
3676+
error) {
3677+
3678+
switch update := upd.(type) {
3679+
case *lnwire.ChannelUpdate1:
3680+
pol, ok := policy.(*models.ChannelEdgePolicy1)
3681+
if !ok {
3682+
return false, fmt.Errorf("expected chan edge policy 1")
3683+
}
3684+
3685+
timestamp := time.Unix(int64(update.Timestamp), 0)
3686+
timeSinceLastUpdate := timestamp.Sub(pol.LastUpdate)
3687+
3688+
return timeSinceLastUpdate >= d.cfg.RebroadcastInterval, nil
3689+
3690+
case *lnwire.ChannelUpdate2:
3691+
pol, ok := policy.(*models.ChannelEdgePolicy2)
3692+
if !ok {
3693+
return false, fmt.Errorf("expected chan edge policy 2")
3694+
}
3695+
3696+
blocksSinceLastUpdate := update.BlockHeight.Val -
3697+
pol.BlockHeight.Val
3698+
3699+
return blocksSinceLastUpdate >=
3700+
uint32(d.cfg.RebroadcastInterval.Hours()*6), nil
3701+
3702+
default:
3703+
return false, fmt.Errorf("unhandled impl of Chan Update")
3704+
}
3705+
}
3706+
36723707
func buildChanProof(ann lnwire.ChannelAnnouncement) (
36733708
models.ChannelAuthProof, error) {
36743709

0 commit comments

Comments
 (0)