Skip to content

Commit 352008a

Browse files
committed
channeldb: speed up graph cache loading
Use the optimized ForEachChannel method to reduce the graph cache loading time.
1 parent 2e2229a commit 352008a

File tree

3 files changed

+110
-10
lines changed

3 files changed

+110
-10
lines changed

channeldb/graph.go

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,15 +216,29 @@ func NewChannelGraph(db kvdb.Backend, rejectCacheSize, chanCacheSize int,
216216
startTime := time.Now()
217217
log.Debugf("Populating in-memory channel graph, this might " +
218218
"take a while...")
219+
219220
err := g.ForEachNodeCacheable(
220221
func(tx kvdb.RTx, node GraphCacheNode) error {
221-
return g.graphCache.AddNode(tx, node)
222+
g.graphCache.AddNodeFeatures(node)
223+
224+
return nil
222225
},
223226
)
224227
if err != nil {
225228
return nil, err
226229
}
227230

231+
err = g.ForEachChannel(func(info *ChannelEdgeInfo,
232+
policy1, policy2 *ChannelEdgePolicy) error {
233+
234+
g.graphCache.AddChannel(info, policy1, policy2)
235+
236+
return nil
237+
})
238+
if err != nil {
239+
return nil, err
240+
}
241+
228242
log.Debugf("Finished populating in-memory channel graph (took "+
229243
"%v, %s)", time.Since(startTime), g.graphCache.Stats())
230244
}

channeldb/graph_test.go

Lines changed: 90 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1207,11 +1207,22 @@ func TestGraphTraversalCacheable(t *testing.T) {
12071207
// Iterate through all the known channels within the graph DB by
12081208
// iterating over each node, once again if the map is empty that
12091209
// indicates that all edges have properly been reached.
1210+
var nodes []GraphCacheNode
12101211
err = graph.ForEachNodeCacheable(
12111212
func(tx kvdb.RTx, node GraphCacheNode) error {
12121213
delete(nodeMap, node.PubKey())
12131214

1214-
return node.ForEachChannel(
1215+
nodes = append(nodes, node)
1216+
1217+
return nil
1218+
},
1219+
)
1220+
require.NoError(t, err)
1221+
require.Len(t, nodeMap, 0)
1222+
1223+
err = graph.db.View(func(tx kvdb.RTx) error {
1224+
for _, node := range nodes {
1225+
err := node.ForEachChannel(
12151226
tx, func(tx kvdb.RTx, info *ChannelEdgeInfo,
12161227
policy *ChannelEdgePolicy,
12171228
policy2 *ChannelEdgePolicy) error {
@@ -1220,10 +1231,15 @@ func TestGraphTraversalCacheable(t *testing.T) {
12201231
return nil
12211232
},
12221233
)
1223-
},
1224-
)
1234+
if err != nil {
1235+
return err
1236+
}
1237+
}
1238+
1239+
return nil
1240+
}, func() {})
1241+
12251242
require.NoError(t, err)
1226-
require.Len(t, nodeMap, 0)
12271243
require.Len(t, chanIndex, 0)
12281244
}
12291245

@@ -3695,9 +3711,20 @@ func BenchmarkForEachChannel(b *testing.B) {
36953711
totalCapacity btcutil.Amount
36963712
maxHTLCs lnwire.MilliSatoshi
36973713
)
3698-
err := graph.ForEachNodeCacheable(
3699-
func(tx kvdb.RTx, n GraphCacheNode) error {
3700-
return n.ForEachChannel(
3714+
3715+
var nodes []GraphCacheNode
3716+
err = graph.ForEachNodeCacheable(
3717+
func(tx kvdb.RTx, node GraphCacheNode) error {
3718+
nodes = append(nodes, node)
3719+
3720+
return nil
3721+
},
3722+
)
3723+
require.NoError(b, err)
3724+
3725+
err = graph.db.View(func(tx kvdb.RTx) error {
3726+
for _, n := range nodes {
3727+
err := n.ForEachChannel(
37013728
tx, func(tx kvdb.RTx,
37023729
info *ChannelEdgeInfo,
37033730
policy *ChannelEdgePolicy,
@@ -3715,8 +3742,13 @@ func BenchmarkForEachChannel(b *testing.B) {
37153742
return nil
37163743
},
37173744
)
3718-
},
3719-
)
3745+
if err != nil {
3746+
return err
3747+
}
3748+
}
3749+
3750+
return nil
3751+
}, func() {})
37203752
require.NoError(b, err)
37213753
}
37223754
}
@@ -3760,3 +3792,52 @@ func TestGraphCacheForEachNodeChannel(t *testing.T) {
37603792

37613793
require.Equal(t, numChans, 1)
37623794
}
3795+
3796+
// TestGraphLoading asserts that the cache is properly reconstructed after a
3797+
// restart.
3798+
func TestGraphLoading(t *testing.T) {
3799+
// First, create a temporary directory to be used for the duration of
3800+
// this test.
3801+
tempDirName, err := ioutil.TempDir("", "channelgraph")
3802+
require.NoError(t, err)
3803+
defer os.RemoveAll(tempDirName)
3804+
3805+
// Next, create the graph for the first time.
3806+
backend, backendCleanup, err := kvdb.GetTestBackend(tempDirName, "cgr")
3807+
require.NoError(t, err)
3808+
defer backend.Close()
3809+
defer backendCleanup()
3810+
3811+
opts := DefaultOptions()
3812+
graph, err := NewChannelGraph(
3813+
backend, opts.RejectCacheSize, opts.ChannelCacheSize,
3814+
opts.BatchCommitInterval, opts.PreAllocCacheNumNodes,
3815+
true, false,
3816+
)
3817+
require.NoError(t, err)
3818+
3819+
// Populate the graph with test data.
3820+
const numNodes = 100
3821+
const numChannels = 4
3822+
_, _ = fillTestGraph(t, graph, numNodes, numChannels)
3823+
3824+
// Recreate the graph. This should cause the graph cache to be
3825+
// populated.
3826+
graphReloaded, err := NewChannelGraph(
3827+
backend, opts.RejectCacheSize, opts.ChannelCacheSize,
3828+
opts.BatchCommitInterval, opts.PreAllocCacheNumNodes,
3829+
true, false,
3830+
)
3831+
require.NoError(t, err)
3832+
3833+
// Assert that the cache content is identical.
3834+
require.Equal(
3835+
t, graph.graphCache.nodeChannels,
3836+
graphReloaded.graphCache.nodeChannels,
3837+
)
3838+
3839+
require.Equal(
3840+
t, graph.graphCache.nodeFeatures,
3841+
graphReloaded.graphCache.nodeFeatures,
3842+
)
3843+
}

docs/release-notes/release-notes-0.14.2.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ connection from the watch-only node.
1919
In other words, freshly-installed LND can now be initialized with multiple
2020
channels from an external (e.g. hardware) wallet *in a single transaction*.
2121

22+
## Database
23+
24+
* [Speed up graph cache loading on startup with
25+
Postgres](https://github.com/lightningnetwork/lnd/pull/6111)
26+
2227
## Build System
2328

2429
* [Clean up Makefile by using go

0 commit comments

Comments
 (0)