Skip to content

Commit dbe4ca3

Browse files
committed
Merge branch '0-18-3-branch-9011' into 0-18-3-branch
2 parents 53799e9 + 4102e33 commit dbe4ca3

File tree

7 files changed

+228
-39
lines changed

7 files changed

+228
-39
lines changed

channeldb/graph.go

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2143,6 +2143,21 @@ func (c *ChannelGraph) FilterKnownChanIDs(chansInfo []ChannelUpdateInfo,
21432143
zombieIndex, scid,
21442144
)
21452145

2146+
// TODO(ziggie): Make sure that for the strict
2147+
// pruning case we compare the pubkeys and
2148+
// whether the right timestamp is not older than
2149+
// the `ChannelPruneExpiry`.
2150+
//
2151+
// NOTE: The timestamp data has no verification
2152+
// attached to it in the `ReplyChannelRange` msg
2153+
// so we are trusting this data at this point.
2154+
// However it is not critical because we are
2155+
// just removing the channel from the db when
2156+
// the timestamps are more recent. During the
2157+
// querying of the gossip msg verification
2158+
// happens as usual.
2159+
// However we should start punishing peers when
2160+
// they don't provide us honest data ?
21462161
isStillZombie := isZombieChan(
21472162
info.Node1UpdateTimestamp,
21482163
info.Node2UpdateTimestamp,
@@ -2211,6 +2226,29 @@ type ChannelUpdateInfo struct {
22112226
Node2UpdateTimestamp time.Time
22122227
}
22132228

2229+
// NewChannelUpdateInfo is a constructor which makes sure we initialize the
2230+
// timestamps with zero seconds unix timestamp which equals
2231+
// `January 1, 1970, 00:00:00 UTC` in case the value is `time.Time{}`.
2232+
func NewChannelUpdateInfo(scid lnwire.ShortChannelID, node1Timestamp,
2233+
node2Timestamp time.Time) ChannelUpdateInfo {
2234+
2235+
chanInfo := ChannelUpdateInfo{
2236+
ShortChannelID: scid,
2237+
Node1UpdateTimestamp: node1Timestamp,
2238+
Node2UpdateTimestamp: node2Timestamp,
2239+
}
2240+
2241+
if node1Timestamp.IsZero() {
2242+
chanInfo.Node1UpdateTimestamp = time.Unix(0, 0)
2243+
}
2244+
2245+
if node2Timestamp.IsZero() {
2246+
chanInfo.Node2UpdateTimestamp = time.Unix(0, 0)
2247+
}
2248+
2249+
return chanInfo
2250+
}
2251+
22142252
// BlockChannelRange represents a range of channels for a given block height.
22152253
type BlockChannelRange struct {
22162254
// Height is the height of the block all of the channels below were
@@ -2284,9 +2322,9 @@ func (c *ChannelGraph) FilterChannelRange(startHeight,
22842322
rawCid := byteOrder.Uint64(k)
22852323
cid := lnwire.NewShortChanIDFromInt(rawCid)
22862324

2287-
chanInfo := ChannelUpdateInfo{
2288-
ShortChannelID: cid,
2289-
}
2325+
chanInfo := NewChannelUpdateInfo(
2326+
cid, time.Time{}, time.Time{},
2327+
)
22902328

22912329
if !withTimestamps {
22922330
channelsPerBlock[cid.BlockHeight] = append(

channeldb/graph_test.go

Lines changed: 39 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1980,9 +1980,9 @@ func TestFilterKnownChanIDs(t *testing.T) {
19801980
t.Fatalf("unable to create channel edge: %v", err)
19811981
}
19821982

1983-
chanIDs = append(chanIDs, ChannelUpdateInfo{
1984-
ShortChannelID: chanID,
1985-
})
1983+
chanIDs = append(chanIDs, NewChannelUpdateInfo(
1984+
chanID, time.Time{}, time.Time{},
1985+
))
19861986
}
19871987

19881988
const numZombies = 5
@@ -2024,20 +2024,28 @@ func TestFilterKnownChanIDs(t *testing.T) {
20242024
// should get the same set back.
20252025
{
20262026
queryIDs: []ChannelUpdateInfo{
2027-
{ShortChannelID: lnwire.ShortChannelID{
2028-
BlockHeight: 99,
2029-
}},
2030-
{ShortChannelID: lnwire.ShortChannelID{
2031-
BlockHeight: 100,
2032-
}},
2027+
{
2028+
ShortChannelID: lnwire.ShortChannelID{
2029+
BlockHeight: 99,
2030+
},
2031+
},
2032+
{
2033+
ShortChannelID: lnwire.ShortChannelID{
2034+
BlockHeight: 100,
2035+
},
2036+
},
20332037
},
20342038
resp: []ChannelUpdateInfo{
2035-
{ShortChannelID: lnwire.ShortChannelID{
2036-
BlockHeight: 99,
2037-
}},
2038-
{ShortChannelID: lnwire.ShortChannelID{
2039-
BlockHeight: 100,
2040-
}},
2039+
{
2040+
ShortChannelID: lnwire.ShortChannelID{
2041+
BlockHeight: 99,
2042+
},
2043+
},
2044+
{
2045+
ShortChannelID: lnwire.ShortChannelID{
2046+
BlockHeight: 100,
2047+
},
2048+
},
20412049
},
20422050
},
20432051

@@ -2419,7 +2427,7 @@ func TestFilterChannelRange(t *testing.T) {
24192427
)
24202428
)
24212429

2422-
updateTimeSeed := int64(1)
2430+
updateTimeSeed := time.Now().Unix()
24232431
maybeAddPolicy := func(chanID uint64, node *LightningNode,
24242432
node2 bool) time.Time {
24252433

@@ -2428,7 +2436,7 @@ func TestFilterChannelRange(t *testing.T) {
24282436
chanFlags = lnwire.ChanUpdateDirection
24292437
}
24302438

2431-
var updateTime time.Time
2439+
var updateTime = time.Unix(0, 0)
24322440
if rand.Int31n(2) == 0 {
24332441
updateTime = time.Unix(updateTimeSeed, 0)
24342442
err = graph.UpdateEdgePolicy(&models.ChannelEdgePolicy{
@@ -2456,11 +2464,16 @@ func TestFilterChannelRange(t *testing.T) {
24562464
)
24572465
require.NoError(t, graph.AddChannelEdge(&channel2))
24582466

2467+
chanInfo1 := NewChannelUpdateInfo(
2468+
chanID1, time.Time{}, time.Time{},
2469+
)
2470+
chanInfo2 := NewChannelUpdateInfo(
2471+
chanID2, time.Time{}, time.Time{},
2472+
)
24592473
channelRanges = append(channelRanges, BlockChannelRange{
24602474
Height: chanHeight,
24612475
Channels: []ChannelUpdateInfo{
2462-
{ShortChannelID: chanID1},
2463-
{ShortChannelID: chanID2},
2476+
chanInfo1, chanInfo2,
24642477
},
24652478
})
24662479

@@ -2471,20 +2484,17 @@ func TestFilterChannelRange(t *testing.T) {
24712484
time4 = maybeAddPolicy(channel2.ChannelID, node2, true)
24722485
)
24732486

2487+
chanInfo1 = NewChannelUpdateInfo(
2488+
chanID1, time1, time2,
2489+
)
2490+
chanInfo2 = NewChannelUpdateInfo(
2491+
chanID2, time3, time4,
2492+
)
24742493
channelRangesWithTimestamps = append(
24752494
channelRangesWithTimestamps, BlockChannelRange{
24762495
Height: chanHeight,
24772496
Channels: []ChannelUpdateInfo{
2478-
{
2479-
ShortChannelID: chanID1,
2480-
Node1UpdateTimestamp: time1,
2481-
Node2UpdateTimestamp: time2,
2482-
},
2483-
{
2484-
ShortChannelID: chanID2,
2485-
Node1UpdateTimestamp: time3,
2486-
Node2UpdateTimestamp: time4,
2487-
},
2497+
chanInfo1, chanInfo2,
24882498
},
24892499
},
24902500
)

discovery/gossiper.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2745,6 +2745,22 @@ func (d *AuthenticatedGossiper) handleChanUpdate(nMsg *networkMsg,
27452745
return nil, true
27462746
}
27472747

2748+
// Check that the ChanUpdate is not too far into the future, this could
2749+
// reveal some faulty implementation therefore we log an error.
2750+
if time.Until(timestamp) > graph.DefaultChannelPruneExpiry {
2751+
log.Errorf("Skewed timestamp (%v) for edge policy of "+
2752+
"short_chan_id(%v), timestamp too far in the future: "+
2753+
"peer=%v, msg=%s, is_remote=%v", timestamp.Unix(),
2754+
shortChanID, nMsg.peer, nMsg.msg.MsgType(),
2755+
nMsg.isRemote,
2756+
)
2757+
2758+
nMsg.err <- fmt.Errorf("skewed timestamp of edge policy, "+
2759+
"timestamp too far in the future: %v", timestamp.Unix())
2760+
2761+
return nil, false
2762+
}
2763+
27482764
// Get the node pub key as far since we don't have it in the channel
27492765
// update announcement message. We'll need this to properly verify the
27502766
// message's signature.

discovery/sync_manager.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -561,7 +561,7 @@ func (m *SyncManager) removeGossipSyncer(peer route.Vertex) {
561561
return
562562
}
563563

564-
log.Debugf("Replaced active GossipSyncer(%x) with GossipSyncer(%x)",
564+
log.Debugf("Replaced active GossipSyncer(%v) with GossipSyncer(%x)",
565565
peer, newActiveSyncer.cfg.peerPub)
566566
}
567567

discovery/syncer.go

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212

1313
"github.com/btcsuite/btcd/chaincfg/chainhash"
1414
"github.com/lightningnetwork/lnd/channeldb"
15+
"github.com/lightningnetwork/lnd/graph"
1516
"github.com/lightningnetwork/lnd/lnpeer"
1617
"github.com/lightningnetwork/lnd/lnwire"
1718
"golang.org/x/time/rate"
@@ -787,6 +788,16 @@ func isLegacyReplyChannelRange(query *lnwire.QueryChannelRange,
787788
// reply to the initial range query to discover new channels that it didn't
788789
// previously know of.
789790
func (g *GossipSyncer) processChanRangeReply(msg *lnwire.ReplyChannelRange) error {
791+
// isStale returns whether the timestamp is too far into the past.
792+
isStale := func(timestamp time.Time) bool {
793+
return time.Since(timestamp) > graph.DefaultChannelPruneExpiry
794+
}
795+
796+
// isSkewed returns whether the timestamp is too far into the future.
797+
isSkewed := func(timestamp time.Time) bool {
798+
return time.Until(timestamp) > graph.DefaultChannelPruneExpiry
799+
}
800+
790801
// If we're not communicating with a legacy node, we'll apply some
791802
// further constraints on their reply to ensure it satisfies our query.
792803
if !isLegacyReplyChannelRange(g.curQueryRangeMsg, msg) {
@@ -838,16 +849,42 @@ func (g *GossipSyncer) processChanRangeReply(msg *lnwire.ReplyChannelRange) erro
838849
}
839850

840851
for i, scid := range msg.ShortChanIDs {
841-
info := channeldb.ChannelUpdateInfo{
842-
ShortChannelID: scid,
843-
}
852+
info := channeldb.NewChannelUpdateInfo(
853+
scid, time.Time{}, time.Time{},
854+
)
844855

845856
if len(msg.Timestamps) != 0 {
846857
t1 := time.Unix(int64(msg.Timestamps[i].Timestamp1), 0)
847858
info.Node1UpdateTimestamp = t1
848859

849860
t2 := time.Unix(int64(msg.Timestamps[i].Timestamp2), 0)
850861
info.Node2UpdateTimestamp = t2
862+
863+
// Sort out all channels with outdated or skewed
864+
// timestamps. Both timestamps need to be out of
865+
// boundaries for us to skip the channel and not query
866+
// it later on.
867+
switch {
868+
case isStale(info.Node1UpdateTimestamp) &&
869+
isStale(info.Node2UpdateTimestamp):
870+
871+
continue
872+
873+
case isSkewed(info.Node1UpdateTimestamp) &&
874+
isSkewed(info.Node2UpdateTimestamp):
875+
876+
continue
877+
878+
case isStale(info.Node1UpdateTimestamp) &&
879+
isSkewed(info.Node2UpdateTimestamp):
880+
881+
continue
882+
883+
case isStale(info.Node2UpdateTimestamp) &&
884+
isSkewed(info.Node1UpdateTimestamp):
885+
886+
continue
887+
}
851888
}
852889

853890
g.bufferedChanRangeReplies = append(

0 commit comments

Comments
 (0)