From d3cf3168d2406413c1876052911f44b2a6d653d3 Mon Sep 17 00:00:00 2001 From: Wilmer Paulino Date: Tue, 4 Sep 2018 18:36:25 -0700 Subject: [PATCH 1/2] channeldb/graph_test: ensure policies for an edge have different timestamps In this commit, we ensure policies for edges we create in TestChanUpdatesInHorizon have different update timestamps. This ensures that there are two entries per edge in the edge update index. Because of this, the test will fail because ChanUpdatesInHorizon will return duplicate channel edges due to looking at all the entries within the edge update index. This will be addressed in a future commit to allow the set of tests to pass once again. --- channeldb/graph_test.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/channeldb/graph_test.go b/channeldb/graph_test.go index 56b4dd382..040ec4b4d 100644 --- a/channeldb/graph_test.go +++ b/channeldb/graph_test.go @@ -1398,11 +1398,12 @@ func TestChanUpdatesInHorizon(t *testing.T) { t.Fatalf("unable to create channel edge: %v", err) } - updateTime := endTime - endTime = updateTime.Add(time.Second * 10) + edge1UpdateTime := endTime + edge2UpdateTime := edge1UpdateTime.Add(time.Second) + endTime = endTime.Add(time.Second * 10) edge1 := newEdgePolicy( - chanID.ToUint64(), op, db, updateTime.Unix(), + chanID.ToUint64(), op, db, edge1UpdateTime.Unix(), ) edge1.Flags = 0 edge1.Node = node2 @@ -1412,7 +1413,7 @@ func TestChanUpdatesInHorizon(t *testing.T) { } edge2 := newEdgePolicy( - chanID.ToUint64(), op, db, updateTime.Unix(), + chanID.ToUint64(), op, db, edge2UpdateTime.Unix(), ) edge2.Flags = 1 edge2.Node = node1 From 3f58c2dea4ca532001058fe69cef01215b738b7f Mon Sep 17 00:00:00 2001 From: Wilmer Paulino Date: Tue, 4 Sep 2018 18:39:23 -0700 Subject: [PATCH 2/2] channeldb/graph: dedup channel edges returned from ChanUpdatesInHorizon In this commit, we ensure that we de-duplicate the set of channel edges returned from ChanUpdatesInHorizon. Other subsystems within lnd use this method to retrieve and send all the channels with updates within a time series to network peers. However, since the method looks at the edge update index, which can include up to two entries per edge for each policy, it's possible that we'd send channel announcements and updates twice, causing extra bandwidth. --- channeldb/graph.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/channeldb/graph.go b/channeldb/graph.go index dc481cf7c..0872d686a 100644 --- a/channeldb/graph.go +++ b/channeldb/graph.go @@ -1176,6 +1176,10 @@ type ChannelEdge struct { // ChanUpdatesInHorizon returns all the known channel edges which have at least // one edge that has an update timestamp within the specified horizon. func (c *ChannelGraph) ChanUpdatesInHorizon(startTime, endTime time.Time) ([]ChannelEdge, error) { + // To ensure we don't return duplicate ChannelEdges, we'll use an + // additional map to keep track of the edges already seen to prevent + // re-adding it. + edgesSeen := make(map[uint64]struct{}) var edgesInHorizon []ChannelEdge err := c.db.View(func(tx *bolt.Tx) error { @@ -1219,6 +1223,14 @@ func (c *ChannelGraph) ChanUpdatesInHorizon(startTime, endTime time.Time) ([]Cha // chan ID so we can query it in the DB. chanID := indexKey[8:] + // If we've already retrieved the info and policies for + // this edge, then we can skip it as we don't need to do + // so again. + chanIDInt := byteOrder.Uint64(chanID) + if _, ok := edgesSeen[chanIDInt]; ok { + continue + } + // First, we'll fetch the static edge information. edgeInfo, err := fetchChanEdgeInfo(edgeIndex, chanID) if err != nil { @@ -1237,6 +1249,7 @@ func (c *ChannelGraph) ChanUpdatesInHorizon(startTime, endTime time.Time) ([]Cha // Finally, we'll collate this edge with the rest of // edges to be returned. + edgesSeen[chanIDInt] = struct{}{} edgesInHorizon = append(edgesInHorizon, ChannelEdge{ Info: &edgeInfo, Policy1: edge1,