Skip to content

Commit c76c05b

Browse files
committed
discovery: use ChannelUpdate interface in handleChanUpdate
1 parent d02804a commit c76c05b

File tree

1 file changed

+121
-84
lines changed

1 file changed

+121
-84
lines changed

discovery/gossiper.go

+121-84
Original file line numberDiff line numberDiff line change
@@ -2070,7 +2070,7 @@ func (d *AuthenticatedGossiper) processNetworkAnnouncement(
20702070
// A new authenticated channel edge update has arrived. This indicates
20712071
// that the directional information for an already known channel has
20722072
// been updated.
2073-
case *lnwire.ChannelUpdate1:
2073+
case lnwire.ChannelUpdate:
20742074
return d.handleChanUpdate(nMsg, msg, schedulerOp)
20752075

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

28262826
// handleChanUpdate processes a new channel update.
28272827
func (d *AuthenticatedGossiper) handleChanUpdate(nMsg *networkMsg,
2828-
upd *lnwire.ChannelUpdate1,
2829-
ops []batch.SchedulerOption) ([]networkMsg, bool) {
2828+
upd lnwire.ChannelUpdate, ops []batch.SchedulerOption) ([]networkMsg,
2829+
bool) {
28302830

2831-
log.Debugf("Processing ChannelUpdate1: peer=%v, short_chan_id=%v, ",
2832-
nMsg.peer, upd.ShortChannelID.ToUint64())
2831+
var (
2832+
scid = upd.SCID()
2833+
chainHash = upd.GetChainHash()
2834+
)
2835+
2836+
log.Debugf("Processing ChannelUpdate: peer=%v, short_chan_id=%v, ",
2837+
nMsg.peer, scid)
28332838

28342839
// We'll ignore any channel updates that target any chain other than
28352840
// the set of chains we know of.
2836-
if !bytes.Equal(upd.ChainHash[:], d.cfg.ChainHash[:]) {
2837-
err := fmt.Errorf("ignoring ChannelUpdate1 from chain=%v, "+
2838-
"gossiper on chain=%v", upd.ChainHash, d.cfg.ChainHash)
2841+
if !bytes.Equal(chainHash[:], d.cfg.ChainHash[:]) {
2842+
err := fmt.Errorf("ignoring %s from chain=%v, "+
2843+
"gossiper on chain=%v", upd.MsgType(), chainHash,
2844+
d.cfg.ChainHash)
28392845
log.Errorf(err.Error())
28402846

28412847
key := newRejectCacheKey(
2842-
upd.ShortChannelID.ToUint64(),
2843-
sourceToPub(nMsg.source),
2848+
scid.ToUint64(), sourceToPub(nMsg.source),
28442849
)
28452850
_, _ = d.recentRejects.Put(key, &cachedReject{})
28462851

28472852
nMsg.err <- err
28482853
return nil, false
28492854
}
28502855

2851-
blockHeight := upd.ShortChannelID.BlockHeight
2852-
shortChanID := upd.ShortChannelID.ToUint64()
2856+
blockHeight := upd.SCID().BlockHeight
2857+
shortChanID := upd.SCID().ToUint64()
28532858

28542859
// If the advertised inclusionary block is beyond our knowledge of the
28552860
// chain tip, then we'll put the announcement in limbo to be fully
28562861
// verified once we advance forward in the chain. If the update has an
28572862
// alias SCID, we'll skip the isPremature check. This is necessary
28582863
// since aliases start at block height 16_000_000.
28592864
d.Lock()
2860-
if nMsg.isRemote && !d.cfg.IsAlias(upd.ShortChannelID) &&
2861-
d.isPremature(upd.ShortChannelID, 0, nMsg) {
2865+
if nMsg.isRemote && !d.cfg.IsAlias(scid) &&
2866+
d.isPremature(scid, 0, nMsg) {
28622867

28632868
log.Warnf("Update announcement for short_chan_id(%v), is "+
28642869
"premature: advertises height %v, only height %v is "+
@@ -2869,31 +2874,28 @@ func (d *AuthenticatedGossiper) handleChanUpdate(nMsg *networkMsg,
28692874
}
28702875
d.Unlock()
28712876

2872-
// Before we perform any of the expensive checks below, we'll check
2873-
// whether this update is stale or is for a zombie channel in order to
2874-
// quickly reject it.
2875-
timestamp := time.Unix(int64(upd.Timestamp), 0)
2876-
28772877
// Fetch the SCID we should be using to lock the channelMtx and make
28782878
// graph queries with.
2879-
graphScid, err := d.cfg.FindBaseByAlias(upd.ShortChannelID)
2879+
graphScid, err := d.cfg.FindBaseByAlias(scid)
28802880
if err != nil {
28812881
// Fallback and set the graphScid to the peer-provided SCID.
28822882
// This will occur for non-option-scid-alias channels and for
28832883
// public option-scid-alias channels after 6 confirmations.
28842884
// Once public option-scid-alias channels have 6 confs, we'll
28852885
// ignore ChannelUpdates with one of their aliases.
2886-
graphScid = upd.ShortChannelID
2886+
graphScid = scid
28872887
}
28882888

2889+
// Before we perform any of the expensive checks below, we'll check
2890+
// whether this update is stale or is for a zombie channel in order to
2891+
// quickly reject it.
28892892
if d.cfg.Router.IsStaleEdgePolicy(graphScid, upd) {
28902893
log.Debugf("Ignored stale edge policy for short_chan_id(%v): "+
28912894
"peer=%v, msg=%s, is_remote=%v", shortChanID,
28922895
nMsg.peer, nMsg.msg.MsgType(), nMsg.isRemote,
28932896
)
28942897

28952898
nMsg.err <- nil
2896-
28972899
return nil, true
28982900
}
28992901

@@ -2935,7 +2937,7 @@ func (d *AuthenticatedGossiper) handleChanUpdate(nMsg *networkMsg,
29352937
// If the edge corresponding to this ChannelUpdate1 was not
29362938
// found in the graph, this might be a channel in the process
29372939
// of being opened, and we haven't processed our own
2938-
// ChannelAnnouncement1 yet, hence it is not found in the
2940+
// ChannelAnnouncement yet, hence it is not found in the
29392941
// graph. This usually gets resolved after the channel proofs
29402942
// are exchanged and the channel is broadcasted to the rest of
29412943
// the network, but in case this is a private channel this
@@ -2972,7 +2974,7 @@ func (d *AuthenticatedGossiper) handleChanUpdate(nMsg *networkMsg,
29722974
})
29732975
}
29742976

2975-
log.Debugf("Got ChannelUpdate1 for edge not found in graph"+
2977+
log.Debugf("Got ChannelUpdate for edge not found in graph"+
29762978
"(shortChanID=%v), saving for reprocessing later",
29772979
shortChanID)
29782980

@@ -2988,7 +2990,7 @@ func (d *AuthenticatedGossiper) handleChanUpdate(nMsg *networkMsg,
29882990
nMsg.err <- err
29892991

29902992
key := newRejectCacheKey(
2991-
upd.ShortChannelID.ToUint64(),
2993+
scid.ToUint64(),
29922994
sourceToPub(nMsg.source),
29932995
)
29942996
_, _ = d.recentRejects.Put(key, &cachedReject{})
@@ -3002,21 +3004,20 @@ func (d *AuthenticatedGossiper) handleChanUpdate(nMsg *networkMsg,
30023004
var (
30033005
pubKey *btcec.PublicKey
30043006
edgeToUpdate models.ChannelEdgePolicy
3007+
direction int
30053008
)
3006-
direction := upd.ChannelFlags & lnwire.ChanUpdateDirection
3007-
switch direction {
3008-
case 0:
3009+
if upd.IsNode1() {
30093010
pubKey, _ = chanInfo.NodeKey1()
30103011
edgeToUpdate = e1
3011-
case 1:
3012+
direction = 0
3013+
} else {
30123014
pubKey, _ = chanInfo.NodeKey2()
30133015
edgeToUpdate = e2
3016+
direction = 1
30143017
}
30153018

3016-
var chanID = chanInfo.GetChanID()
3017-
30183019
log.Debugf("Validating ChannelUpdate1: channel=%v, from node=%x, has "+
3019-
"edge=%v", chanID, pubKey.SerializeCompressed(),
3020+
"edge=%v", chanInfo.GetChanID(), pubKey.SerializeCompressed(),
30203021
edgeToUpdate != nil)
30213022

30223023
// Validate the channel announcement with the expected public key and
@@ -3028,7 +3029,7 @@ func (d *AuthenticatedGossiper) handleChanUpdate(nMsg *networkMsg,
30283029
if err != nil {
30293030
rErr := fmt.Errorf("unable to validate channel update "+
30303031
"announcement for short_chan_id=%v: %v",
3031-
spew.Sdump(upd.ShortChannelID), err)
3032+
spew.Sdump(scid), err)
30323033

30333034
log.Error(rErr)
30343035
nMsg.err <- rErr
@@ -3038,24 +3039,11 @@ func (d *AuthenticatedGossiper) handleChanUpdate(nMsg *networkMsg,
30383039
// If we have a previous version of the edge being updated, we'll want
30393040
// to rate limit its updates to prevent spam throughout the network.
30403041
if nMsg.isRemote && edgeToUpdate != nil {
3041-
edge, ok := edgeToUpdate.(*models.ChannelEdgePolicy1)
3042-
if !ok {
3043-
rErr := fmt.Errorf("expected "+
3044-
"*models.ChannelEdgePolicy1, got: %T",
3045-
edgeToUpdate)
3046-
3047-
log.Error(rErr)
3048-
nMsg.err <- rErr
3049-
3050-
return nil, false
3051-
}
3052-
30533042
// If it's a keep-alive update, we'll only propagate one if
30543043
// it's been a day since the previous. This follows our own
30553044
// heuristic of sending keep-alive updates after the same
30563045
// duration (see retransmitStaleAnns).
3057-
timeSinceLastUpdate := timestamp.Sub(edge.LastUpdate)
3058-
isKeepAlive, err := IsKeepAliveUpdate(upd, edge)
3046+
isKeepAlive, err := IsKeepAliveUpdate(upd, edgeToUpdate)
30593047
if err != nil {
30603048
log.Errorf("Could not determine if update is "+
30613049
"keepalive: %v", err)
@@ -3065,7 +3053,18 @@ func (d *AuthenticatedGossiper) handleChanUpdate(nMsg *networkMsg,
30653053
}
30663054

30673055
if isKeepAlive {
3068-
if timeSinceLastUpdate < d.cfg.RebroadcastInterval {
3056+
within, err := d.updateWithinRebroadcastInterval(
3057+
upd, edgeToUpdate,
3058+
)
3059+
if err != nil {
3060+
log.Errorf("Could not determine if update is "+
3061+
"within rebroadcast interval: %v", err)
3062+
nMsg.err <- err
3063+
3064+
return nil, false
3065+
}
3066+
3067+
if !within {
30693068
log.Debugf("Ignoring keep alive update not "+
30703069
"within %v period for channel %v",
30713070
d.cfg.RebroadcastInterval, shortChanID)
@@ -3084,7 +3083,7 @@ func (d *AuthenticatedGossiper) handleChanUpdate(nMsg *networkMsg,
30843083
// multiple aliases for a channel and we may otherwise
30853084
// rate-limit only a single alias of the channel,
30863085
// instead of the whole channel.
3087-
baseScid := chanID
3086+
baseScid := chanInfo.GetChanID()
30883087
d.Lock()
30893088
rls, ok := d.chanUpdateRateLimiter[baseScid]
30903089
if !ok {
@@ -3115,18 +3114,22 @@ func (d *AuthenticatedGossiper) handleChanUpdate(nMsg *networkMsg,
31153114
// different alias. This might mean that SigBytes is incorrect as it
31163115
// signs a different SCID than the database SCID, but since there will
31173116
// only be a difference if AuthProof == nil, this is fine.
3118-
update := &models.ChannelEdgePolicy1{
3119-
SigBytes: upd.Signature.ToSignatureBytes(),
3120-
ChannelID: chanID,
3121-
LastUpdate: timestamp,
3122-
MessageFlags: upd.MessageFlags,
3123-
ChannelFlags: upd.ChannelFlags,
3124-
TimeLockDelta: upd.TimeLockDelta,
3125-
MinHTLC: upd.HtlcMinimumMsat,
3126-
MaxHTLC: upd.HtlcMaximumMsat,
3127-
FeeBaseMSat: lnwire.MilliSatoshi(upd.BaseFee),
3128-
FeeProportionalMillionths: lnwire.MilliSatoshi(upd.FeeRate),
3129-
ExtraOpaqueData: upd.ExtraOpaqueData,
3117+
update, err := models.EdgePolicyFromUpdate(upd)
3118+
if err != nil {
3119+
rErr := fmt.Errorf("unable to convert update to policy for "+
3120+
"short_chan_id=%v: %v", spew.Sdump(scid), err)
3121+
3122+
log.Error(rErr)
3123+
nMsg.err <- rErr
3124+
return nil, false
3125+
}
3126+
switch upd := update.(type) {
3127+
case *models.ChannelEdgePolicy1:
3128+
upd.ChannelID = chanInfo.GetChanID()
3129+
case *models.ChannelEdgePolicy2:
3130+
upd.ShortChannelID = lnwire.NewShortChanIDFromInt(
3131+
chanInfo.GetChanID(),
3132+
)
31303133
}
31313134

31323135
if err := d.cfg.Router.UpdateEdge(update, ops...); err != nil {
@@ -3142,7 +3145,8 @@ func (d *AuthenticatedGossiper) handleChanUpdate(nMsg *networkMsg,
31423145
// Since we know the stored SCID in the graph, we'll
31433146
// cache that SCID.
31443147
key := newRejectCacheKey(
3145-
chanID, sourceToPub(nMsg.source),
3148+
chanInfo.GetChanID(),
3149+
sourceToPub(nMsg.source),
31463150
)
31473151
_, _ = d.recentRejects.Put(key, &cachedReject{})
31483152

@@ -3151,32 +3155,33 @@ func (d *AuthenticatedGossiper) handleChanUpdate(nMsg *networkMsg,
31513155
}
31523156

31533157
nMsg.err <- err
3158+
31543159
return nil, false
31553160
}
31563161

31573162
// If this is a local ChannelUpdate1 without an AuthProof, it means it
31583163
// is an update to a channel that is not (yet) supposed to be announced
3159-
// to the greater network. However, our channel counter party will need
3164+
// to the greater network. However, our channel counterparty will need
31603165
// to be given the update, so we'll try sending the update directly to
31613166
// the remote peer.
31623167
if !nMsg.isRemote && chanInfo.GetAuthProof() == nil {
3163-
if nMsg.optionalMsgFields != nil {
3168+
if nMsg.optionalMsgFields != nil &&
3169+
nMsg.optionalMsgFields.remoteAlias != nil {
3170+
3171+
// The remoteAlias field was specified, meaning
3172+
// that we should replace the SCID in the
3173+
// update with the remote's alias. We'll also
3174+
// need to re-sign the channel update. This is
3175+
// required for option-scid-alias feature-bit
3176+
// negotiated channels.
31643177
remoteAlias := nMsg.optionalMsgFields.remoteAlias
3165-
if remoteAlias != nil {
3166-
// The remoteAlias field was specified, meaning
3167-
// that we should replace the SCID in the
3168-
// update with the remote's alias. We'll also
3169-
// need to re-sign the channel update. This is
3170-
// required for option-scid-alias feature-bit
3171-
// negotiated channels.
3172-
upd.ShortChannelID = *remoteAlias
3173-
3174-
err := d.cfg.SignAliasUpdate(upd)
3175-
if err != nil {
3176-
log.Error(err)
3177-
nMsg.err <- err
3178-
return nil, false
3179-
}
3178+
upd.SetSCID(*remoteAlias)
3179+
3180+
err := d.cfg.SignAliasUpdate(upd)
3181+
if err != nil {
3182+
log.Error(err)
3183+
nMsg.err <- err
3184+
return nil, false
31803185
}
31813186
}
31823187

@@ -3193,7 +3198,7 @@ func (d *AuthenticatedGossiper) handleChanUpdate(nMsg *networkMsg,
31933198
if err != nil {
31943199
err := fmt.Errorf("unable to reliably send %v for "+
31953200
"channel=%v to peer=%x: %v", upd.MsgType(),
3196-
upd.ShortChannelID, remotePubKey, err)
3201+
scid, remotePubKey, err)
31973202
nMsg.err <- err
31983203
return nil, false
31993204
}
@@ -3206,7 +3211,7 @@ func (d *AuthenticatedGossiper) handleChanUpdate(nMsg *networkMsg,
32063211
// contains an alias because the network would reject this.
32073212
var announcements []networkMsg
32083213
if chanInfo.GetAuthProof() != nil &&
3209-
!d.cfg.IsAlias(upd.ShortChannelID) {
3214+
!d.cfg.IsAlias(scid) {
32103215

32113216
announcements = append(announcements, networkMsg{
32123217
peer: nMsg.peer,
@@ -3218,9 +3223,9 @@ func (d *AuthenticatedGossiper) handleChanUpdate(nMsg *networkMsg,
32183223

32193224
nMsg.err <- nil
32203225

3221-
log.Debugf("Processed ChannelUpdate1: peer=%v, short_chan_id=%v, "+
3222-
"timestamp=%v", nMsg.peer, upd.ShortChannelID.ToUint64(),
3223-
timestamp)
3226+
log.Debugf("Processed %s: peer=%v, short_chan_id=%v, ", upd.MsgType(),
3227+
nMsg.peer, scid.ToUint64())
3228+
32243229
return announcements, true
32253230
}
32263231

@@ -3646,6 +3651,38 @@ func (d *AuthenticatedGossiper) handleAnnSig(nMsg *networkMsg,
36463651
return announcements, true
36473652
}
36483653

3654+
func (d *AuthenticatedGossiper) updateWithinRebroadcastInterval(
3655+
upd lnwire.ChannelUpdate, policy models.ChannelEdgePolicy) (bool,
3656+
error) {
3657+
3658+
switch update := upd.(type) {
3659+
case *lnwire.ChannelUpdate1:
3660+
pol, ok := policy.(*models.ChannelEdgePolicy1)
3661+
if !ok {
3662+
return false, fmt.Errorf("expected chan edge policy 1")
3663+
}
3664+
3665+
timestamp := time.Unix(int64(update.Timestamp), 0)
3666+
timeSinceLastUpdate := timestamp.Sub(pol.LastUpdate)
3667+
3668+
return timeSinceLastUpdate >= d.cfg.RebroadcastInterval, nil
3669+
3670+
case *lnwire.ChannelUpdate2:
3671+
pol, ok := policy.(*models.ChannelEdgePolicy2)
3672+
if !ok {
3673+
return false, fmt.Errorf("expected chan edge policy 2")
3674+
}
3675+
3676+
blocksSinceLastUpdate := update.BlockHeight - pol.BlockHeight
3677+
3678+
return blocksSinceLastUpdate >=
3679+
uint32(d.cfg.RebroadcastInterval.Hours()*6), nil
3680+
3681+
default:
3682+
return false, fmt.Errorf("unhandled impl of Chan Update")
3683+
}
3684+
}
3685+
36493686
func buildChanProof(ann lnwire.ChannelAnnouncement) (
36503687
models.ChannelAuthProof, error) {
36513688

0 commit comments

Comments
 (0)