From 3c25195330063ea0a98d15a68fdc862eda3ba2be Mon Sep 17 00:00:00 2001 From: Elle Mouton Date: Thu, 10 Jul 2025 13:07:51 +0200 Subject: [PATCH 1/9] graph/db: don't let tests write to graphCache Instead of letting tests set the graphCache to nil in order to simulate it not being set, we instead make use of the WithUseGraphCache helper. --- graph/db/graph_test.go | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/graph/db/graph_test.go b/graph/db/graph_test.go index 501ff10be..1c38b3e7c 100644 --- a/graph/db/graph_test.go +++ b/graph/db/graph_test.go @@ -1739,11 +1739,16 @@ func testForEachSourceNodeChannel(t *testing.T, v lnwire.GossipVersion) { require.Empty(t, expectedSrcChans) } +// TestGraphTraversal tests that we can traverse the graph and find all +// nodes and channels that we expect to find. func TestGraphTraversal(t *testing.T) { t.Parallel() ctx := t.Context() - graph := MakeTestGraph(t) + // If we turn the channel graph cache _off_, then iterate through the + // set of channels (to force the fall back), we should find all the + // channel as well as the nodes included. + graph := MakeTestGraph(t, WithUseGraphCache(false)) // We'd like to test some of the graph traversal capabilities within // the DB, so we'll create a series of fake nodes to insert into the @@ -1760,10 +1765,6 @@ func TestGraphTraversal(t *testing.T) { nodeIndex[node.PubKeyBytes] = struct{}{} } - // If we turn the channel graph cache _off_, then iterate through the - // set of channels (to force the fall back), we should find all the - // channel as well as the nodes included. - graph.graphCache = nil err := graph.ForEachNodeCached(ctx, lnwire.GossipVersion1, false, func(_ context.Context, node route.Vertex, _ []net.Addr, chans map[uint64]*DirectedChannel) error { @@ -5022,7 +5023,7 @@ func BenchmarkForEachChannel(b *testing.B) { } } -// TestGraphCacheForEachNodeChannel tests that the forEachNodeDirectedChannel +// TestForEachNodeDirectedChannel tests that the ForEachNodeDirectedChannel // method works as expected, and is able to handle nil self edges. func testGraphCacheForEachNodeChannel(t *testing.T, v lnwire.GossipVersion) { @@ -5030,11 +5031,12 @@ func testGraphCacheForEachNodeChannel(t *testing.T, t.Parallel() ctx := t.Context() - graph := NewVersionedGraph(MakeTestGraph(t), v) - // Unset the channel graph cache to simulate the user running with the - // option turned off. - graph.graphCache = nil + // option turned off. This forces the V1Store ForEachNodeDirectedChannel + // to be queried instead of the graph cache's ForEachChannel method. + graph := NewVersionedGraph( + MakeTestGraph(t, WithUseGraphCache(false)), v, + ) node1 := createTestVertex(t, v) require.NoError(t, graph.AddNode(ctx, node1)) From 7f7b85ee2215162617cc4bbbeb608a69fa3fa60f Mon Sep 17 00:00:00 2001 From: Elle Mouton Date: Thu, 10 Jul 2025 13:13:38 +0200 Subject: [PATCH 2/9] graph/db: misc graphCache test updates Clean up TestGraphCacheTraversal so that we are explicitly enabling the graphCache. This removes the need to explicitly make calls to the cache. Also remove a duplicate check from assertNodeNotInCache. --- graph/db/graph_test.go | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/graph/db/graph_test.go b/graph/db/graph_test.go index 1c38b3e7c..13f24edda 100644 --- a/graph/db/graph_test.go +++ b/graph/db/graph_test.go @@ -1347,9 +1347,6 @@ func assertNodeNotInCache(t *testing.T, g *ChannelGraph, n route.Vertex) { _, ok := g.graphCache.nodeFeatures[n] require.False(t, ok) - _, ok = g.graphCache.nodeChannels[n] - require.False(t, ok) - // We should get the default features for this node. features := g.graphCache.GetFeatures(n) require.Equal(t, lnwire.EmptyFeatureVector(), features) @@ -1915,10 +1912,14 @@ func testGraphTraversalCacheable(t *testing.T, v lnwire.GossipVersion) { require.Len(t, chanIndex2, 0) } +// TestGraphCacheTraversal tests traversal of the graph via the graph cache. func TestGraphCacheTraversal(t *testing.T) { t.Parallel() + ctx := t.Context() - graph := MakeTestGraph(t) + // Explicitly enable the graph cache so that the + // ForEachNodeDirectedChannel call below will use the cache. + graph := MakeTestGraph(t, WithUseGraphCache(true)) // We'd like to test some of the graph traversal capabilities within // the DB, so we'll create a series of fake nodes to insert into the @@ -1936,8 +1937,8 @@ func TestGraphCacheTraversal(t *testing.T) { for _, node := range nodeList { node := node - err := graph.graphCache.ForEachChannel( - node.PubKeyBytes, func(d *DirectedChannel) error { + err := graph.ForEachNodeDirectedChannel( + ctx, node.PubKeyBytes, func(d *DirectedChannel) error { delete(chanIndex, d.ChannelID) if !d.OutPolicySet || d.InPolicy == nil { @@ -1958,6 +1959,8 @@ func TestGraphCacheTraversal(t *testing.T) { numNodeChans++ return nil + }, func() { + numNodeChans = 0 }, ) require.NoError(t, err) From 19216ee32d6c9f8cec6de40ae3d449de6e0e96e4 Mon Sep 17 00:00:00 2001 From: Elle Mouton Date: Thu, 10 Jul 2025 13:22:53 +0200 Subject: [PATCH 3/9] graph/db: add cacheLoaded atomic bool Use this to block reading from the cache unless cacheLoaded returns true. This will start being useful once cache population is done asynchronously. --- graph/db/graph.go | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/graph/db/graph.go b/graph/db/graph.go index 5e74bfcb7..3568986e2 100644 --- a/graph/db/graph.go +++ b/graph/db/graph.go @@ -30,7 +30,11 @@ type ChannelGraph struct { started atomic.Bool stopped atomic.Bool - graphCache *GraphCache + // cacheLoaded is true if the initial graphCache population has + // finished. We use this to ensure that when performing any reads, + // we only read from the graphCache if it has been fully populated. + cacheLoaded atomic.Bool + graphCache *GraphCache db Store *topologyManager @@ -206,6 +210,8 @@ func (c *ChannelGraph) populateCache(ctx context.Context) error { } } + c.cacheLoaded.Store(true) + log.Infof("Finished populating in-memory channel graph (took %v, %s)", time.Since(startTime), c.graphCache.Stats()) @@ -226,7 +232,7 @@ func (c *ChannelGraph) ForEachNodeDirectedChannel(ctx context.Context, node route.Vertex, cb func(channel *DirectedChannel) error, reset func()) error { - if c.graphCache != nil { + if c.graphCache != nil && c.cacheLoaded.Load() { return c.graphCache.ForEachChannel(node, cb) } @@ -247,7 +253,7 @@ func (c *ChannelGraph) ForEachNodeDirectedChannel(ctx context.Context, func (c *ChannelGraph) FetchNodeFeatures(ctx context.Context, node route.Vertex) (*lnwire.FeatureVector, error) { - if c.graphCache != nil { + if c.graphCache != nil && c.cacheLoaded.Load() { return c.graphCache.GetFeatures(node), nil } @@ -261,7 +267,7 @@ func (c *ChannelGraph) FetchNodeFeatures(ctx context.Context, func (c *ChannelGraph) GraphSession(ctx context.Context, cb func(graph NodeTraverser) error, reset func()) error { - if c.graphCache != nil { + if c.graphCache != nil && c.cacheLoaded.Load() { return cb(c) } @@ -277,7 +283,7 @@ func (c *ChannelGraph) ForEachNodeCached(ctx context.Context, cb func(ctx context.Context, node route.Vertex, addrs []net.Addr, chans map[uint64]*DirectedChannel) error, reset func()) error { - if !withAddrs && c.graphCache != nil { + if !withAddrs && c.graphCache != nil && c.cacheLoaded.Load() { return c.graphCache.ForEachNode( func(node route.Vertex, channels map[uint64]*DirectedChannel) error { From 24d6e9d618f0e782bb55522af6e974cfc3fdc710 Mon Sep 17 00:00:00 2001 From: Elle Mouton Date: Thu, 10 Jul 2025 13:30:28 +0200 Subject: [PATCH 4/9] graph/db: move graph disabled check to inside populateCache Refactor so that we don't have two layers of indentation later on when we want to spin populateCache off into a goroutine. --- graph/db/graph.go | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/graph/db/graph.go b/graph/db/graph.go index 3568986e2..eb84603f2 100644 --- a/graph/db/graph.go +++ b/graph/db/graph.go @@ -79,11 +79,8 @@ func (c *ChannelGraph) Start() error { ctx := context.TODO() - if c.graphCache != nil { - if err := c.populateCache(ctx); err != nil { - return fmt.Errorf("could not populate the graph "+ - "cache: %w", err) - } + if err := c.populateCache(ctx); err != nil { + return fmt.Errorf("could not populate the graph cache: %w", err) } c.wg.Add(1) @@ -165,9 +162,13 @@ func (c *ChannelGraph) handleTopologySubscriptions(ctx context.Context) { } // populateCache loads the entire channel graph into the in-memory graph cache. -// -// NOTE: This should only be called if the graphCache has been constructed. func (c *ChannelGraph) populateCache(ctx context.Context) error { + if c.graphCache == nil { + log.Info("In-memory channel graph cache disabled") + + return nil + } + startTime := time.Now() log.Info("Populating in-memory channel graph, this might take a " + "while...") From ee4bc4dde5d1b163ea8b71b9c9b125341d8a53fa Mon Sep 17 00:00:00 2001 From: Elle Mouton Date: Fri, 6 Mar 2026 11:14:03 +0200 Subject: [PATCH 5/9] graph/db: add startup context cancellation Create a cancellable context in Start() and store its cancel function on the struct. Stop() invokes it so that long-running DB iterations (e.g. cache population) can be interrupted promptly during shutdown. --- graph/db/graph.go | 10 +++++++--- graph/db/kv_store.go | 12 ++++++++++-- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/graph/db/graph.go b/graph/db/graph.go index eb84603f2..7662253fd 100644 --- a/graph/db/graph.go +++ b/graph/db/graph.go @@ -15,6 +15,7 @@ import ( "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/wire" "github.com/lightningnetwork/lnd/batch" + "github.com/lightningnetwork/lnd/fn/v2" "github.com/lightningnetwork/lnd/graph/db/models" "github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/routing/route" @@ -39,8 +40,9 @@ type ChannelGraph struct { db Store *topologyManager - quit chan struct{} - wg sync.WaitGroup + quit chan struct{} + wg sync.WaitGroup + cancel fn.Option[context.CancelFunc] } // NewChannelGraph creates a new ChannelGraph instance with the given backend. @@ -77,7 +79,8 @@ func (c *ChannelGraph) Start() error { log.Debugf("ChannelGraph starting") defer log.Debug("ChannelGraph started") - ctx := context.TODO() + ctx, cancel := context.WithCancel(context.Background()) + c.cancel = fn.Some(cancel) if err := c.populateCache(ctx); err != nil { return fmt.Errorf("could not populate the graph cache: %w", err) @@ -98,6 +101,7 @@ func (c *ChannelGraph) Stop() error { log.Debugf("ChannelGraph shutting down...") defer log.Debug("ChannelGraph shutdown complete") + c.cancel.WhenSome(func(fn context.CancelFunc) { fn() }) close(c.quit) c.wg.Wait() diff --git a/graph/db/kv_store.go b/graph/db/kv_store.go index 2a993d73b..3021fe9af 100644 --- a/graph/db/kv_store.go +++ b/graph/db/kv_store.go @@ -493,7 +493,7 @@ func forEachChannel(db kvdb.Backend, cb func(*models.ChannelEdgeInfo, // // NOTE: this method is like ForEachChannel but fetches only the data required // for the graph cache. -func (c *KVStore) ForEachChannelCacheable(_ context.Context, +func (c *KVStore) ForEachChannelCacheable(ctx context.Context, v lnwire.GossipVersion, cb func(*models.CachedEdgeInfo, *models.CachedEdgePolicy, *models.CachedEdgePolicy) error, reset func()) error { @@ -524,6 +524,10 @@ func (c *KVStore) ForEachChannelCacheable(_ context.Context, // loaded above and invoke the callback. return kvdb.ForAll( edgeIndex, func(k, edgeInfoBytes []byte) error { + if err := ctx.Err(); err != nil { + return err + } + var chanID [8]byte copy(chanID[:], k) @@ -895,7 +899,7 @@ func forEachNode(db kvdb.Backend, // graph, executing the passed callback with each node encountered. If the // callback returns an error, then the transaction is aborted and the iteration // stops early. -func (c *KVStore) ForEachNodeCacheable(_ context.Context, +func (c *KVStore) ForEachNodeCacheable(ctx context.Context, v lnwire.GossipVersion, cb func(route.Vertex, *lnwire.FeatureVector) error, reset func()) error { @@ -912,6 +916,10 @@ func (c *KVStore) ForEachNodeCacheable(_ context.Context, } return nodes.ForEach(func(pubKey, nodeBytes []byte) error { + if err := ctx.Err(); err != nil { + return err + } + // If this is the source key, then we skip this // iteration as the value for this key is a pubKey // rather than raw node information. From 4486b5261d22918d50e41cc771904412ebd99794 Mon Sep 17 00:00:00 2001 From: Elle Mouton Date: Fri, 6 Mar 2026 09:51:00 +0200 Subject: [PATCH 6/9] graph/db: allow async cache population Introduce graphCacheState, a wrapper around GraphCache that tracks its population lifecycle (loading -> loaded) and buffers concurrent mutations during the initial DB scan. Once population completes, buffered updates are replayed and the cache begins serving reads. Start() now launches populateCache in a background goroutine by default. While the cache is loading, all graph reads fall back to the database. The KV iterators (ForEachNodeCacheable, ForEachChannelCacheable) now respect context cancellation so that Stop() can interrupt a long-running population. Tests cover: concurrent reads during population, concurrent write replay, shutdown cancellation during load, population failure with DB fallback, and KV iterator cancellation. --- graph/db/graph.go | 196 ++++++++----- graph/db/graph_cache_state.go | 105 +++++++ graph/db/graph_test.go | 502 ++++++++++++++++++++++++++++++++-- graph/db/kv_store.go | 8 +- graph/db/options.go | 30 +- 5 files changed, 734 insertions(+), 107 deletions(-) create mode 100644 graph/db/graph_cache_state.go diff --git a/graph/db/graph.go b/graph/db/graph.go index 7662253fd..e7ed585c5 100644 --- a/graph/db/graph.go +++ b/graph/db/graph.go @@ -31,11 +31,9 @@ type ChannelGraph struct { started atomic.Bool stopped atomic.Bool - // cacheLoaded is true if the initial graphCache population has - // finished. We use this to ensure that when performing any reads, - // we only read from the graphCache if it has been fully populated. - cacheLoaded atomic.Bool - graphCache *GraphCache + opts *chanGraphOptions + + cache *graphCacheState db Store *topologyManager @@ -55,6 +53,7 @@ func NewChannelGraph(v1Store Store, } g := &ChannelGraph{ + opts: opts, db: v1Store, topologyManager: newTopologyManager(), quit: make(chan struct{}), @@ -63,7 +62,7 @@ func NewChannelGraph(v1Store Store, // The graph cache can be turned off (e.g. for mobile users) for a // speed/memory usage tradeoff. if opts.useGraphCache { - g.graphCache = NewGraphCache(opts.preAllocCacheNumNodes) + g.cache = newGraphCacheState(opts.preAllocCacheNumNodes) } return g, nil @@ -82,8 +81,21 @@ func (c *ChannelGraph) Start() error { ctx, cancel := context.WithCancel(context.Background()) c.cancel = fn.Some(cancel) - if err := c.populateCache(ctx); err != nil { - return fmt.Errorf("could not populate the graph cache: %w", err) + if c.opts.asyncGraphCachePopulation { + c.wg.Add(1) + go func() { + defer c.wg.Done() + + if err := c.populateCache(ctx); err != nil { + log.Criticalf("Could not populate the "+ + "graph cache: %v", err) + } + }() + } else { + if err := c.populateCache(ctx); err != nil { + return fmt.Errorf("could not populate the graph "+ + "cache: %w", err) + } } c.wg.Add(1) @@ -167,12 +179,21 @@ func (c *ChannelGraph) handleTopologySubscriptions(ctx context.Context) { // populateCache loads the entire channel graph into the in-memory graph cache. func (c *ChannelGraph) populateCache(ctx context.Context) error { - if c.graphCache == nil { + if c.cache == nil { log.Info("In-memory channel graph cache disabled") return nil } + c.cache.beginPopulation() + + loaded := false + defer func() { + c.cache.finishPopulation(loaded) + }() + + cache := c.cache.graphCache + startTime := time.Now() log.Info("Populating in-memory channel graph, this might take a " + "while...") @@ -186,7 +207,7 @@ func (c *ChannelGraph) populateCache(ctx context.Context) error { func(node route.Vertex, features *lnwire.FeatureVector) error { - c.graphCache.AddNodeFeatures(node, features) + cache.AddNodeFeatures(node, features) return nil }, func() {}, @@ -203,7 +224,7 @@ func (c *ChannelGraph) populateCache(ctx context.Context) error { policy1, policy2 *models.CachedEdgePolicy) error { - c.graphCache.AddChannel(info, policy1, policy2) + cache.AddChannel(info, policy1, policy2) return nil }, func() {}, @@ -215,10 +236,10 @@ func (c *ChannelGraph) populateCache(ctx context.Context) error { } } - c.cacheLoaded.Store(true) + loaded = true log.Infof("Finished populating in-memory channel graph (took %v, %s)", - time.Since(startTime), c.graphCache.Stats()) + time.Since(startTime), cache.Stats()) return nil } @@ -237,8 +258,8 @@ func (c *ChannelGraph) ForEachNodeDirectedChannel(ctx context.Context, node route.Vertex, cb func(channel *DirectedChannel) error, reset func()) error { - if c.graphCache != nil && c.cacheLoaded.Load() { - return c.graphCache.ForEachChannel(node, cb) + if c.cache != nil && c.cache.isLoaded() { + return c.cache.graphCache.ForEachChannel(node, cb) } // TODO(elle): once the no-cache path needs to support @@ -258,8 +279,8 @@ func (c *ChannelGraph) ForEachNodeDirectedChannel(ctx context.Context, func (c *ChannelGraph) FetchNodeFeatures(ctx context.Context, node route.Vertex) (*lnwire.FeatureVector, error) { - if c.graphCache != nil && c.cacheLoaded.Load() { - return c.graphCache.GetFeatures(node), nil + if c.cache != nil && c.cache.isLoaded() { + return c.cache.graphCache.GetFeatures(node), nil } return c.db.FetchNodeFeatures(ctx, lnwire.GossipVersion1, node) @@ -272,7 +293,7 @@ func (c *ChannelGraph) FetchNodeFeatures(ctx context.Context, func (c *ChannelGraph) GraphSession(ctx context.Context, cb func(graph NodeTraverser) error, reset func()) error { - if c.graphCache != nil && c.cacheLoaded.Load() { + if c.cache != nil && c.cache.isLoaded() { return cb(c) } @@ -288,8 +309,8 @@ func (c *ChannelGraph) ForEachNodeCached(ctx context.Context, cb func(ctx context.Context, node route.Vertex, addrs []net.Addr, chans map[uint64]*DirectedChannel) error, reset func()) error { - if !withAddrs && c.graphCache != nil && c.cacheLoaded.Load() { - return c.graphCache.ForEachNode( + if !withAddrs && c.cache != nil && c.cache.isLoaded() { + return c.cache.graphCache.ForEachNode( func(node route.Vertex, channels map[uint64]*DirectedChannel) error { @@ -315,10 +336,12 @@ func (c *ChannelGraph) AddNode(ctx context.Context, return err } - if c.graphCache != nil { - c.graphCache.AddNodeFeatures( - node.PubKeyBytes, node.Features, - ) + if c.cache != nil { + c.cache.applyUpdate(func(cache *GraphCache) { + cache.AddNodeFeatures( + node.PubKeyBytes, node.Features, + ) + }) } select { @@ -344,8 +367,10 @@ func (c *ChannelGraph) AddChannelEdge(ctx context.Context, return err } - if c.graphCache != nil { - c.graphCache.AddChannel(models.NewCachedEdge(edge), nil, nil) + if c.cache != nil { + c.cache.applyUpdate(func(cache *GraphCache) { + cache.AddChannel(models.NewCachedEdge(edge), nil, nil) + }) } select { @@ -368,7 +393,7 @@ func (c *ChannelGraph) MarkEdgeLive(ctx context.Context, return err } - if c.graphCache != nil { + if c.cache != nil { // We need to add the channel back into our graph cache, // otherwise we won't use it for path finding. infos, err := c.db.FetchChanInfos(ctx, v, []uint64{chanID}) @@ -390,9 +415,12 @@ func (c *ChannelGraph) MarkEdgeLive(ctx context.Context, policy2 = models.NewCachedPolicy(info.Policy2) } - c.graphCache.AddChannel( - models.NewCachedEdge(info.Info), policy1, policy2, - ) + c.cache.applyUpdate(func(cache *GraphCache) { + cache.AddChannel( + models.NewCachedEdge(info.Info), + policy1, policy2, + ) + }) } return nil @@ -417,13 +445,15 @@ func (c *ChannelGraph) DeleteChannelEdges(ctx context.Context, return err } - if c.graphCache != nil { - for _, info := range infos { - c.graphCache.RemoveChannel( - info.NodeKey1Bytes, info.NodeKey2Bytes, - info.ChannelID, - ) - } + if c.cache != nil { + c.cache.applyUpdate(func(cache *GraphCache) { + for _, info := range infos { + cache.RemoveChannel( + info.NodeKey1Bytes, info.NodeKey2Bytes, + info.ChannelID, + ) + } + }) } return err @@ -444,13 +474,15 @@ func (c *ChannelGraph) DisconnectBlockAtHeight(ctx context.Context, return nil, err } - if c.graphCache != nil { - for _, edge := range edges { - c.graphCache.RemoveChannel( - edge.NodeKey1Bytes, edge.NodeKey2Bytes, - edge.ChannelID, - ) - } + if c.cache != nil { + c.cache.applyUpdate(func(cache *GraphCache) { + for _, edge := range edges { + cache.RemoveChannel( + edge.NodeKey1Bytes, edge.NodeKey2Bytes, + edge.ChannelID, + ) + } + }) } return edges, nil @@ -475,20 +507,22 @@ func (c *ChannelGraph) PruneGraph(ctx context.Context, return nil, err } - if c.graphCache != nil { - for _, edge := range edges { - c.graphCache.RemoveChannel( - edge.NodeKey1Bytes, edge.NodeKey2Bytes, - edge.ChannelID, - ) - } + if c.cache != nil { + c.cache.applyUpdate(func(cache *GraphCache) { + for _, edge := range edges { + cache.RemoveChannel( + edge.NodeKey1Bytes, edge.NodeKey2Bytes, + edge.ChannelID, + ) + } + for _, node := range nodes { + cache.RemoveNode(node) + } + }) - for _, node := range nodes { - c.graphCache.RemoveNode(node) + if stats, ok := c.cache.stats(); ok { + log.Debugf("Pruned graph, cache now has %s", stats) } - - log.Debugf("Pruned graph, cache now has %s", - c.graphCache.Stats()) } if len(edges) != 0 { @@ -518,10 +552,12 @@ func (c *ChannelGraph) PruneGraphNodes(ctx context.Context) error { return err } - if c.graphCache != nil { - for _, node := range nodes { - c.graphCache.RemoveNode(node) - } + if c.cache != nil { + c.cache.applyUpdate(func(cache *GraphCache) { + for _, node := range nodes { + cache.RemoveNode(node) + } + }) } return nil @@ -589,8 +625,10 @@ func (c *ChannelGraph) MarkEdgeZombie(ctx context.Context, return err } - if c.graphCache != nil { - c.graphCache.RemoveChannel(pubKey1, pubKey2, chanID) + if c.cache != nil { + c.cache.applyUpdate(func(cache *GraphCache) { + cache.RemoveChannel(pubKey1, pubKey2, chanID) + }) } return nil @@ -611,10 +649,12 @@ func (c *ChannelGraph) UpdateEdgePolicy(ctx context.Context, return err } - if c.graphCache != nil { - c.graphCache.UpdatePolicy( - models.NewCachedPolicy(edge), from, to, - ) + if c.cache != nil { + c.cache.applyUpdate(func(cache *GraphCache) { + cache.UpdatePolicy( + models.NewCachedPolicy(edge), from, to, + ) + }) } select { @@ -820,8 +860,8 @@ func NewVersionedGraph(c *ChannelGraph, func (c *VersionedGraph) FetchNodeFeatures(ctx context.Context, node route.Vertex) (*lnwire.FeatureVector, error) { - if c.graphCache != nil { - return c.graphCache.GetFeatures(node), nil + if c.cache != nil && c.cache.isLoaded() { + return c.cache.graphCache.GetFeatures(node), nil } return c.db.FetchNodeFeatures(ctx, c.v, node) @@ -837,8 +877,8 @@ func (c *VersionedGraph) ForEachNodeDirectedChannel(ctx context.Context, node route.Vertex, cb func(channel *DirectedChannel) error, reset func()) error { - if c.graphCache != nil { - return c.graphCache.ForEachChannel(node, cb) + if c.cache != nil && c.cache.isLoaded() { + return c.cache.graphCache.ForEachChannel(node, cb) } return c.db.ForEachNodeDirectedChannel(ctx, c.v, node, cb, reset) @@ -891,7 +931,7 @@ func (c *VersionedGraph) ChannelView(ctx context.Context) ([]EdgePoint, func (c *VersionedGraph) GraphSession(ctx context.Context, cb func(graph NodeTraverser) error, reset func()) error { - if c.graphCache != nil { + if c.cache != nil && c.cache.isLoaded() { return cb(c) } @@ -951,8 +991,10 @@ func (c *VersionedGraph) DeleteNode(ctx context.Context, return err } - if c.graphCache != nil { - c.graphCache.RemoveNode(nodePub) + if c.cache != nil { + c.cache.applyUpdate(func(cache *GraphCache) { + cache.RemoveNode(nodePub) + }) } return nil @@ -1096,7 +1138,13 @@ func MakeTestGraph(t testing.TB, store := NewTestDB(t) - graph, err := NewChannelGraph(store, opts...) + // Default to synchronous cache population in tests so that the + // cache is fully loaded before the test proceeds. + allOpts := append( + []ChanGraphOption{WithSyncGraphCachePopulation()}, opts..., + ) + + graph, err := NewChannelGraph(store, allOpts...) require.NoError(t, err) require.NoError(t, graph.Start()) diff --git a/graph/db/graph_cache_state.go b/graph/db/graph_cache_state.go new file mode 100644 index 000000000..716d770ce --- /dev/null +++ b/graph/db/graph_cache_state.go @@ -0,0 +1,105 @@ +package graphdb + +import ( + "sync" + "sync/atomic" +) + +// pendingUpdatesWarnThreshold is the number of buffered cache mutations at +// which a warning is logged. A large buffer indicates that cache population is +// taking a long time relative to the incoming gossip rate. +const pendingUpdatesWarnThreshold = 10_000 + +// graphCacheState tracks the in-memory graph cache together with its +// population state. The underlying GraphCache is independently thread-safe, so +// once reads are allowed to use it, they do not need to hold updateMtx. +type graphCacheState struct { + graphCache *GraphCache + loaded atomic.Bool + failed atomic.Bool + + updateMtx sync.Mutex + loading bool + + pendingUpdates []func(*GraphCache) +} + +// newGraphCacheState constructs a graph cache state with a new cache instance. +func newGraphCacheState(preAllocNumNodes int) *graphCacheState { + return &graphCacheState{ + graphCache: NewGraphCache(preAllocNumNodes), + } +} + +// isLoaded reports whether the cache has finished its initial population and +// is safe to serve reads from. +func (s *graphCacheState) isLoaded() bool { + return s.loaded.Load() +} + +// isFailed reports whether the cache population attempt has failed. +func (s *graphCacheState) isFailed() bool { + return s.failed.Load() +} + +// stats returns the cache stats if the cache has finished its initial +// population. +func (s *graphCacheState) stats() (string, bool) { + if !s.isLoaded() { + return "", false + } + + return s.graphCache.Stats(), true +} + +// beginPopulation marks the cache as loading and starts buffering concurrent +// cache mutations until the population pass completes. +func (s *graphCacheState) beginPopulation() { + s.updateMtx.Lock() + defer s.updateMtx.Unlock() + + s.loading = true + s.pendingUpdates = nil +} + +// finishPopulation replays any buffered mutations and marks the cache as ready +// when the initial population completed successfully. If population failed, +// buffered mutations are discarded since the cache won't be used for reads. +func (s *graphCacheState) finishPopulation(loaded bool) { + s.updateMtx.Lock() + defer s.updateMtx.Unlock() + + if loaded { + for _, update := range s.pendingUpdates { + update(s.graphCache) + } + + s.loaded.Store(true) + } else { + s.failed.Store(true) + } + + s.pendingUpdates = nil + s.loading = false +} + +// applyUpdate applies a cache mutation immediately or buffers it when the +// cache is still being populated. +func (s *graphCacheState) applyUpdate(update func(cache *GraphCache)) { + s.updateMtx.Lock() + defer s.updateMtx.Unlock() + + if s.loading { + s.pendingUpdates = append(s.pendingUpdates, update) + + if len(s.pendingUpdates)%pendingUpdatesWarnThreshold == 0 { + log.Warnf("Graph cache has %d pending updates "+ + "buffered during population", + len(s.pendingUpdates)) + } + + return + } + + update(s.graphCache) +} diff --git a/graph/db/graph_test.go b/graph/db/graph_test.go index 13f24edda..f82ed51c8 100644 --- a/graph/db/graph_test.go +++ b/graph/db/graph_test.go @@ -24,6 +24,7 @@ import ( "github.com/lightningnetwork/lnd/fn/v2" "github.com/lightningnetwork/lnd/graph/db/models" "github.com/lightningnetwork/lnd/kvdb" + "github.com/lightningnetwork/lnd/lntest/wait" "github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/routing/route" "github.com/stretchr/testify/require" @@ -440,7 +441,9 @@ func testPartialNode(t *testing.T, v lnwire.GossipVersion) { t.Parallel() ctx := t.Context() - graph := NewVersionedGraph(MakeTestGraph(t), v) + graph := NewVersionedGraph( + MakeTestGraph(t, WithSyncGraphCachePopulation()), v, + ) // To insert a partial node, we need to add a channel edge that has // node keys for nodes we are not yet aware of. @@ -612,7 +615,9 @@ func testEdgeInsertionDeletion(t *testing.T, v lnwire.GossipVersion) { t.Parallel() ctx := t.Context() - graph := NewVersionedGraph(MakeTestGraph(t), v) + graph := NewVersionedGraph( + MakeTestGraph(t, WithSyncGraphCachePopulation()), v, + ) // We'd like to test the insertion/deletion of edges, so we create two // vertexes to connect. @@ -849,7 +854,7 @@ func TestDisconnectBlockAtHeight(t *testing.T) { t.Parallel() ctx := t.Context() - graph := MakeTestGraph(t) + graph := MakeTestGraph(t, WithSyncGraphCachePopulation()) sourceNode := createTestVertex(t, lnwire.GossipVersion1) require.NoError(t, graph.SetSourceNode(ctx, sourceNode)) @@ -1148,7 +1153,9 @@ func testEdgeInfoUpdates(t *testing.T, v lnwire.GossipVersion) { t.Parallel() ctx := t.Context() - graph := NewVersionedGraph(MakeTestGraph(t), v) + graph := NewVersionedGraph( + MakeTestGraph(t, WithSyncGraphCachePopulation()), v, + ) // We'd like to test the update of edges inserted into the database, so // we create two vertexes to connect. @@ -1166,7 +1173,7 @@ func testEdgeInfoUpdates(t *testing.T, v lnwire.GossipVersion) { // is added, will fail. err := graph.UpdateEdgePolicy(ctx, edge1) require.ErrorIs(t, err, ErrEdgeNotFound) - require.Len(t, graph.graphCache.nodeChannels, 0) + require.Len(t, graph.cache.graphCache.nodeChannels, 0) // Add the edge info. require.NoError(t, graph.AddChannelEdge(ctx, edgeInfo)) @@ -1329,8 +1336,9 @@ func assertNodeInCache(t *testing.T, g *ChannelGraph, n *models.Node, expectedFeatures *lnwire.FeatureVector) { // Let's check the internal view first. + nodeFeatures := g.cache.graphCache.nodeFeatures require.Equal( - t, expectedFeatures, g.graphCache.nodeFeatures[n.PubKeyBytes], + t, expectedFeatures, nodeFeatures[n.PubKeyBytes], ) // The external view should reflect this as well. Except when we expect @@ -1339,16 +1347,19 @@ func assertNodeInCache(t *testing.T, g *ChannelGraph, n *models.Node, if expectedFeatures == nil { expectedFeatures = lnwire.EmptyFeatureVector() } - features := g.graphCache.GetFeatures(n.PubKeyBytes) + features := g.cache.graphCache.GetFeatures(n.PubKeyBytes) require.Equal(t, expectedFeatures, features) } func assertNodeNotInCache(t *testing.T, g *ChannelGraph, n route.Vertex) { - _, ok := g.graphCache.nodeFeatures[n] + _, ok := g.cache.graphCache.nodeFeatures[n] + require.False(t, ok) + + _, ok = g.cache.graphCache.nodeChannels[n] require.False(t, ok) // We should get the default features for this node. - features := g.graphCache.GetFeatures(n) + features := g.cache.graphCache.GetFeatures(n) require.Equal(t, lnwire.EmptyFeatureVector(), features) } @@ -1356,8 +1367,8 @@ func assertEdgeWithNoPoliciesInCache(t *testing.T, g *ChannelGraph, e *models.ChannelEdgeInfo) { // Let's check the internal view first. - require.NotEmpty(t, g.graphCache.nodeChannels[e.NodeKey1Bytes]) - require.NotEmpty(t, g.graphCache.nodeChannels[e.NodeKey2Bytes]) + require.NotEmpty(t, g.cache.graphCache.nodeChannels[e.NodeKey1Bytes]) + require.NotEmpty(t, g.cache.graphCache.nodeChannels[e.NodeKey2Bytes]) expectedNode1Channel := &DirectedChannel{ ChannelID: e.ChannelID, @@ -1367,12 +1378,13 @@ func assertEdgeWithNoPoliciesInCache(t *testing.T, g *ChannelGraph, OutPolicySet: false, InPolicy: nil, } + nodeChannels := g.cache.graphCache.nodeChannels require.Contains( - t, g.graphCache.nodeChannels[e.NodeKey1Bytes], e.ChannelID, + t, nodeChannels[e.NodeKey1Bytes], e.ChannelID, ) require.Equal( t, expectedNode1Channel, - g.graphCache.nodeChannels[e.NodeKey1Bytes][e.ChannelID], + nodeChannels[e.NodeKey1Bytes][e.ChannelID], ) expectedNode2Channel := &DirectedChannel{ @@ -1384,16 +1396,16 @@ func assertEdgeWithNoPoliciesInCache(t *testing.T, g *ChannelGraph, InPolicy: nil, } require.Contains( - t, g.graphCache.nodeChannels[e.NodeKey2Bytes], e.ChannelID, + t, nodeChannels[e.NodeKey2Bytes], e.ChannelID, ) require.Equal( t, expectedNode2Channel, - g.graphCache.nodeChannels[e.NodeKey2Bytes][e.ChannelID], + nodeChannels[e.NodeKey2Bytes][e.ChannelID], ) // The external view should reflect this as well. var foundChannel *DirectedChannel - err := g.graphCache.ForEachChannel( + err := g.cache.graphCache.ForEachChannel( e.NodeKey1Bytes, func(c *DirectedChannel) error { if c.ChannelID == e.ChannelID { foundChannel = c @@ -1406,7 +1418,7 @@ func assertEdgeWithNoPoliciesInCache(t *testing.T, g *ChannelGraph, require.NotNil(t, foundChannel) require.Equal(t, expectedNode1Channel, foundChannel) - err = g.graphCache.ForEachChannel( + err = g.cache.graphCache.ForEachChannel( e.NodeKey2Bytes, func(c *DirectedChannel) error { if c.ChannelID == e.ChannelID { foundChannel = c @@ -1423,7 +1435,7 @@ func assertEdgeWithNoPoliciesInCache(t *testing.T, g *ChannelGraph, func assertNoEdge(t *testing.T, g *ChannelGraph, chanID uint64) { // Make sure no channel in the cache has the given channel ID. If there // are no channels at all, that is fine as well. - for _, channels := range g.graphCache.nodeChannels { + for _, channels := range g.cache.graphCache.nodeChannels { for _, channel := range channels { require.NotEqual(t, channel.ChannelID, chanID) } @@ -1434,7 +1446,7 @@ func assertEdgeWithPolicyInCache(t *testing.T, g *ChannelGraph, e *models.ChannelEdgeInfo, p *models.ChannelEdgePolicy, policy1 bool) { // Check the internal state first. - c1, ok := g.graphCache.nodeChannels[e.NodeKey1Bytes][e.ChannelID] + c1, ok := g.cache.graphCache.nodeChannels[e.NodeKey1Bytes][e.ChannelID] require.True(t, ok) if policy1 { @@ -1447,7 +1459,7 @@ func assertEdgeWithPolicyInCache(t *testing.T, g *ChannelGraph, ) } - c2, ok := g.graphCache.nodeChannels[e.NodeKey2Bytes][e.ChannelID] + c2, ok := g.cache.graphCache.nodeChannels[e.NodeKey2Bytes][e.ChannelID] require.True(t, ok) if policy1 { @@ -1465,14 +1477,14 @@ func assertEdgeWithPolicyInCache(t *testing.T, g *ChannelGraph, c1Ext *DirectedChannel c2Ext *DirectedChannel ) - require.NoError(t, g.graphCache.ForEachChannel( + require.NoError(t, g.cache.graphCache.ForEachChannel( e.NodeKey1Bytes, func(c *DirectedChannel) error { c1Ext = c return nil }, )) - require.NoError(t, g.graphCache.ForEachChannel( + require.NoError(t, g.cache.graphCache.ForEachChannel( e.NodeKey2Bytes, func(c *DirectedChannel) error { c2Ext = c @@ -5137,7 +5149,9 @@ func TestGraphLoading(t *testing.T) { // Next, create the graph for the first time. graphStore := NewTestDB(t) - graph, err := NewChannelGraph(graphStore) + graph, err := NewChannelGraph( + graphStore, WithSyncGraphCachePopulation(), + ) require.NoError(t, err) require.NoError(t, graph.Start()) t.Cleanup(func() { @@ -5153,7 +5167,9 @@ func TestGraphLoading(t *testing.T) { // Recreate the graph. This should cause the graph cache to be // populated. - graphReloaded, err := NewChannelGraph(graphStore) + graphReloaded, err := NewChannelGraph( + graphStore, WithSyncGraphCachePopulation(), + ) require.NoError(t, err) require.NoError(t, graphReloaded.Start()) t.Cleanup(func() { @@ -5162,16 +5178,446 @@ func TestGraphLoading(t *testing.T) { // Assert that the cache content is identical. require.Equal( - t, graph.graphCache.nodeChannels, - graphReloaded.graphCache.nodeChannels, + t, graph.cache.graphCache.nodeChannels, + graphReloaded.cache.graphCache.nodeChannels, ) require.Equal( - t, graph.graphCache.nodeFeatures, - graphReloaded.graphCache.nodeFeatures, + t, graph.cache.graphCache.nodeFeatures, + graphReloaded.cache.graphCache.nodeFeatures, ) } +// TestAsyncGraphCache tests the behaviour of the ChannelGraph when the graph +// cache is populated asynchronously. +func TestAsyncGraphCache(t *testing.T) { + t.Parallel() + ctx := t.Context() + + const ( + numNodes = 100 + numChannels = 3 + ) + + // Next, create the graph for the first time. + graphStore := NewTestDB(t) + + // The first time we spin up the graph, we Start is as normal and fill + // it with test data. This will ensure that the graph cache has + // something to load on the next Start. + graph, err := NewChannelGraph(graphStore) + require.NoError(t, err) + require.NoError(t, graph.Start()) + channels, nodes := fillTestGraph( + t, graph, numNodes, numChannels, lnwire.GossipVersion1, + ) + + assertGraphState := func() { + var ( + numNodes int + chanIndex = make(map[uint64]struct{}, numChannels) + ) + + // We query the graph for all nodes and channels, and + // assert that we get the expected number of nodes and + // channels. + err := graph.ForEachNodeCached( + ctx, lnwire.GossipVersion1, false, + func(_ context.Context, node route.Vertex, + _ []net.Addr, + chans map[uint64]*DirectedChannel) error { + + numNodes++ + for chanID := range chans { + chanIndex[chanID] = struct{}{} + } + + return nil + }, func() { + numNodes = 0 + chanIndex = make( + map[uint64]struct{}, numChannels, + ) + }, + ) + require.NoError(t, err) + + require.Equal(t, len(nodes), numNodes) + require.Equal(t, len(channels), len(chanIndex)) + } + + assertGraphState() + + // Now we stop the graph. + require.NoError(t, graph.Stop()) + + // Recreate it but don't start it yet. + graph, err = NewChannelGraph(graphStore) + require.NoError(t, err) + + // Spin off a goroutine that starts to make queries to the ChannelGraph. + // We start this before we start the graph, so that we can ensure that + // the queries are made while the graph cache is being populated. + var ( + wg sync.WaitGroup + numRuns = 10 + ) + for i := 0; i < numRuns; i++ { + wg.Add(1) + go func() { + defer wg.Done() + + assertGraphState() + }() + } + + require.NoError(t, graph.Start()) + t.Cleanup(func() { + require.NoError(t, graph.Stop()) + }) + + wg.Wait() + + // Wait for the cache to be fully populated. + err = wait.Predicate(func() bool { + return graph.cache.isLoaded() + }, wait.DefaultTimeout) + require.NoError(t, err) + + // And then assert that all the expected nodes and channels are + // present in the graph cache. + for _, node := range nodes { + _, ok := graph.cache.graphCache.nodeChannels[node.PubKeyBytes] + require.True(t, ok) + } +} + +type blockingCacheLoadStore struct { + Store + + cacheLoadStarted chan struct{} + allowCacheLoad chan struct{} + blockOnce sync.Once +} + +// ForEachChannelCacheable pauses the first cacheable channel iteration until +// the test allows it to continue. +func (s *blockingCacheLoadStore) ForEachChannelCacheable(ctx context.Context, + v lnwire.GossipVersion, cb func(*models.CachedEdgeInfo, + *models.CachedEdgePolicy, *models.CachedEdgePolicy) error, + reset func()) error { + + return s.Store.ForEachChannelCacheable( + ctx, v, func(info *models.CachedEdgeInfo, + policy1, + policy2 *models.CachedEdgePolicy) error { + + s.blockOnce.Do(func() { + close(s.cacheLoadStarted) + <-s.allowCacheLoad + }) + + return cb(info, policy1, policy2) + }, reset, + ) +} + +type shutdownBlockingCacheLoadStore struct { + Store + + cacheLoadStarted chan struct{} + blockOnce sync.Once +} + +// ForEachChannelCacheable blocks until the context is canceled so tests can +// assert that Stop interrupts async cache population. +func (s *shutdownBlockingCacheLoadStore) ForEachChannelCacheable( + ctx context.Context, v lnwire.GossipVersion, + cb func(*models.CachedEdgeInfo, *models.CachedEdgePolicy, + *models.CachedEdgePolicy) error, reset func()) error { + + return s.Store.ForEachChannelCacheable( + ctx, v, func(info *models.CachedEdgeInfo, + policy1, + policy2 *models.CachedEdgePolicy) error { + + s.blockOnce.Do(func() { + close(s.cacheLoadStarted) + <-ctx.Done() + }) + + return ctx.Err() + }, reset, + ) +} + +type failingCacheLoadStore struct { + Store + + cacheLoadAttempted chan struct{} + populateErr error +} + +// ForEachChannelCacheable fails the initial cache population after signaling +// that the async load reached channel iteration. +func (s *failingCacheLoadStore) ForEachChannelCacheable(ctx context.Context, + v lnwire.GossipVersion, cb func(*models.CachedEdgeInfo, + *models.CachedEdgePolicy, *models.CachedEdgePolicy) error, + reset func()) error { + + close(s.cacheLoadAttempted) + + return s.populateErr +} + +// TestAsyncGraphCacheReplaysConcurrentWrites asserts that graph mutations that +// happen while the async cache population is running are replayed onto the +// cache before it becomes readable. +func TestAsyncGraphCacheReplaysConcurrentWrites(t *testing.T) { + t.Parallel() + ctx := t.Context() + + store := NewTestDB(t) + + setupGraph, err := NewChannelGraph( + store, WithSyncGraphCachePopulation(), + ) + require.NoError(t, err) + require.NoError(t, setupGraph.Start()) + + node1 := createTestVertex(t, lnwire.GossipVersion1) + require.NoError(t, setupGraph.AddNode(ctx, node1)) + node2 := createTestVertex(t, lnwire.GossipVersion1) + require.NoError(t, setupGraph.AddNode(ctx, node2)) + + edgeInfo, edge1, edge2 := createChannelEdge( + node1, node2, lnwire.GossipVersion1, + ) + require.NoError(t, setupGraph.AddChannelEdge(ctx, edgeInfo)) + require.NoError(t, setupGraph.UpdateEdgePolicy(ctx, edge1)) + require.NoError(t, setupGraph.UpdateEdgePolicy(ctx, edge2)) + require.NoError(t, setupGraph.Stop()) + + blockingStore := &blockingCacheLoadStore{ + Store: store, + cacheLoadStarted: make(chan struct{}), + allowCacheLoad: make(chan struct{}), + } + + graph, err := NewChannelGraph(blockingStore) + require.NoError(t, err) + require.NoError(t, graph.Start()) + t.Cleanup(func() { + require.NoError(t, graph.Stop()) + }) + + <-blockingStore.cacheLoadStarted + + updatedEdge := *edge1 + updatedEdge.LastUpdate = nextUpdateTime() + updatedEdge.FeeBaseMSat++ + require.NoError(t, graph.UpdateEdgePolicy(ctx, &updatedEdge)) + + close(blockingStore.allowCacheLoad) + + err = wait.Predicate(func() bool { + return graph.cache.isLoaded() + }, wait.DefaultTimeout) + require.NoError(t, err) + + var cachedFee lnwire.MilliSatoshi + err = graph.ForEachNodeDirectedChannel( + ctx, updatedEdge.ToNode, + func(channel *DirectedChannel) error { + if channel.ChannelID != updatedEdge.ChannelID { + return nil + } + + require.NotNil(t, channel.InPolicy) + cachedFee = channel.InPolicy.FeeBaseMSat + + return nil + }, func() {}, + ) + require.NoError(t, err) + require.Equal(t, updatedEdge.FeeBaseMSat, cachedFee) +} + +// TestAsyncGraphCacheStopCancelsLoad asserts that Stop interrupts async cache +// population instead of waiting for the full load to finish. +func TestAsyncGraphCacheStopCancelsLoad(t *testing.T) { + t.Parallel() + ctx := t.Context() + + store := NewTestDB(t) + + setupGraph, err := NewChannelGraph( + store, WithSyncGraphCachePopulation(), + ) + require.NoError(t, err) + require.NoError(t, setupGraph.Start()) + + node1 := createTestVertex(t, lnwire.GossipVersion1) + require.NoError(t, setupGraph.AddNode(ctx, node1)) + node2 := createTestVertex(t, lnwire.GossipVersion1) + require.NoError(t, setupGraph.AddNode(ctx, node2)) + + edgeInfo, edge1, edge2 := createChannelEdge( + node1, node2, lnwire.GossipVersion1, + ) + require.NoError(t, setupGraph.AddChannelEdge(ctx, edgeInfo)) + require.NoError(t, setupGraph.UpdateEdgePolicy(ctx, edge1)) + require.NoError(t, setupGraph.UpdateEdgePolicy(ctx, edge2)) + require.NoError(t, setupGraph.Stop()) + + blockingStore := &shutdownBlockingCacheLoadStore{ + Store: store, + cacheLoadStarted: make(chan struct{}), + } + + graph, err := NewChannelGraph(blockingStore) + require.NoError(t, err) + require.NoError(t, graph.Start()) + + <-blockingStore.cacheLoadStarted + + stopErr := make(chan error, 1) + go func() { + stopErr <- graph.Stop() + }() + + select { + case err := <-stopErr: + require.NoError(t, err) + + case <-time.After(wait.DefaultTimeout): + t.Fatal("Stop did not cancel graph cache loading") + } +} + +// TestAsyncGraphCachePopulationFailureFallsBackToDB asserts that cache +// population errors leave the cache unreadable while reads continue to succeed +// through the DB-backed path. +func TestAsyncGraphCachePopulationFailureFallsBackToDB(t *testing.T) { + t.Parallel() + ctx := t.Context() + + store := NewTestDB(t) + + setupGraph, err := NewChannelGraph( + store, WithSyncGraphCachePopulation(), + ) + require.NoError(t, err) + require.NoError(t, setupGraph.Start()) + + node1 := createTestVertex(t, lnwire.GossipVersion1) + require.NoError(t, setupGraph.AddNode(ctx, node1)) + node2 := createTestVertex(t, lnwire.GossipVersion1) + require.NoError(t, setupGraph.AddNode(ctx, node2)) + + edgeInfo, edge1, edge2 := createChannelEdge( + node1, node2, lnwire.GossipVersion1, + ) + require.NoError(t, setupGraph.AddChannelEdge(ctx, edgeInfo)) + require.NoError(t, setupGraph.UpdateEdgePolicy(ctx, edge1)) + require.NoError(t, setupGraph.UpdateEdgePolicy(ctx, edge2)) + require.NoError(t, setupGraph.Stop()) + + populateErr := errors.New("cache population failed") + failingStore := &failingCacheLoadStore{ + Store: store, + cacheLoadAttempted: make(chan struct{}), + populateErr: populateErr, + } + + graph, err := NewChannelGraph(failingStore) + require.NoError(t, err) + require.NoError(t, graph.Start()) + t.Cleanup(func() { + require.NoError(t, graph.Stop()) + }) + + <-failingStore.cacheLoadAttempted + require.False(t, graph.cache.isLoaded()) + + var numChannels int + err = graph.ForEachNodeDirectedChannel( + ctx, edge1.ToNode, + func(channel *DirectedChannel) error { + if channel.ChannelID != edge1.ChannelID { + return nil + } + + numChannels++ + require.NotNil(t, channel.InPolicy) + require.Equal(t, edge1.FeeBaseMSat, + channel.InPolicy.FeeBaseMSat) + + return nil + }, func() {}, + ) + require.NoError(t, err) + require.Equal(t, 1, numChannels) +} + +// TestKVCacheableIteratorsRespectCancellation asserts that KV-backed cache +// iterators return when their context is canceled. +func TestKVCacheableIteratorsRespectCancellation(t *testing.T) { + t.Parallel() + + if isSQLDB { + t.Skip("KV iterator cancellation is specific to KVStore") + } + + ctx := t.Context() + store := NewTestDB(t) + + kvStore, ok := store.(*KVStore) + require.True(t, ok) + + graph, err := NewChannelGraph( + kvStore, WithSyncGraphCachePopulation(), + ) + require.NoError(t, err) + require.NoError(t, graph.Start()) + t.Cleanup(func() { + require.NoError(t, graph.Stop()) + }) + + node1 := createTestVertex(t, lnwire.GossipVersion1) + require.NoError(t, graph.AddNode(ctx, node1)) + node2 := createTestVertex(t, lnwire.GossipVersion1) + require.NoError(t, graph.AddNode(ctx, node2)) + + edgeInfo, edge1, edge2 := createChannelEdge( + node1, node2, lnwire.GossipVersion1, + ) + require.NoError(t, graph.AddChannelEdge(ctx, edgeInfo)) + require.NoError(t, graph.UpdateEdgePolicy(ctx, edge1)) + require.NoError(t, graph.UpdateEdgePolicy(ctx, edge2)) + + canceledCtx, cancel := context.WithCancel(ctx) + cancel() + + err = kvStore.ForEachNodeCacheable( + canceledCtx, lnwire.GossipVersion1, + func(route.Vertex, *lnwire.FeatureVector) error { + return nil + }, func() {}, + ) + require.ErrorIs(t, err, context.Canceled) + + err = kvStore.ForEachChannelCacheable( + canceledCtx, lnwire.GossipVersion1, + func(*models.CachedEdgeInfo, *models.CachedEdgePolicy, + *models.CachedEdgePolicy) error { + + return nil + }, func() {}, + ) + require.ErrorIs(t, err, context.Canceled) +} + // TestClosedScid tests that we can correctly insert a SCID into the index of // closed short channel ids. func TestClosedScid(t *testing.T) { diff --git a/graph/db/kv_store.go b/graph/db/kv_store.go index 3021fe9af..aa32f75da 100644 --- a/graph/db/kv_store.go +++ b/graph/db/kv_store.go @@ -250,7 +250,7 @@ func (c channelMapKey) String() string { // getChannelMap loads all channel edge policies from the database and stores // them in a map. -func getChannelMap(edges kvdb.RBucket) ( +func getChannelMap(ctx context.Context, edges kvdb.RBucket) ( map[channelMapKey]*models.ChannelEdgePolicy, error) { // Create a map to store all channel edge policies. @@ -440,7 +440,9 @@ func forEachChannel(db kvdb.Backend, cb func(*models.ChannelEdgeInfo, // First, load all edges in memory indexed by node and channel // id. - channelMap, err := getChannelMap(edges) + channelMap, err := getChannelMap( + context.Background(), edges, + ) if err != nil { return err } @@ -510,7 +512,7 @@ func (c *KVStore) ForEachChannelCacheable(ctx context.Context, // First, load all edges in memory indexed by node and channel // id. - channelMap, err := getChannelMap(edges) + channelMap, err := getChannelMap(ctx, edges) if err != nil { return err } diff --git a/graph/db/options.go b/graph/db/options.go index 15ea6f4ee..df49fd7e0 100644 --- a/graph/db/options.go +++ b/graph/db/options.go @@ -85,14 +85,21 @@ type chanGraphOptions struct { // preAllocCacheNumNodes is the number of nodes we expect to be in the // graph cache, so we can pre-allocate the map accordingly. preAllocCacheNumNodes int + + // asyncGraphCachePopulation indicates whether the graph cache + // should be populated asynchronously or if the Start method should + // block until the cache is fully populated. This is true by + // default. + asyncGraphCachePopulation bool } // defaultChanGraphOptions returns a new chanGraphOptions instance populated // with default values. func defaultChanGraphOptions() *chanGraphOptions { return &chanGraphOptions{ - useGraphCache: true, - preAllocCacheNumNodes: DefaultPreAllocCacheNumNodes, + useGraphCache: true, + asyncGraphCachePopulation: true, + preAllocCacheNumNodes: DefaultPreAllocCacheNumNodes, } } @@ -115,6 +122,25 @@ func WithPreAllocCacheNumNodes(n int) ChanGraphOption { } } +// WithAsyncGraphCachePopulation sets whether the graph cache should be +// populated asynchronously or if the Start method should block until the +// cache is fully populated. +func WithAsyncGraphCachePopulation(async bool) ChanGraphOption { + return func(o *chanGraphOptions) { + o.asyncGraphCachePopulation = async + } +} + +// WithSyncGraphCachePopulation will cause the ChannelGraph to block +// until the graph cache is fully populated before returning from the Start +// method. This is useful for tests that need to ensure the graph cache is +// fully populated before proceeding with further operations. +func WithSyncGraphCachePopulation() ChanGraphOption { + return func(o *chanGraphOptions) { + o.asyncGraphCachePopulation = false + } +} + // StoreOptions holds parameters for tuning and customizing a graph DB. type StoreOptions struct { // RejectCacheSize is the maximum number of rejectCacheEntries to hold From eb04d405a2898fcfa2f0e337e85a36dbbe9cd47e Mon Sep 17 00:00:00 2001 From: Elle Mouton Date: Thu, 10 Jul 2025 14:05:37 +0200 Subject: [PATCH 7/9] multi: add --db.sync-graph-cache-load option Add a new option to opt out of the new asynchronous graph cache loading feature. --- config_builder.go | 3 +++ lncfg/db.go | 2 ++ sample-lnd.conf | 6 ++++++ 3 files changed, 11 insertions(+) diff --git a/config_builder.go b/config_builder.go index 647d265bd..0f563d6f2 100644 --- a/config_builder.go +++ b/config_builder.go @@ -1056,6 +1056,9 @@ func (d *DefaultDatabaseBuilder) BuildDatabase( chanGraphOpts := []graphdb.ChanGraphOption{ graphdb.WithUseGraphCache(!cfg.DB.NoGraphCache), + graphdb.WithAsyncGraphCachePopulation( + !cfg.DB.SyncGraphCacheLoad, + ), } // We want to pre-allocate the channel graph cache according to what we diff --git a/lncfg/db.go b/lncfg/db.go index 6835382e2..4a8680b38 100644 --- a/lncfg/db.go +++ b/lncfg/db.go @@ -89,6 +89,8 @@ type DB struct { NoGraphCache bool `long:"no-graph-cache" description:"Don't use the in-memory graph cache for path finding. Much slower but uses less RAM. Can only be used with a bolt database backend."` + SyncGraphCacheLoad bool `long:"sync-graph-cache-load" description:"Force synchronous loading of the graph cache. This will block the startup until the graph cache is fully loaded into memory. This is useful if any bugs appear with the new async loading feature of the graph cache."` + PruneRevocation bool `long:"prune-revocation" description:"Run the optional migration that prunes the revocation logs to save disk space."` NoRevLogAmtData bool `long:"no-rev-log-amt-data" description:"If set, the to-local and to-remote output amounts of revoked commitment transactions will not be stored in the revocation log. Note that once this data is lost, a watchtower client will not be able to back up the revoked state."` diff --git a/sample-lnd.conf b/sample-lnd.conf index f874fadcb..6f3d84934 100644 --- a/sample-lnd.conf +++ b/sample-lnd.conf @@ -1501,6 +1501,12 @@ ; less RAM. Can only be used with a bolt database backend. ; db.no-graph-cache=false +; Block the start-up of LND until the graph cache has been fully populated. +; If not set, the graph cache will be populated asynchronously and any read +; calls made before the cache is fully populated will fall back to the +; database. +; db.sync-graph-cache-load=false + ; Specify whether the optional migration for pruning old revocation logs ; should be applied. This migration will only save disk space if there are open ; channels prior to lnd@v0.15.0. From 844d0460a1ff42e047145243d9cd87053bb81e43 Mon Sep 17 00:00:00 2001 From: Elle Mouton Date: Fri, 6 Mar 2026 10:24:22 +0200 Subject: [PATCH 8/9] lnrpc: expose graph cache state in GetInfo Add a GraphCacheStatus enum to GetInfoResponse so callers can tell whether the graph cache is disabled, still loading, or fully loaded. This makes the async graph cache startup state visible to operators and clients without changing the existing DB fallback behaviour for reads. --- graph/db/graph.go | 37 + graph/db/graph_test.go | 92 +++ lnrpc/lightning.pb.go | 1331 ++++++++++++++++++---------------- lnrpc/lightning.proto | 10 + lnrpc/lightning.swagger.json | 14 + rpcserver.go | 23 + 6 files changed, 876 insertions(+), 631 deletions(-) diff --git a/graph/db/graph.go b/graph/db/graph.go index e7ed585c5..507312f65 100644 --- a/graph/db/graph.go +++ b/graph/db/graph.go @@ -26,6 +26,26 @@ import ( // busy shutting down. var ErrChanGraphShuttingDown = fmt.Errorf("ChannelGraph shutting down") +// GraphCacheStatus describes the current state of the in-memory graph cache. +type GraphCacheStatus uint8 + +const ( + // GraphCacheStatusDisabled indicates that the graph cache is disabled. + GraphCacheStatusDisabled GraphCacheStatus = iota + + // GraphCacheStatusLoading indicates that the graph cache is still + // being populated from the DB and is not yet serving reads. + GraphCacheStatusLoading + + // GraphCacheStatusLoaded indicates that the graph cache has + // completed its initial population and is serving reads. + GraphCacheStatusLoaded + + // GraphCacheStatusFailed indicates that the initial population of + // the graph cache failed. Reads fall back to the database. + GraphCacheStatusFailed +) + // ChannelGraph is a layer above the graph's CRUD layer. type ChannelGraph struct { started atomic.Bool @@ -68,6 +88,23 @@ func NewChannelGraph(v1Store Store, return g, nil } +// GraphCacheStatus returns the current state of the in-memory graph cache. +func (c *ChannelGraph) GraphCacheStatus() GraphCacheStatus { + switch { + case c.cache == nil: + return GraphCacheStatusDisabled + + case c.cache.isLoaded(): + return GraphCacheStatusLoaded + + case c.cache.isFailed(): + return GraphCacheStatusFailed + + default: + return GraphCacheStatusLoading + } +} + // Start kicks off any goroutines required for the ChannelGraph to function. // If the graph cache is enabled, then it will be populated with the contents of // the database. diff --git a/graph/db/graph_test.go b/graph/db/graph_test.go index f82ed51c8..46ac8d0ec 100644 --- a/graph/db/graph_test.go +++ b/graph/db/graph_test.go @@ -5538,6 +5538,11 @@ func TestAsyncGraphCachePopulationFailureFallsBackToDB(t *testing.T) { }) <-failingStore.cacheLoadAttempted + + err = wait.Predicate(func() bool { + return graph.GraphCacheStatus() == GraphCacheStatusFailed + }, wait.DefaultTimeout) + require.NoError(t, err) require.False(t, graph.cache.isLoaded()) var numChannels int @@ -5560,6 +5565,93 @@ func TestAsyncGraphCachePopulationFailureFallsBackToDB(t *testing.T) { require.Equal(t, 1, numChannels) } +// TestGraphCacheStatus asserts that the graph cache reports disabled, loading, +// loaded and failed states as expected. +func TestGraphCacheStatus(t *testing.T) { + t.Parallel() + ctx := t.Context() + + store := NewTestDB(t) + + disabledGraph, err := NewChannelGraph( + store, WithUseGraphCache(false), + ) + require.NoError(t, err) + require.Equal( + t, GraphCacheStatusDisabled, disabledGraph.GraphCacheStatus(), + ) + require.NoError(t, disabledGraph.Start()) + require.Equal( + t, GraphCacheStatusDisabled, disabledGraph.GraphCacheStatus(), + ) + require.NoError(t, disabledGraph.Stop()) + + setupGraph, err := NewChannelGraph( + store, WithSyncGraphCachePopulation(), + ) + require.NoError(t, err) + require.NoError(t, setupGraph.Start()) + + node1 := createTestVertex(t, lnwire.GossipVersion1) + require.NoError(t, setupGraph.AddNode(ctx, node1)) + node2 := createTestVertex(t, lnwire.GossipVersion1) + require.NoError(t, setupGraph.AddNode(ctx, node2)) + + edgeInfo, edge1, edge2 := createChannelEdge( + node1, node2, lnwire.GossipVersion1, + ) + require.NoError(t, setupGraph.AddChannelEdge(ctx, edgeInfo)) + require.NoError(t, setupGraph.UpdateEdgePolicy(ctx, edge1)) + require.NoError(t, setupGraph.UpdateEdgePolicy(ctx, edge2)) + require.NoError(t, setupGraph.Stop()) + + blockingStore := &blockingCacheLoadStore{ + Store: store, + cacheLoadStarted: make(chan struct{}), + allowCacheLoad: make(chan struct{}), + } + + graph, err := NewChannelGraph(blockingStore) + require.NoError(t, err) + require.Equal(t, GraphCacheStatusLoading, graph.GraphCacheStatus()) + require.NoError(t, graph.Start()) + t.Cleanup(func() { + require.NoError(t, graph.Stop()) + }) + + <-blockingStore.cacheLoadStarted + require.Equal(t, GraphCacheStatusLoading, graph.GraphCacheStatus()) + + close(blockingStore.allowCacheLoad) + err = wait.Predicate(func() bool { + return graph.GraphCacheStatus() == GraphCacheStatusLoaded + }, wait.DefaultTimeout) + require.NoError(t, err) + require.NoError(t, graph.Stop()) + + // Assert the failed state by using a store that errors during cache + // population. + populateErr := errors.New("cache population failed") + failingStore := &failingCacheLoadStore{ + Store: store, + cacheLoadAttempted: make(chan struct{}), + populateErr: populateErr, + } + + failedGraph, err := NewChannelGraph(failingStore) + require.NoError(t, err) + require.NoError(t, failedGraph.Start()) + t.Cleanup(func() { + require.NoError(t, failedGraph.Stop()) + }) + + <-failingStore.cacheLoadAttempted + err = wait.Predicate(func() bool { + return failedGraph.GraphCacheStatus() == GraphCacheStatusFailed + }, wait.DefaultTimeout) + require.NoError(t, err) +} + // TestKVCacheableIteratorsRespectCancellation asserts that KV-backed cache // iterators return when their context is canceled. func TestKVCacheableIteratorsRespectCancellation(t *testing.T) { diff --git a/lnrpc/lightning.pb.go b/lnrpc/lightning.pb.go index d987f7504..3e1cf4dc7 100644 --- a/lnrpc/lightning.pb.go +++ b/lnrpc/lightning.pb.go @@ -472,6 +472,58 @@ func (ResolutionOutcome) EnumDescriptor() ([]byte, []int) { return file_lightning_proto_rawDescGZIP(), []int{6} } +type GraphCacheStatus int32 + +const ( + GraphCacheStatus_GRAPH_CACHE_STATUS_DISABLED GraphCacheStatus = 0 + GraphCacheStatus_GRAPH_CACHE_STATUS_LOADING GraphCacheStatus = 1 + GraphCacheStatus_GRAPH_CACHE_STATUS_LOADED GraphCacheStatus = 2 + GraphCacheStatus_GRAPH_CACHE_STATUS_FAILED GraphCacheStatus = 3 +) + +// Enum value maps for GraphCacheStatus. +var ( + GraphCacheStatus_name = map[int32]string{ + 0: "GRAPH_CACHE_STATUS_DISABLED", + 1: "GRAPH_CACHE_STATUS_LOADING", + 2: "GRAPH_CACHE_STATUS_LOADED", + 3: "GRAPH_CACHE_STATUS_FAILED", + } + GraphCacheStatus_value = map[string]int32{ + "GRAPH_CACHE_STATUS_DISABLED": 0, + "GRAPH_CACHE_STATUS_LOADING": 1, + "GRAPH_CACHE_STATUS_LOADED": 2, + "GRAPH_CACHE_STATUS_FAILED": 3, + } +) + +func (x GraphCacheStatus) Enum() *GraphCacheStatus { + p := new(GraphCacheStatus) + *p = x + return p +} + +func (x GraphCacheStatus) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (GraphCacheStatus) Descriptor() protoreflect.EnumDescriptor { + return file_lightning_proto_enumTypes[7].Descriptor() +} + +func (GraphCacheStatus) Type() protoreflect.EnumType { + return &file_lightning_proto_enumTypes[7] +} + +func (x GraphCacheStatus) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use GraphCacheStatus.Descriptor instead. +func (GraphCacheStatus) EnumDescriptor() ([]byte, []int) { + return file_lightning_proto_rawDescGZIP(), []int{7} +} + type NodeMetricType int32 const ( @@ -502,11 +554,11 @@ func (x NodeMetricType) String() string { } func (NodeMetricType) Descriptor() protoreflect.EnumDescriptor { - return file_lightning_proto_enumTypes[7].Descriptor() + return file_lightning_proto_enumTypes[8].Descriptor() } func (NodeMetricType) Type() protoreflect.EnumType { - return &file_lightning_proto_enumTypes[7] + return &file_lightning_proto_enumTypes[8] } func (x NodeMetricType) Number() protoreflect.EnumNumber { @@ -515,7 +567,7 @@ func (x NodeMetricType) Number() protoreflect.EnumNumber { // Deprecated: Use NodeMetricType.Descriptor instead. func (NodeMetricType) EnumDescriptor() ([]byte, []int) { - return file_lightning_proto_rawDescGZIP(), []int{7} + return file_lightning_proto_rawDescGZIP(), []int{8} } type InvoiceHTLCState int32 @@ -551,11 +603,11 @@ func (x InvoiceHTLCState) String() string { } func (InvoiceHTLCState) Descriptor() protoreflect.EnumDescriptor { - return file_lightning_proto_enumTypes[8].Descriptor() + return file_lightning_proto_enumTypes[9].Descriptor() } func (InvoiceHTLCState) Type() protoreflect.EnumType { - return &file_lightning_proto_enumTypes[8] + return &file_lightning_proto_enumTypes[9] } func (x InvoiceHTLCState) Number() protoreflect.EnumNumber { @@ -564,7 +616,7 @@ func (x InvoiceHTLCState) Number() protoreflect.EnumNumber { // Deprecated: Use InvoiceHTLCState.Descriptor instead. func (InvoiceHTLCState) EnumDescriptor() ([]byte, []int) { - return file_lightning_proto_rawDescGZIP(), []int{8} + return file_lightning_proto_rawDescGZIP(), []int{9} } type PaymentFailureReason int32 @@ -621,11 +673,11 @@ func (x PaymentFailureReason) String() string { } func (PaymentFailureReason) Descriptor() protoreflect.EnumDescriptor { - return file_lightning_proto_enumTypes[9].Descriptor() + return file_lightning_proto_enumTypes[10].Descriptor() } func (PaymentFailureReason) Type() protoreflect.EnumType { - return &file_lightning_proto_enumTypes[9] + return &file_lightning_proto_enumTypes[10] } func (x PaymentFailureReason) Number() protoreflect.EnumNumber { @@ -634,7 +686,7 @@ func (x PaymentFailureReason) Number() protoreflect.EnumNumber { // Deprecated: Use PaymentFailureReason.Descriptor instead. func (PaymentFailureReason) EnumDescriptor() ([]byte, []int) { - return file_lightning_proto_rawDescGZIP(), []int{9} + return file_lightning_proto_rawDescGZIP(), []int{10} } type FeatureBit int32 @@ -742,11 +794,11 @@ func (x FeatureBit) String() string { } func (FeatureBit) Descriptor() protoreflect.EnumDescriptor { - return file_lightning_proto_enumTypes[10].Descriptor() + return file_lightning_proto_enumTypes[11].Descriptor() } func (FeatureBit) Type() protoreflect.EnumType { - return &file_lightning_proto_enumTypes[10] + return &file_lightning_proto_enumTypes[11] } func (x FeatureBit) Number() protoreflect.EnumNumber { @@ -755,7 +807,7 @@ func (x FeatureBit) Number() protoreflect.EnumNumber { // Deprecated: Use FeatureBit.Descriptor instead. func (FeatureBit) EnumDescriptor() ([]byte, []int) { - return file_lightning_proto_rawDescGZIP(), []int{10} + return file_lightning_proto_rawDescGZIP(), []int{11} } type UpdateFailure int32 @@ -797,11 +849,11 @@ func (x UpdateFailure) String() string { } func (UpdateFailure) Descriptor() protoreflect.EnumDescriptor { - return file_lightning_proto_enumTypes[11].Descriptor() + return file_lightning_proto_enumTypes[12].Descriptor() } func (UpdateFailure) Type() protoreflect.EnumType { - return &file_lightning_proto_enumTypes[11] + return &file_lightning_proto_enumTypes[12] } func (x UpdateFailure) Number() protoreflect.EnumNumber { @@ -810,7 +862,7 @@ func (x UpdateFailure) Number() protoreflect.EnumNumber { // Deprecated: Use UpdateFailure.Descriptor instead. func (UpdateFailure) EnumDescriptor() ([]byte, []int) { - return file_lightning_proto_rawDescGZIP(), []int{11} + return file_lightning_proto_rawDescGZIP(), []int{12} } type ChannelCloseSummary_ClosureType int32 @@ -855,11 +907,11 @@ func (x ChannelCloseSummary_ClosureType) String() string { } func (ChannelCloseSummary_ClosureType) Descriptor() protoreflect.EnumDescriptor { - return file_lightning_proto_enumTypes[12].Descriptor() + return file_lightning_proto_enumTypes[13].Descriptor() } func (ChannelCloseSummary_ClosureType) Type() protoreflect.EnumType { - return &file_lightning_proto_enumTypes[12] + return &file_lightning_proto_enumTypes[13] } func (x ChannelCloseSummary_ClosureType) Number() protoreflect.EnumNumber { @@ -911,11 +963,11 @@ func (x Peer_SyncType) String() string { } func (Peer_SyncType) Descriptor() protoreflect.EnumDescriptor { - return file_lightning_proto_enumTypes[13].Descriptor() + return file_lightning_proto_enumTypes[14].Descriptor() } func (Peer_SyncType) Type() protoreflect.EnumType { - return &file_lightning_proto_enumTypes[13] + return &file_lightning_proto_enumTypes[14] } func (x Peer_SyncType) Number() protoreflect.EnumNumber { @@ -957,11 +1009,11 @@ func (x PeerEvent_EventType) String() string { } func (PeerEvent_EventType) Descriptor() protoreflect.EnumDescriptor { - return file_lightning_proto_enumTypes[14].Descriptor() + return file_lightning_proto_enumTypes[15].Descriptor() } func (PeerEvent_EventType) Type() protoreflect.EnumType { - return &file_lightning_proto_enumTypes[14] + return &file_lightning_proto_enumTypes[15] } func (x PeerEvent_EventType) Number() protoreflect.EnumNumber { @@ -1012,11 +1064,11 @@ func (x PendingChannelsResponse_ForceClosedChannel_AnchorState) String() string } func (PendingChannelsResponse_ForceClosedChannel_AnchorState) Descriptor() protoreflect.EnumDescriptor { - return file_lightning_proto_enumTypes[15].Descriptor() + return file_lightning_proto_enumTypes[16].Descriptor() } func (PendingChannelsResponse_ForceClosedChannel_AnchorState) Type() protoreflect.EnumType { - return &file_lightning_proto_enumTypes[15] + return &file_lightning_proto_enumTypes[16] } func (x PendingChannelsResponse_ForceClosedChannel_AnchorState) Number() protoreflect.EnumNumber { @@ -1076,11 +1128,11 @@ func (x ChannelEventUpdate_UpdateType) String() string { } func (ChannelEventUpdate_UpdateType) Descriptor() protoreflect.EnumDescriptor { - return file_lightning_proto_enumTypes[16].Descriptor() + return file_lightning_proto_enumTypes[17].Descriptor() } func (ChannelEventUpdate_UpdateType) Type() protoreflect.EnumType { - return &file_lightning_proto_enumTypes[16] + return &file_lightning_proto_enumTypes[17] } func (x ChannelEventUpdate_UpdateType) Number() protoreflect.EnumNumber { @@ -1128,11 +1180,11 @@ func (x Invoice_InvoiceState) String() string { } func (Invoice_InvoiceState) Descriptor() protoreflect.EnumDescriptor { - return file_lightning_proto_enumTypes[17].Descriptor() + return file_lightning_proto_enumTypes[18].Descriptor() } func (Invoice_InvoiceState) Type() protoreflect.EnumType { - return &file_lightning_proto_enumTypes[17] + return &file_lightning_proto_enumTypes[18] } func (x Invoice_InvoiceState) Number() protoreflect.EnumNumber { @@ -1190,11 +1242,11 @@ func (x Payment_PaymentStatus) String() string { } func (Payment_PaymentStatus) Descriptor() protoreflect.EnumDescriptor { - return file_lightning_proto_enumTypes[18].Descriptor() + return file_lightning_proto_enumTypes[19].Descriptor() } func (Payment_PaymentStatus) Type() protoreflect.EnumType { - return &file_lightning_proto_enumTypes[18] + return &file_lightning_proto_enumTypes[19] } func (x Payment_PaymentStatus) Number() protoreflect.EnumNumber { @@ -1239,11 +1291,11 @@ func (x HTLCAttempt_HTLCStatus) String() string { } func (HTLCAttempt_HTLCStatus) Descriptor() protoreflect.EnumDescriptor { - return file_lightning_proto_enumTypes[19].Descriptor() + return file_lightning_proto_enumTypes[20].Descriptor() } func (HTLCAttempt_HTLCStatus) Type() protoreflect.EnumType { - return &file_lightning_proto_enumTypes[19] + return &file_lightning_proto_enumTypes[20] } func (x HTLCAttempt_HTLCStatus) Number() protoreflect.EnumNumber { @@ -1373,11 +1425,11 @@ func (x Failure_FailureCode) String() string { } func (Failure_FailureCode) Descriptor() protoreflect.EnumDescriptor { - return file_lightning_proto_enumTypes[20].Descriptor() + return file_lightning_proto_enumTypes[21].Descriptor() } func (Failure_FailureCode) Type() protoreflect.EnumType { - return &file_lightning_proto_enumTypes[20] + return &file_lightning_proto_enumTypes[21] } func (x Failure_FailureCode) Number() protoreflect.EnumNumber { @@ -6416,9 +6468,11 @@ type GetInfoResponse struct { StoreFinalHtlcResolutions bool `protobuf:"varint,22,opt,name=store_final_htlc_resolutions,json=storeFinalHtlcResolutions,proto3" json:"store_final_htlc_resolutions,omitempty"` // Whether the wallet is fully synced to the best chain. This indicates the // wallet's internal sync state with the backing chain source. - WalletSynced bool `protobuf:"varint,23,opt,name=wallet_synced,json=walletSynced,proto3" json:"wallet_synced,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + WalletSynced bool `protobuf:"varint,23,opt,name=wallet_synced,json=walletSynced,proto3" json:"wallet_synced,omitempty"` + // The current status of the in-memory graph cache. + GraphCacheStatus GraphCacheStatus `protobuf:"varint,24,opt,name=graph_cache_status,json=graphCacheStatus,proto3,enum=lnrpc.GraphCacheStatus" json:"graph_cache_status,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *GetInfoResponse) Reset() { @@ -6599,6 +6653,13 @@ func (x *GetInfoResponse) GetWalletSynced() bool { return false } +func (x *GetInfoResponse) GetGraphCacheStatus() GraphCacheStatus { + if x != nil { + return x.GraphCacheStatus + } + return GraphCacheStatus_GRAPH_CACHE_STATUS_DISABLED +} + type GetDebugInfoRequest struct { state protoimpl.MessageState `protogen:"open.v1"` // If set to true, the log file content will be included in the response. @@ -19182,7 +19243,7 @@ const file_lightning_proto_rawDesc = "" + "\tEventType\x12\x0f\n" + "\vPEER_ONLINE\x10\x00\x12\x10\n" + "\fPEER_OFFLINE\x10\x01\"\x10\n" + - "\x0eGetInfoRequest\"\xa7\a\n" + + "\x0eGetInfoRequest\"\xee\a\n" + "\x0fGetInfoResponse\x12\x18\n" + "\aversion\x18\x0e \x01(\tR\aversion\x12\x1f\n" + "\vcommit_hash\x18\x14 \x01(\tR\n" + @@ -19207,7 +19268,8 @@ const file_lightning_proto_rawDesc = "" + "\bfeatures\x18\x13 \x03(\v2$.lnrpc.GetInfoResponse.FeaturesEntryR\bfeatures\x128\n" + "\x18require_htlc_interceptor\x18\x15 \x01(\bR\x16requireHtlcInterceptor\x12?\n" + "\x1cstore_final_htlc_resolutions\x18\x16 \x01(\bR\x19storeFinalHtlcResolutions\x12#\n" + - "\rwallet_synced\x18\x17 \x01(\bR\fwalletSynced\x1aK\n" + + "\rwallet_synced\x18\x17 \x01(\bR\fwalletSynced\x12E\n" + + "\x12graph_cache_status\x18\x18 \x01(\x0e2\x17.lnrpc.GraphCacheStatusR\x10graphCacheStatus\x1aK\n" + "\rFeaturesEntry\x12\x10\n" + "\x03key\x18\x01 \x01(\rR\x03key\x12$\n" + "\x05value\x18\x02 \x01(\v2\x0e.lnrpc.FeatureR\x05value:\x028\x01J\x04\b\v\x10\f\"6\n" + @@ -20295,7 +20357,12 @@ const file_lightning_proto_rawDesc = "" + "\tUNCLAIMED\x10\x02\x12\r\n" + "\tABANDONED\x10\x03\x12\x0f\n" + "\vFIRST_STAGE\x10\x04\x12\v\n" + - "\aTIMEOUT\x10\x05*9\n" + + "\aTIMEOUT\x10\x05*\x91\x01\n" + + "\x10GraphCacheStatus\x12\x1f\n" + + "\x1bGRAPH_CACHE_STATUS_DISABLED\x10\x00\x12\x1e\n" + + "\x1aGRAPH_CACHE_STATUS_LOADING\x10\x01\x12\x1d\n" + + "\x19GRAPH_CACHE_STATUS_LOADED\x10\x02\x12\x1d\n" + + "\x19GRAPH_CACHE_STATUS_FAILED\x10\x03*9\n" + "\x0eNodeMetricType\x12\v\n" + "\aUNKNOWN\x10\x00\x12\x1a\n" + "\x16BETWEENNESS_CENTRALITY\x10\x01*;\n" + @@ -20436,7 +20503,7 @@ func file_lightning_proto_rawDescGZIP() []byte { return file_lightning_proto_rawDescData } -var file_lightning_proto_enumTypes = make([]protoimpl.EnumInfo, 21) +var file_lightning_proto_enumTypes = make([]protoimpl.EnumInfo, 22) var file_lightning_proto_msgTypes = make([]protoimpl.MessageInfo, 238) var file_lightning_proto_goTypes = []any{ (OutputScriptType)(0), // 0: lnrpc.OutputScriptType @@ -20446,610 +20513,612 @@ var file_lightning_proto_goTypes = []any{ (Initiator)(0), // 4: lnrpc.Initiator (ResolutionType)(0), // 5: lnrpc.ResolutionType (ResolutionOutcome)(0), // 6: lnrpc.ResolutionOutcome - (NodeMetricType)(0), // 7: lnrpc.NodeMetricType - (InvoiceHTLCState)(0), // 8: lnrpc.InvoiceHTLCState - (PaymentFailureReason)(0), // 9: lnrpc.PaymentFailureReason - (FeatureBit)(0), // 10: lnrpc.FeatureBit - (UpdateFailure)(0), // 11: lnrpc.UpdateFailure - (ChannelCloseSummary_ClosureType)(0), // 12: lnrpc.ChannelCloseSummary.ClosureType - (Peer_SyncType)(0), // 13: lnrpc.Peer.SyncType - (PeerEvent_EventType)(0), // 14: lnrpc.PeerEvent.EventType - (PendingChannelsResponse_ForceClosedChannel_AnchorState)(0), // 15: lnrpc.PendingChannelsResponse.ForceClosedChannel.AnchorState - (ChannelEventUpdate_UpdateType)(0), // 16: lnrpc.ChannelEventUpdate.UpdateType - (Invoice_InvoiceState)(0), // 17: lnrpc.Invoice.InvoiceState - (Payment_PaymentStatus)(0), // 18: lnrpc.Payment.PaymentStatus - (HTLCAttempt_HTLCStatus)(0), // 19: lnrpc.HTLCAttempt.HTLCStatus - (Failure_FailureCode)(0), // 20: lnrpc.Failure.FailureCode - (*LookupHtlcResolutionRequest)(nil), // 21: lnrpc.LookupHtlcResolutionRequest - (*LookupHtlcResolutionResponse)(nil), // 22: lnrpc.LookupHtlcResolutionResponse - (*SubscribeCustomMessagesRequest)(nil), // 23: lnrpc.SubscribeCustomMessagesRequest - (*CustomMessage)(nil), // 24: lnrpc.CustomMessage - (*SendCustomMessageRequest)(nil), // 25: lnrpc.SendCustomMessageRequest - (*SendCustomMessageResponse)(nil), // 26: lnrpc.SendCustomMessageResponse - (*SubscribeOnionMessagesRequest)(nil), // 27: lnrpc.SubscribeOnionMessagesRequest - (*OnionMessageUpdate)(nil), // 28: lnrpc.OnionMessageUpdate - (*SendOnionMessageRequest)(nil), // 29: lnrpc.SendOnionMessageRequest - (*SendOnionMessageResponse)(nil), // 30: lnrpc.SendOnionMessageResponse - (*Utxo)(nil), // 31: lnrpc.Utxo - (*OutputDetail)(nil), // 32: lnrpc.OutputDetail - (*Transaction)(nil), // 33: lnrpc.Transaction - (*GetTransactionsRequest)(nil), // 34: lnrpc.GetTransactionsRequest - (*TransactionDetails)(nil), // 35: lnrpc.TransactionDetails - (*FeeLimit)(nil), // 36: lnrpc.FeeLimit - (*SendRequest)(nil), // 37: lnrpc.SendRequest - (*SendResponse)(nil), // 38: lnrpc.SendResponse - (*SendToRouteRequest)(nil), // 39: lnrpc.SendToRouteRequest - (*ChannelAcceptRequest)(nil), // 40: lnrpc.ChannelAcceptRequest - (*ChannelAcceptResponse)(nil), // 41: lnrpc.ChannelAcceptResponse - (*ChannelPoint)(nil), // 42: lnrpc.ChannelPoint - (*OutPoint)(nil), // 43: lnrpc.OutPoint - (*PreviousOutPoint)(nil), // 44: lnrpc.PreviousOutPoint - (*LightningAddress)(nil), // 45: lnrpc.LightningAddress - (*EstimateFeeRequest)(nil), // 46: lnrpc.EstimateFeeRequest - (*EstimateFeeResponse)(nil), // 47: lnrpc.EstimateFeeResponse - (*SendManyRequest)(nil), // 48: lnrpc.SendManyRequest - (*SendManyResponse)(nil), // 49: lnrpc.SendManyResponse - (*SendCoinsRequest)(nil), // 50: lnrpc.SendCoinsRequest - (*SendCoinsResponse)(nil), // 51: lnrpc.SendCoinsResponse - (*ListUnspentRequest)(nil), // 52: lnrpc.ListUnspentRequest - (*ListUnspentResponse)(nil), // 53: lnrpc.ListUnspentResponse - (*NewAddressRequest)(nil), // 54: lnrpc.NewAddressRequest - (*NewAddressResponse)(nil), // 55: lnrpc.NewAddressResponse - (*SignMessageRequest)(nil), // 56: lnrpc.SignMessageRequest - (*SignMessageResponse)(nil), // 57: lnrpc.SignMessageResponse - (*VerifyMessageRequest)(nil), // 58: lnrpc.VerifyMessageRequest - (*VerifyMessageResponse)(nil), // 59: lnrpc.VerifyMessageResponse - (*ConnectPeerRequest)(nil), // 60: lnrpc.ConnectPeerRequest - (*ConnectPeerResponse)(nil), // 61: lnrpc.ConnectPeerResponse - (*DisconnectPeerRequest)(nil), // 62: lnrpc.DisconnectPeerRequest - (*DisconnectPeerResponse)(nil), // 63: lnrpc.DisconnectPeerResponse - (*HTLC)(nil), // 64: lnrpc.HTLC - (*ChannelConstraints)(nil), // 65: lnrpc.ChannelConstraints - (*Channel)(nil), // 66: lnrpc.Channel - (*ListChannelsRequest)(nil), // 67: lnrpc.ListChannelsRequest - (*ListChannelsResponse)(nil), // 68: lnrpc.ListChannelsResponse - (*AliasMap)(nil), // 69: lnrpc.AliasMap - (*ListAliasesRequest)(nil), // 70: lnrpc.ListAliasesRequest - (*ListAliasesResponse)(nil), // 71: lnrpc.ListAliasesResponse - (*ChannelCloseSummary)(nil), // 72: lnrpc.ChannelCloseSummary - (*Resolution)(nil), // 73: lnrpc.Resolution - (*ClosedChannelsRequest)(nil), // 74: lnrpc.ClosedChannelsRequest - (*ClosedChannelsResponse)(nil), // 75: lnrpc.ClosedChannelsResponse - (*Peer)(nil), // 76: lnrpc.Peer - (*TimestampedError)(nil), // 77: lnrpc.TimestampedError - (*ListPeersRequest)(nil), // 78: lnrpc.ListPeersRequest - (*ListPeersResponse)(nil), // 79: lnrpc.ListPeersResponse - (*PeerEventSubscription)(nil), // 80: lnrpc.PeerEventSubscription - (*PeerEvent)(nil), // 81: lnrpc.PeerEvent - (*GetInfoRequest)(nil), // 82: lnrpc.GetInfoRequest - (*GetInfoResponse)(nil), // 83: lnrpc.GetInfoResponse - (*GetDebugInfoRequest)(nil), // 84: lnrpc.GetDebugInfoRequest - (*GetDebugInfoResponse)(nil), // 85: lnrpc.GetDebugInfoResponse - (*GetRecoveryInfoRequest)(nil), // 86: lnrpc.GetRecoveryInfoRequest - (*GetRecoveryInfoResponse)(nil), // 87: lnrpc.GetRecoveryInfoResponse - (*Chain)(nil), // 88: lnrpc.Chain - (*ChannelOpenUpdate)(nil), // 89: lnrpc.ChannelOpenUpdate - (*CloseOutput)(nil), // 90: lnrpc.CloseOutput - (*ChannelCloseUpdate)(nil), // 91: lnrpc.ChannelCloseUpdate - (*CloseChannelRequest)(nil), // 92: lnrpc.CloseChannelRequest - (*CloseStatusUpdate)(nil), // 93: lnrpc.CloseStatusUpdate - (*PendingUpdate)(nil), // 94: lnrpc.PendingUpdate - (*InstantUpdate)(nil), // 95: lnrpc.InstantUpdate - (*ReadyForPsbtFunding)(nil), // 96: lnrpc.ReadyForPsbtFunding - (*BatchOpenChannelRequest)(nil), // 97: lnrpc.BatchOpenChannelRequest - (*BatchOpenChannel)(nil), // 98: lnrpc.BatchOpenChannel - (*BatchOpenChannelResponse)(nil), // 99: lnrpc.BatchOpenChannelResponse - (*OpenChannelRequest)(nil), // 100: lnrpc.OpenChannelRequest - (*OpenStatusUpdate)(nil), // 101: lnrpc.OpenStatusUpdate - (*KeyLocator)(nil), // 102: lnrpc.KeyLocator - (*KeyDescriptor)(nil), // 103: lnrpc.KeyDescriptor - (*ChanPointShim)(nil), // 104: lnrpc.ChanPointShim - (*PsbtShim)(nil), // 105: lnrpc.PsbtShim - (*FundingShim)(nil), // 106: lnrpc.FundingShim - (*FundingShimCancel)(nil), // 107: lnrpc.FundingShimCancel - (*FundingPsbtVerify)(nil), // 108: lnrpc.FundingPsbtVerify - (*FundingPsbtFinalize)(nil), // 109: lnrpc.FundingPsbtFinalize - (*FundingTransitionMsg)(nil), // 110: lnrpc.FundingTransitionMsg - (*FundingStateStepResp)(nil), // 111: lnrpc.FundingStateStepResp - (*PendingHTLC)(nil), // 112: lnrpc.PendingHTLC - (*PendingChannelsRequest)(nil), // 113: lnrpc.PendingChannelsRequest - (*PendingChannelsResponse)(nil), // 114: lnrpc.PendingChannelsResponse - (*ChannelEventSubscription)(nil), // 115: lnrpc.ChannelEventSubscription - (*ChannelCommitUpdate)(nil), // 116: lnrpc.ChannelCommitUpdate - (*ChannelEventUpdate)(nil), // 117: lnrpc.ChannelEventUpdate - (*WalletAccountBalance)(nil), // 118: lnrpc.WalletAccountBalance - (*WalletBalanceRequest)(nil), // 119: lnrpc.WalletBalanceRequest - (*WalletBalanceResponse)(nil), // 120: lnrpc.WalletBalanceResponse - (*Amount)(nil), // 121: lnrpc.Amount - (*ChannelBalanceRequest)(nil), // 122: lnrpc.ChannelBalanceRequest - (*ChannelBalanceResponse)(nil), // 123: lnrpc.ChannelBalanceResponse - (*QueryRoutesRequest)(nil), // 124: lnrpc.QueryRoutesRequest - (*NodePair)(nil), // 125: lnrpc.NodePair - (*EdgeLocator)(nil), // 126: lnrpc.EdgeLocator - (*QueryRoutesResponse)(nil), // 127: lnrpc.QueryRoutesResponse - (*Hop)(nil), // 128: lnrpc.Hop - (*MPPRecord)(nil), // 129: lnrpc.MPPRecord - (*AMPRecord)(nil), // 130: lnrpc.AMPRecord - (*Route)(nil), // 131: lnrpc.Route - (*NodeInfoRequest)(nil), // 132: lnrpc.NodeInfoRequest - (*NodeInfo)(nil), // 133: lnrpc.NodeInfo - (*LightningNode)(nil), // 134: lnrpc.LightningNode - (*NodeAddress)(nil), // 135: lnrpc.NodeAddress - (*RoutingPolicy)(nil), // 136: lnrpc.RoutingPolicy - (*ChannelAuthProof)(nil), // 137: lnrpc.ChannelAuthProof - (*ChannelEdge)(nil), // 138: lnrpc.ChannelEdge - (*ChannelGraphRequest)(nil), // 139: lnrpc.ChannelGraphRequest - (*ChannelGraph)(nil), // 140: lnrpc.ChannelGraph - (*NodeMetricsRequest)(nil), // 141: lnrpc.NodeMetricsRequest - (*NodeMetricsResponse)(nil), // 142: lnrpc.NodeMetricsResponse - (*FloatMetric)(nil), // 143: lnrpc.FloatMetric - (*ChanInfoRequest)(nil), // 144: lnrpc.ChanInfoRequest - (*NetworkInfoRequest)(nil), // 145: lnrpc.NetworkInfoRequest - (*NetworkInfo)(nil), // 146: lnrpc.NetworkInfo - (*StopRequest)(nil), // 147: lnrpc.StopRequest - (*StopResponse)(nil), // 148: lnrpc.StopResponse - (*GraphTopologySubscription)(nil), // 149: lnrpc.GraphTopologySubscription - (*GraphTopologyUpdate)(nil), // 150: lnrpc.GraphTopologyUpdate - (*NodeUpdate)(nil), // 151: lnrpc.NodeUpdate - (*ChannelEdgeUpdate)(nil), // 152: lnrpc.ChannelEdgeUpdate - (*ClosedChannelUpdate)(nil), // 153: lnrpc.ClosedChannelUpdate - (*HopHint)(nil), // 154: lnrpc.HopHint - (*SetID)(nil), // 155: lnrpc.SetID - (*RouteHint)(nil), // 156: lnrpc.RouteHint - (*BlindedPaymentPath)(nil), // 157: lnrpc.BlindedPaymentPath - (*BlindedPath)(nil), // 158: lnrpc.BlindedPath - (*BlindedHop)(nil), // 159: lnrpc.BlindedHop - (*AMPInvoiceState)(nil), // 160: lnrpc.AMPInvoiceState - (*Invoice)(nil), // 161: lnrpc.Invoice - (*BlindedPathConfig)(nil), // 162: lnrpc.BlindedPathConfig - (*InvoiceHTLC)(nil), // 163: lnrpc.InvoiceHTLC - (*AMP)(nil), // 164: lnrpc.AMP - (*AddInvoiceResponse)(nil), // 165: lnrpc.AddInvoiceResponse - (*PaymentHash)(nil), // 166: lnrpc.PaymentHash - (*ListInvoiceRequest)(nil), // 167: lnrpc.ListInvoiceRequest - (*ListInvoiceResponse)(nil), // 168: lnrpc.ListInvoiceResponse - (*InvoiceSubscription)(nil), // 169: lnrpc.InvoiceSubscription - (*DelCanceledInvoiceReq)(nil), // 170: lnrpc.DelCanceledInvoiceReq - (*DelCanceledInvoiceResp)(nil), // 171: lnrpc.DelCanceledInvoiceResp - (*Payment)(nil), // 172: lnrpc.Payment - (*HTLCAttempt)(nil), // 173: lnrpc.HTLCAttempt - (*ListPaymentsRequest)(nil), // 174: lnrpc.ListPaymentsRequest - (*ListPaymentsResponse)(nil), // 175: lnrpc.ListPaymentsResponse - (*DeletePaymentRequest)(nil), // 176: lnrpc.DeletePaymentRequest - (*DeleteAllPaymentsRequest)(nil), // 177: lnrpc.DeleteAllPaymentsRequest - (*DeletePaymentResponse)(nil), // 178: lnrpc.DeletePaymentResponse - (*DeleteAllPaymentsResponse)(nil), // 179: lnrpc.DeleteAllPaymentsResponse - (*AbandonChannelRequest)(nil), // 180: lnrpc.AbandonChannelRequest - (*AbandonChannelResponse)(nil), // 181: lnrpc.AbandonChannelResponse - (*DebugLevelRequest)(nil), // 182: lnrpc.DebugLevelRequest - (*DebugLevelResponse)(nil), // 183: lnrpc.DebugLevelResponse - (*PayReqString)(nil), // 184: lnrpc.PayReqString - (*PayReq)(nil), // 185: lnrpc.PayReq - (*Feature)(nil), // 186: lnrpc.Feature - (*FeeReportRequest)(nil), // 187: lnrpc.FeeReportRequest - (*ChannelFeeReport)(nil), // 188: lnrpc.ChannelFeeReport - (*FeeReportResponse)(nil), // 189: lnrpc.FeeReportResponse - (*InboundFee)(nil), // 190: lnrpc.InboundFee - (*PolicyUpdateRequest)(nil), // 191: lnrpc.PolicyUpdateRequest - (*FailedUpdate)(nil), // 192: lnrpc.FailedUpdate - (*PolicyUpdateResponse)(nil), // 193: lnrpc.PolicyUpdateResponse - (*ForwardingHistoryRequest)(nil), // 194: lnrpc.ForwardingHistoryRequest - (*ForwardingEvent)(nil), // 195: lnrpc.ForwardingEvent - (*ForwardingHistoryResponse)(nil), // 196: lnrpc.ForwardingHistoryResponse - (*ExportChannelBackupRequest)(nil), // 197: lnrpc.ExportChannelBackupRequest - (*ChannelBackup)(nil), // 198: lnrpc.ChannelBackup - (*MultiChanBackup)(nil), // 199: lnrpc.MultiChanBackup - (*ChanBackupExportRequest)(nil), // 200: lnrpc.ChanBackupExportRequest - (*ChanBackupSnapshot)(nil), // 201: lnrpc.ChanBackupSnapshot - (*ChannelBackups)(nil), // 202: lnrpc.ChannelBackups - (*RestoreChanBackupRequest)(nil), // 203: lnrpc.RestoreChanBackupRequest - (*RestoreBackupResponse)(nil), // 204: lnrpc.RestoreBackupResponse - (*ChannelBackupSubscription)(nil), // 205: lnrpc.ChannelBackupSubscription - (*VerifyChanBackupResponse)(nil), // 206: lnrpc.VerifyChanBackupResponse - (*MacaroonPermission)(nil), // 207: lnrpc.MacaroonPermission - (*BakeMacaroonRequest)(nil), // 208: lnrpc.BakeMacaroonRequest - (*BakeMacaroonResponse)(nil), // 209: lnrpc.BakeMacaroonResponse - (*ListMacaroonIDsRequest)(nil), // 210: lnrpc.ListMacaroonIDsRequest - (*ListMacaroonIDsResponse)(nil), // 211: lnrpc.ListMacaroonIDsResponse - (*DeleteMacaroonIDRequest)(nil), // 212: lnrpc.DeleteMacaroonIDRequest - (*DeleteMacaroonIDResponse)(nil), // 213: lnrpc.DeleteMacaroonIDResponse - (*MacaroonPermissionList)(nil), // 214: lnrpc.MacaroonPermissionList - (*ListPermissionsRequest)(nil), // 215: lnrpc.ListPermissionsRequest - (*ListPermissionsResponse)(nil), // 216: lnrpc.ListPermissionsResponse - (*Failure)(nil), // 217: lnrpc.Failure - (*ChannelUpdate)(nil), // 218: lnrpc.ChannelUpdate - (*MacaroonId)(nil), // 219: lnrpc.MacaroonId - (*Op)(nil), // 220: lnrpc.Op - (*CheckMacPermRequest)(nil), // 221: lnrpc.CheckMacPermRequest - (*CheckMacPermResponse)(nil), // 222: lnrpc.CheckMacPermResponse - (*RPCMiddlewareRequest)(nil), // 223: lnrpc.RPCMiddlewareRequest - (*MetadataValues)(nil), // 224: lnrpc.MetadataValues - (*StreamAuth)(nil), // 225: lnrpc.StreamAuth - (*RPCMessage)(nil), // 226: lnrpc.RPCMessage - (*RPCMiddlewareResponse)(nil), // 227: lnrpc.RPCMiddlewareResponse - (*MiddlewareRegistration)(nil), // 228: lnrpc.MiddlewareRegistration - (*InterceptFeedback)(nil), // 229: lnrpc.InterceptFeedback - nil, // 230: lnrpc.OnionMessageUpdate.CustomRecordsEntry - nil, // 231: lnrpc.SendRequest.DestCustomRecordsEntry - nil, // 232: lnrpc.EstimateFeeRequest.AddrToAmountEntry - nil, // 233: lnrpc.SendManyRequest.AddrToAmountEntry - nil, // 234: lnrpc.Peer.FeaturesEntry - nil, // 235: lnrpc.GetInfoResponse.FeaturesEntry - nil, // 236: lnrpc.GetDebugInfoResponse.ConfigEntry - (*PendingChannelsResponse_PendingChannel)(nil), // 237: lnrpc.PendingChannelsResponse.PendingChannel - (*PendingChannelsResponse_PendingOpenChannel)(nil), // 238: lnrpc.PendingChannelsResponse.PendingOpenChannel - (*PendingChannelsResponse_WaitingCloseChannel)(nil), // 239: lnrpc.PendingChannelsResponse.WaitingCloseChannel - (*PendingChannelsResponse_Commitments)(nil), // 240: lnrpc.PendingChannelsResponse.Commitments - (*PendingChannelsResponse_ClosedChannel)(nil), // 241: lnrpc.PendingChannelsResponse.ClosedChannel - (*PendingChannelsResponse_ForceClosedChannel)(nil), // 242: lnrpc.PendingChannelsResponse.ForceClosedChannel - nil, // 243: lnrpc.WalletBalanceResponse.AccountBalanceEntry - nil, // 244: lnrpc.QueryRoutesRequest.DestCustomRecordsEntry - nil, // 245: lnrpc.Hop.CustomRecordsEntry - nil, // 246: lnrpc.LightningNode.FeaturesEntry - nil, // 247: lnrpc.LightningNode.CustomRecordsEntry - nil, // 248: lnrpc.RoutingPolicy.CustomRecordsEntry - nil, // 249: lnrpc.ChannelEdge.CustomRecordsEntry - nil, // 250: lnrpc.NodeMetricsResponse.BetweennessCentralityEntry - nil, // 251: lnrpc.NodeUpdate.FeaturesEntry - nil, // 252: lnrpc.Invoice.FeaturesEntry - nil, // 253: lnrpc.Invoice.AmpInvoiceStateEntry - nil, // 254: lnrpc.InvoiceHTLC.CustomRecordsEntry - nil, // 255: lnrpc.Payment.FirstHopCustomRecordsEntry - nil, // 256: lnrpc.PayReq.FeaturesEntry - nil, // 257: lnrpc.ListPermissionsResponse.MethodPermissionsEntry - nil, // 258: lnrpc.RPCMiddlewareRequest.MetadataPairsEntry + (GraphCacheStatus)(0), // 7: lnrpc.GraphCacheStatus + (NodeMetricType)(0), // 8: lnrpc.NodeMetricType + (InvoiceHTLCState)(0), // 9: lnrpc.InvoiceHTLCState + (PaymentFailureReason)(0), // 10: lnrpc.PaymentFailureReason + (FeatureBit)(0), // 11: lnrpc.FeatureBit + (UpdateFailure)(0), // 12: lnrpc.UpdateFailure + (ChannelCloseSummary_ClosureType)(0), // 13: lnrpc.ChannelCloseSummary.ClosureType + (Peer_SyncType)(0), // 14: lnrpc.Peer.SyncType + (PeerEvent_EventType)(0), // 15: lnrpc.PeerEvent.EventType + (PendingChannelsResponse_ForceClosedChannel_AnchorState)(0), // 16: lnrpc.PendingChannelsResponse.ForceClosedChannel.AnchorState + (ChannelEventUpdate_UpdateType)(0), // 17: lnrpc.ChannelEventUpdate.UpdateType + (Invoice_InvoiceState)(0), // 18: lnrpc.Invoice.InvoiceState + (Payment_PaymentStatus)(0), // 19: lnrpc.Payment.PaymentStatus + (HTLCAttempt_HTLCStatus)(0), // 20: lnrpc.HTLCAttempt.HTLCStatus + (Failure_FailureCode)(0), // 21: lnrpc.Failure.FailureCode + (*LookupHtlcResolutionRequest)(nil), // 22: lnrpc.LookupHtlcResolutionRequest + (*LookupHtlcResolutionResponse)(nil), // 23: lnrpc.LookupHtlcResolutionResponse + (*SubscribeCustomMessagesRequest)(nil), // 24: lnrpc.SubscribeCustomMessagesRequest + (*CustomMessage)(nil), // 25: lnrpc.CustomMessage + (*SendCustomMessageRequest)(nil), // 26: lnrpc.SendCustomMessageRequest + (*SendCustomMessageResponse)(nil), // 27: lnrpc.SendCustomMessageResponse + (*SubscribeOnionMessagesRequest)(nil), // 28: lnrpc.SubscribeOnionMessagesRequest + (*OnionMessageUpdate)(nil), // 29: lnrpc.OnionMessageUpdate + (*SendOnionMessageRequest)(nil), // 30: lnrpc.SendOnionMessageRequest + (*SendOnionMessageResponse)(nil), // 31: lnrpc.SendOnionMessageResponse + (*Utxo)(nil), // 32: lnrpc.Utxo + (*OutputDetail)(nil), // 33: lnrpc.OutputDetail + (*Transaction)(nil), // 34: lnrpc.Transaction + (*GetTransactionsRequest)(nil), // 35: lnrpc.GetTransactionsRequest + (*TransactionDetails)(nil), // 36: lnrpc.TransactionDetails + (*FeeLimit)(nil), // 37: lnrpc.FeeLimit + (*SendRequest)(nil), // 38: lnrpc.SendRequest + (*SendResponse)(nil), // 39: lnrpc.SendResponse + (*SendToRouteRequest)(nil), // 40: lnrpc.SendToRouteRequest + (*ChannelAcceptRequest)(nil), // 41: lnrpc.ChannelAcceptRequest + (*ChannelAcceptResponse)(nil), // 42: lnrpc.ChannelAcceptResponse + (*ChannelPoint)(nil), // 43: lnrpc.ChannelPoint + (*OutPoint)(nil), // 44: lnrpc.OutPoint + (*PreviousOutPoint)(nil), // 45: lnrpc.PreviousOutPoint + (*LightningAddress)(nil), // 46: lnrpc.LightningAddress + (*EstimateFeeRequest)(nil), // 47: lnrpc.EstimateFeeRequest + (*EstimateFeeResponse)(nil), // 48: lnrpc.EstimateFeeResponse + (*SendManyRequest)(nil), // 49: lnrpc.SendManyRequest + (*SendManyResponse)(nil), // 50: lnrpc.SendManyResponse + (*SendCoinsRequest)(nil), // 51: lnrpc.SendCoinsRequest + (*SendCoinsResponse)(nil), // 52: lnrpc.SendCoinsResponse + (*ListUnspentRequest)(nil), // 53: lnrpc.ListUnspentRequest + (*ListUnspentResponse)(nil), // 54: lnrpc.ListUnspentResponse + (*NewAddressRequest)(nil), // 55: lnrpc.NewAddressRequest + (*NewAddressResponse)(nil), // 56: lnrpc.NewAddressResponse + (*SignMessageRequest)(nil), // 57: lnrpc.SignMessageRequest + (*SignMessageResponse)(nil), // 58: lnrpc.SignMessageResponse + (*VerifyMessageRequest)(nil), // 59: lnrpc.VerifyMessageRequest + (*VerifyMessageResponse)(nil), // 60: lnrpc.VerifyMessageResponse + (*ConnectPeerRequest)(nil), // 61: lnrpc.ConnectPeerRequest + (*ConnectPeerResponse)(nil), // 62: lnrpc.ConnectPeerResponse + (*DisconnectPeerRequest)(nil), // 63: lnrpc.DisconnectPeerRequest + (*DisconnectPeerResponse)(nil), // 64: lnrpc.DisconnectPeerResponse + (*HTLC)(nil), // 65: lnrpc.HTLC + (*ChannelConstraints)(nil), // 66: lnrpc.ChannelConstraints + (*Channel)(nil), // 67: lnrpc.Channel + (*ListChannelsRequest)(nil), // 68: lnrpc.ListChannelsRequest + (*ListChannelsResponse)(nil), // 69: lnrpc.ListChannelsResponse + (*AliasMap)(nil), // 70: lnrpc.AliasMap + (*ListAliasesRequest)(nil), // 71: lnrpc.ListAliasesRequest + (*ListAliasesResponse)(nil), // 72: lnrpc.ListAliasesResponse + (*ChannelCloseSummary)(nil), // 73: lnrpc.ChannelCloseSummary + (*Resolution)(nil), // 74: lnrpc.Resolution + (*ClosedChannelsRequest)(nil), // 75: lnrpc.ClosedChannelsRequest + (*ClosedChannelsResponse)(nil), // 76: lnrpc.ClosedChannelsResponse + (*Peer)(nil), // 77: lnrpc.Peer + (*TimestampedError)(nil), // 78: lnrpc.TimestampedError + (*ListPeersRequest)(nil), // 79: lnrpc.ListPeersRequest + (*ListPeersResponse)(nil), // 80: lnrpc.ListPeersResponse + (*PeerEventSubscription)(nil), // 81: lnrpc.PeerEventSubscription + (*PeerEvent)(nil), // 82: lnrpc.PeerEvent + (*GetInfoRequest)(nil), // 83: lnrpc.GetInfoRequest + (*GetInfoResponse)(nil), // 84: lnrpc.GetInfoResponse + (*GetDebugInfoRequest)(nil), // 85: lnrpc.GetDebugInfoRequest + (*GetDebugInfoResponse)(nil), // 86: lnrpc.GetDebugInfoResponse + (*GetRecoveryInfoRequest)(nil), // 87: lnrpc.GetRecoveryInfoRequest + (*GetRecoveryInfoResponse)(nil), // 88: lnrpc.GetRecoveryInfoResponse + (*Chain)(nil), // 89: lnrpc.Chain + (*ChannelOpenUpdate)(nil), // 90: lnrpc.ChannelOpenUpdate + (*CloseOutput)(nil), // 91: lnrpc.CloseOutput + (*ChannelCloseUpdate)(nil), // 92: lnrpc.ChannelCloseUpdate + (*CloseChannelRequest)(nil), // 93: lnrpc.CloseChannelRequest + (*CloseStatusUpdate)(nil), // 94: lnrpc.CloseStatusUpdate + (*PendingUpdate)(nil), // 95: lnrpc.PendingUpdate + (*InstantUpdate)(nil), // 96: lnrpc.InstantUpdate + (*ReadyForPsbtFunding)(nil), // 97: lnrpc.ReadyForPsbtFunding + (*BatchOpenChannelRequest)(nil), // 98: lnrpc.BatchOpenChannelRequest + (*BatchOpenChannel)(nil), // 99: lnrpc.BatchOpenChannel + (*BatchOpenChannelResponse)(nil), // 100: lnrpc.BatchOpenChannelResponse + (*OpenChannelRequest)(nil), // 101: lnrpc.OpenChannelRequest + (*OpenStatusUpdate)(nil), // 102: lnrpc.OpenStatusUpdate + (*KeyLocator)(nil), // 103: lnrpc.KeyLocator + (*KeyDescriptor)(nil), // 104: lnrpc.KeyDescriptor + (*ChanPointShim)(nil), // 105: lnrpc.ChanPointShim + (*PsbtShim)(nil), // 106: lnrpc.PsbtShim + (*FundingShim)(nil), // 107: lnrpc.FundingShim + (*FundingShimCancel)(nil), // 108: lnrpc.FundingShimCancel + (*FundingPsbtVerify)(nil), // 109: lnrpc.FundingPsbtVerify + (*FundingPsbtFinalize)(nil), // 110: lnrpc.FundingPsbtFinalize + (*FundingTransitionMsg)(nil), // 111: lnrpc.FundingTransitionMsg + (*FundingStateStepResp)(nil), // 112: lnrpc.FundingStateStepResp + (*PendingHTLC)(nil), // 113: lnrpc.PendingHTLC + (*PendingChannelsRequest)(nil), // 114: lnrpc.PendingChannelsRequest + (*PendingChannelsResponse)(nil), // 115: lnrpc.PendingChannelsResponse + (*ChannelEventSubscription)(nil), // 116: lnrpc.ChannelEventSubscription + (*ChannelCommitUpdate)(nil), // 117: lnrpc.ChannelCommitUpdate + (*ChannelEventUpdate)(nil), // 118: lnrpc.ChannelEventUpdate + (*WalletAccountBalance)(nil), // 119: lnrpc.WalletAccountBalance + (*WalletBalanceRequest)(nil), // 120: lnrpc.WalletBalanceRequest + (*WalletBalanceResponse)(nil), // 121: lnrpc.WalletBalanceResponse + (*Amount)(nil), // 122: lnrpc.Amount + (*ChannelBalanceRequest)(nil), // 123: lnrpc.ChannelBalanceRequest + (*ChannelBalanceResponse)(nil), // 124: lnrpc.ChannelBalanceResponse + (*QueryRoutesRequest)(nil), // 125: lnrpc.QueryRoutesRequest + (*NodePair)(nil), // 126: lnrpc.NodePair + (*EdgeLocator)(nil), // 127: lnrpc.EdgeLocator + (*QueryRoutesResponse)(nil), // 128: lnrpc.QueryRoutesResponse + (*Hop)(nil), // 129: lnrpc.Hop + (*MPPRecord)(nil), // 130: lnrpc.MPPRecord + (*AMPRecord)(nil), // 131: lnrpc.AMPRecord + (*Route)(nil), // 132: lnrpc.Route + (*NodeInfoRequest)(nil), // 133: lnrpc.NodeInfoRequest + (*NodeInfo)(nil), // 134: lnrpc.NodeInfo + (*LightningNode)(nil), // 135: lnrpc.LightningNode + (*NodeAddress)(nil), // 136: lnrpc.NodeAddress + (*RoutingPolicy)(nil), // 137: lnrpc.RoutingPolicy + (*ChannelAuthProof)(nil), // 138: lnrpc.ChannelAuthProof + (*ChannelEdge)(nil), // 139: lnrpc.ChannelEdge + (*ChannelGraphRequest)(nil), // 140: lnrpc.ChannelGraphRequest + (*ChannelGraph)(nil), // 141: lnrpc.ChannelGraph + (*NodeMetricsRequest)(nil), // 142: lnrpc.NodeMetricsRequest + (*NodeMetricsResponse)(nil), // 143: lnrpc.NodeMetricsResponse + (*FloatMetric)(nil), // 144: lnrpc.FloatMetric + (*ChanInfoRequest)(nil), // 145: lnrpc.ChanInfoRequest + (*NetworkInfoRequest)(nil), // 146: lnrpc.NetworkInfoRequest + (*NetworkInfo)(nil), // 147: lnrpc.NetworkInfo + (*StopRequest)(nil), // 148: lnrpc.StopRequest + (*StopResponse)(nil), // 149: lnrpc.StopResponse + (*GraphTopologySubscription)(nil), // 150: lnrpc.GraphTopologySubscription + (*GraphTopologyUpdate)(nil), // 151: lnrpc.GraphTopologyUpdate + (*NodeUpdate)(nil), // 152: lnrpc.NodeUpdate + (*ChannelEdgeUpdate)(nil), // 153: lnrpc.ChannelEdgeUpdate + (*ClosedChannelUpdate)(nil), // 154: lnrpc.ClosedChannelUpdate + (*HopHint)(nil), // 155: lnrpc.HopHint + (*SetID)(nil), // 156: lnrpc.SetID + (*RouteHint)(nil), // 157: lnrpc.RouteHint + (*BlindedPaymentPath)(nil), // 158: lnrpc.BlindedPaymentPath + (*BlindedPath)(nil), // 159: lnrpc.BlindedPath + (*BlindedHop)(nil), // 160: lnrpc.BlindedHop + (*AMPInvoiceState)(nil), // 161: lnrpc.AMPInvoiceState + (*Invoice)(nil), // 162: lnrpc.Invoice + (*BlindedPathConfig)(nil), // 163: lnrpc.BlindedPathConfig + (*InvoiceHTLC)(nil), // 164: lnrpc.InvoiceHTLC + (*AMP)(nil), // 165: lnrpc.AMP + (*AddInvoiceResponse)(nil), // 166: lnrpc.AddInvoiceResponse + (*PaymentHash)(nil), // 167: lnrpc.PaymentHash + (*ListInvoiceRequest)(nil), // 168: lnrpc.ListInvoiceRequest + (*ListInvoiceResponse)(nil), // 169: lnrpc.ListInvoiceResponse + (*InvoiceSubscription)(nil), // 170: lnrpc.InvoiceSubscription + (*DelCanceledInvoiceReq)(nil), // 171: lnrpc.DelCanceledInvoiceReq + (*DelCanceledInvoiceResp)(nil), // 172: lnrpc.DelCanceledInvoiceResp + (*Payment)(nil), // 173: lnrpc.Payment + (*HTLCAttempt)(nil), // 174: lnrpc.HTLCAttempt + (*ListPaymentsRequest)(nil), // 175: lnrpc.ListPaymentsRequest + (*ListPaymentsResponse)(nil), // 176: lnrpc.ListPaymentsResponse + (*DeletePaymentRequest)(nil), // 177: lnrpc.DeletePaymentRequest + (*DeleteAllPaymentsRequest)(nil), // 178: lnrpc.DeleteAllPaymentsRequest + (*DeletePaymentResponse)(nil), // 179: lnrpc.DeletePaymentResponse + (*DeleteAllPaymentsResponse)(nil), // 180: lnrpc.DeleteAllPaymentsResponse + (*AbandonChannelRequest)(nil), // 181: lnrpc.AbandonChannelRequest + (*AbandonChannelResponse)(nil), // 182: lnrpc.AbandonChannelResponse + (*DebugLevelRequest)(nil), // 183: lnrpc.DebugLevelRequest + (*DebugLevelResponse)(nil), // 184: lnrpc.DebugLevelResponse + (*PayReqString)(nil), // 185: lnrpc.PayReqString + (*PayReq)(nil), // 186: lnrpc.PayReq + (*Feature)(nil), // 187: lnrpc.Feature + (*FeeReportRequest)(nil), // 188: lnrpc.FeeReportRequest + (*ChannelFeeReport)(nil), // 189: lnrpc.ChannelFeeReport + (*FeeReportResponse)(nil), // 190: lnrpc.FeeReportResponse + (*InboundFee)(nil), // 191: lnrpc.InboundFee + (*PolicyUpdateRequest)(nil), // 192: lnrpc.PolicyUpdateRequest + (*FailedUpdate)(nil), // 193: lnrpc.FailedUpdate + (*PolicyUpdateResponse)(nil), // 194: lnrpc.PolicyUpdateResponse + (*ForwardingHistoryRequest)(nil), // 195: lnrpc.ForwardingHistoryRequest + (*ForwardingEvent)(nil), // 196: lnrpc.ForwardingEvent + (*ForwardingHistoryResponse)(nil), // 197: lnrpc.ForwardingHistoryResponse + (*ExportChannelBackupRequest)(nil), // 198: lnrpc.ExportChannelBackupRequest + (*ChannelBackup)(nil), // 199: lnrpc.ChannelBackup + (*MultiChanBackup)(nil), // 200: lnrpc.MultiChanBackup + (*ChanBackupExportRequest)(nil), // 201: lnrpc.ChanBackupExportRequest + (*ChanBackupSnapshot)(nil), // 202: lnrpc.ChanBackupSnapshot + (*ChannelBackups)(nil), // 203: lnrpc.ChannelBackups + (*RestoreChanBackupRequest)(nil), // 204: lnrpc.RestoreChanBackupRequest + (*RestoreBackupResponse)(nil), // 205: lnrpc.RestoreBackupResponse + (*ChannelBackupSubscription)(nil), // 206: lnrpc.ChannelBackupSubscription + (*VerifyChanBackupResponse)(nil), // 207: lnrpc.VerifyChanBackupResponse + (*MacaroonPermission)(nil), // 208: lnrpc.MacaroonPermission + (*BakeMacaroonRequest)(nil), // 209: lnrpc.BakeMacaroonRequest + (*BakeMacaroonResponse)(nil), // 210: lnrpc.BakeMacaroonResponse + (*ListMacaroonIDsRequest)(nil), // 211: lnrpc.ListMacaroonIDsRequest + (*ListMacaroonIDsResponse)(nil), // 212: lnrpc.ListMacaroonIDsResponse + (*DeleteMacaroonIDRequest)(nil), // 213: lnrpc.DeleteMacaroonIDRequest + (*DeleteMacaroonIDResponse)(nil), // 214: lnrpc.DeleteMacaroonIDResponse + (*MacaroonPermissionList)(nil), // 215: lnrpc.MacaroonPermissionList + (*ListPermissionsRequest)(nil), // 216: lnrpc.ListPermissionsRequest + (*ListPermissionsResponse)(nil), // 217: lnrpc.ListPermissionsResponse + (*Failure)(nil), // 218: lnrpc.Failure + (*ChannelUpdate)(nil), // 219: lnrpc.ChannelUpdate + (*MacaroonId)(nil), // 220: lnrpc.MacaroonId + (*Op)(nil), // 221: lnrpc.Op + (*CheckMacPermRequest)(nil), // 222: lnrpc.CheckMacPermRequest + (*CheckMacPermResponse)(nil), // 223: lnrpc.CheckMacPermResponse + (*RPCMiddlewareRequest)(nil), // 224: lnrpc.RPCMiddlewareRequest + (*MetadataValues)(nil), // 225: lnrpc.MetadataValues + (*StreamAuth)(nil), // 226: lnrpc.StreamAuth + (*RPCMessage)(nil), // 227: lnrpc.RPCMessage + (*RPCMiddlewareResponse)(nil), // 228: lnrpc.RPCMiddlewareResponse + (*MiddlewareRegistration)(nil), // 229: lnrpc.MiddlewareRegistration + (*InterceptFeedback)(nil), // 230: lnrpc.InterceptFeedback + nil, // 231: lnrpc.OnionMessageUpdate.CustomRecordsEntry + nil, // 232: lnrpc.SendRequest.DestCustomRecordsEntry + nil, // 233: lnrpc.EstimateFeeRequest.AddrToAmountEntry + nil, // 234: lnrpc.SendManyRequest.AddrToAmountEntry + nil, // 235: lnrpc.Peer.FeaturesEntry + nil, // 236: lnrpc.GetInfoResponse.FeaturesEntry + nil, // 237: lnrpc.GetDebugInfoResponse.ConfigEntry + (*PendingChannelsResponse_PendingChannel)(nil), // 238: lnrpc.PendingChannelsResponse.PendingChannel + (*PendingChannelsResponse_PendingOpenChannel)(nil), // 239: lnrpc.PendingChannelsResponse.PendingOpenChannel + (*PendingChannelsResponse_WaitingCloseChannel)(nil), // 240: lnrpc.PendingChannelsResponse.WaitingCloseChannel + (*PendingChannelsResponse_Commitments)(nil), // 241: lnrpc.PendingChannelsResponse.Commitments + (*PendingChannelsResponse_ClosedChannel)(nil), // 242: lnrpc.PendingChannelsResponse.ClosedChannel + (*PendingChannelsResponse_ForceClosedChannel)(nil), // 243: lnrpc.PendingChannelsResponse.ForceClosedChannel + nil, // 244: lnrpc.WalletBalanceResponse.AccountBalanceEntry + nil, // 245: lnrpc.QueryRoutesRequest.DestCustomRecordsEntry + nil, // 246: lnrpc.Hop.CustomRecordsEntry + nil, // 247: lnrpc.LightningNode.FeaturesEntry + nil, // 248: lnrpc.LightningNode.CustomRecordsEntry + nil, // 249: lnrpc.RoutingPolicy.CustomRecordsEntry + nil, // 250: lnrpc.ChannelEdge.CustomRecordsEntry + nil, // 251: lnrpc.NodeMetricsResponse.BetweennessCentralityEntry + nil, // 252: lnrpc.NodeUpdate.FeaturesEntry + nil, // 253: lnrpc.Invoice.FeaturesEntry + nil, // 254: lnrpc.Invoice.AmpInvoiceStateEntry + nil, // 255: lnrpc.InvoiceHTLC.CustomRecordsEntry + nil, // 256: lnrpc.Payment.FirstHopCustomRecordsEntry + nil, // 257: lnrpc.PayReq.FeaturesEntry + nil, // 258: lnrpc.ListPermissionsResponse.MethodPermissionsEntry + nil, // 259: lnrpc.RPCMiddlewareRequest.MetadataPairsEntry } var file_lightning_proto_depIdxs = []int32{ - 158, // 0: lnrpc.OnionMessageUpdate.reply_path:type_name -> lnrpc.BlindedPath - 230, // 1: lnrpc.OnionMessageUpdate.custom_records:type_name -> lnrpc.OnionMessageUpdate.CustomRecordsEntry + 159, // 0: lnrpc.OnionMessageUpdate.reply_path:type_name -> lnrpc.BlindedPath + 231, // 1: lnrpc.OnionMessageUpdate.custom_records:type_name -> lnrpc.OnionMessageUpdate.CustomRecordsEntry 2, // 2: lnrpc.Utxo.address_type:type_name -> lnrpc.AddressType - 43, // 3: lnrpc.Utxo.outpoint:type_name -> lnrpc.OutPoint + 44, // 3: lnrpc.Utxo.outpoint:type_name -> lnrpc.OutPoint 0, // 4: lnrpc.OutputDetail.output_type:type_name -> lnrpc.OutputScriptType - 32, // 5: lnrpc.Transaction.output_details:type_name -> lnrpc.OutputDetail - 44, // 6: lnrpc.Transaction.previous_outpoints:type_name -> lnrpc.PreviousOutPoint - 33, // 7: lnrpc.TransactionDetails.transactions:type_name -> lnrpc.Transaction - 36, // 8: lnrpc.SendRequest.fee_limit:type_name -> lnrpc.FeeLimit - 231, // 9: lnrpc.SendRequest.dest_custom_records:type_name -> lnrpc.SendRequest.DestCustomRecordsEntry - 10, // 10: lnrpc.SendRequest.dest_features:type_name -> lnrpc.FeatureBit - 131, // 11: lnrpc.SendResponse.payment_route:type_name -> lnrpc.Route - 131, // 12: lnrpc.SendToRouteRequest.route:type_name -> lnrpc.Route + 33, // 5: lnrpc.Transaction.output_details:type_name -> lnrpc.OutputDetail + 45, // 6: lnrpc.Transaction.previous_outpoints:type_name -> lnrpc.PreviousOutPoint + 34, // 7: lnrpc.TransactionDetails.transactions:type_name -> lnrpc.Transaction + 37, // 8: lnrpc.SendRequest.fee_limit:type_name -> lnrpc.FeeLimit + 232, // 9: lnrpc.SendRequest.dest_custom_records:type_name -> lnrpc.SendRequest.DestCustomRecordsEntry + 11, // 10: lnrpc.SendRequest.dest_features:type_name -> lnrpc.FeatureBit + 132, // 11: lnrpc.SendResponse.payment_route:type_name -> lnrpc.Route + 132, // 12: lnrpc.SendToRouteRequest.route:type_name -> lnrpc.Route 3, // 13: lnrpc.ChannelAcceptRequest.commitment_type:type_name -> lnrpc.CommitmentType - 232, // 14: lnrpc.EstimateFeeRequest.AddrToAmount:type_name -> lnrpc.EstimateFeeRequest.AddrToAmountEntry + 233, // 14: lnrpc.EstimateFeeRequest.AddrToAmount:type_name -> lnrpc.EstimateFeeRequest.AddrToAmountEntry 1, // 15: lnrpc.EstimateFeeRequest.coin_selection_strategy:type_name -> lnrpc.CoinSelectionStrategy - 43, // 16: lnrpc.EstimateFeeRequest.inputs:type_name -> lnrpc.OutPoint - 43, // 17: lnrpc.EstimateFeeResponse.inputs:type_name -> lnrpc.OutPoint - 233, // 18: lnrpc.SendManyRequest.AddrToAmount:type_name -> lnrpc.SendManyRequest.AddrToAmountEntry + 44, // 16: lnrpc.EstimateFeeRequest.inputs:type_name -> lnrpc.OutPoint + 44, // 17: lnrpc.EstimateFeeResponse.inputs:type_name -> lnrpc.OutPoint + 234, // 18: lnrpc.SendManyRequest.AddrToAmount:type_name -> lnrpc.SendManyRequest.AddrToAmountEntry 1, // 19: lnrpc.SendManyRequest.coin_selection_strategy:type_name -> lnrpc.CoinSelectionStrategy 1, // 20: lnrpc.SendCoinsRequest.coin_selection_strategy:type_name -> lnrpc.CoinSelectionStrategy - 43, // 21: lnrpc.SendCoinsRequest.outpoints:type_name -> lnrpc.OutPoint - 31, // 22: lnrpc.ListUnspentResponse.utxos:type_name -> lnrpc.Utxo + 44, // 21: lnrpc.SendCoinsRequest.outpoints:type_name -> lnrpc.OutPoint + 32, // 22: lnrpc.ListUnspentResponse.utxos:type_name -> lnrpc.Utxo 2, // 23: lnrpc.NewAddressRequest.type:type_name -> lnrpc.AddressType - 45, // 24: lnrpc.ConnectPeerRequest.addr:type_name -> lnrpc.LightningAddress - 64, // 25: lnrpc.Channel.pending_htlcs:type_name -> lnrpc.HTLC + 46, // 24: lnrpc.ConnectPeerRequest.addr:type_name -> lnrpc.LightningAddress + 65, // 25: lnrpc.Channel.pending_htlcs:type_name -> lnrpc.HTLC 3, // 26: lnrpc.Channel.commitment_type:type_name -> lnrpc.CommitmentType - 65, // 27: lnrpc.Channel.local_constraints:type_name -> lnrpc.ChannelConstraints - 65, // 28: lnrpc.Channel.remote_constraints:type_name -> lnrpc.ChannelConstraints - 66, // 29: lnrpc.ListChannelsResponse.channels:type_name -> lnrpc.Channel - 69, // 30: lnrpc.ListAliasesResponse.alias_maps:type_name -> lnrpc.AliasMap - 12, // 31: lnrpc.ChannelCloseSummary.close_type:type_name -> lnrpc.ChannelCloseSummary.ClosureType + 66, // 27: lnrpc.Channel.local_constraints:type_name -> lnrpc.ChannelConstraints + 66, // 28: lnrpc.Channel.remote_constraints:type_name -> lnrpc.ChannelConstraints + 67, // 29: lnrpc.ListChannelsResponse.channels:type_name -> lnrpc.Channel + 70, // 30: lnrpc.ListAliasesResponse.alias_maps:type_name -> lnrpc.AliasMap + 13, // 31: lnrpc.ChannelCloseSummary.close_type:type_name -> lnrpc.ChannelCloseSummary.ClosureType 4, // 32: lnrpc.ChannelCloseSummary.open_initiator:type_name -> lnrpc.Initiator 4, // 33: lnrpc.ChannelCloseSummary.close_initiator:type_name -> lnrpc.Initiator - 73, // 34: lnrpc.ChannelCloseSummary.resolutions:type_name -> lnrpc.Resolution + 74, // 34: lnrpc.ChannelCloseSummary.resolutions:type_name -> lnrpc.Resolution 5, // 35: lnrpc.Resolution.resolution_type:type_name -> lnrpc.ResolutionType 6, // 36: lnrpc.Resolution.outcome:type_name -> lnrpc.ResolutionOutcome - 43, // 37: lnrpc.Resolution.outpoint:type_name -> lnrpc.OutPoint - 72, // 38: lnrpc.ClosedChannelsResponse.channels:type_name -> lnrpc.ChannelCloseSummary - 13, // 39: lnrpc.Peer.sync_type:type_name -> lnrpc.Peer.SyncType - 234, // 40: lnrpc.Peer.features:type_name -> lnrpc.Peer.FeaturesEntry - 77, // 41: lnrpc.Peer.errors:type_name -> lnrpc.TimestampedError - 76, // 42: lnrpc.ListPeersResponse.peers:type_name -> lnrpc.Peer - 14, // 43: lnrpc.PeerEvent.type:type_name -> lnrpc.PeerEvent.EventType - 88, // 44: lnrpc.GetInfoResponse.chains:type_name -> lnrpc.Chain - 235, // 45: lnrpc.GetInfoResponse.features:type_name -> lnrpc.GetInfoResponse.FeaturesEntry - 236, // 46: lnrpc.GetDebugInfoResponse.config:type_name -> lnrpc.GetDebugInfoResponse.ConfigEntry - 42, // 47: lnrpc.ChannelOpenUpdate.channel_point:type_name -> lnrpc.ChannelPoint - 90, // 48: lnrpc.ChannelCloseUpdate.local_close_output:type_name -> lnrpc.CloseOutput - 90, // 49: lnrpc.ChannelCloseUpdate.remote_close_output:type_name -> lnrpc.CloseOutput - 90, // 50: lnrpc.ChannelCloseUpdate.additional_outputs:type_name -> lnrpc.CloseOutput - 42, // 51: lnrpc.CloseChannelRequest.channel_point:type_name -> lnrpc.ChannelPoint - 94, // 52: lnrpc.CloseStatusUpdate.close_pending:type_name -> lnrpc.PendingUpdate - 91, // 53: lnrpc.CloseStatusUpdate.chan_close:type_name -> lnrpc.ChannelCloseUpdate - 95, // 54: lnrpc.CloseStatusUpdate.close_instant:type_name -> lnrpc.InstantUpdate - 98, // 55: lnrpc.BatchOpenChannelRequest.channels:type_name -> lnrpc.BatchOpenChannel - 1, // 56: lnrpc.BatchOpenChannelRequest.coin_selection_strategy:type_name -> lnrpc.CoinSelectionStrategy - 3, // 57: lnrpc.BatchOpenChannel.commitment_type:type_name -> lnrpc.CommitmentType - 94, // 58: lnrpc.BatchOpenChannelResponse.pending_channels:type_name -> lnrpc.PendingUpdate - 106, // 59: lnrpc.OpenChannelRequest.funding_shim:type_name -> lnrpc.FundingShim - 3, // 60: lnrpc.OpenChannelRequest.commitment_type:type_name -> lnrpc.CommitmentType - 43, // 61: lnrpc.OpenChannelRequest.outpoints:type_name -> lnrpc.OutPoint - 94, // 62: lnrpc.OpenStatusUpdate.chan_pending:type_name -> lnrpc.PendingUpdate - 89, // 63: lnrpc.OpenStatusUpdate.chan_open:type_name -> lnrpc.ChannelOpenUpdate - 96, // 64: lnrpc.OpenStatusUpdate.psbt_fund:type_name -> lnrpc.ReadyForPsbtFunding - 102, // 65: lnrpc.KeyDescriptor.key_loc:type_name -> lnrpc.KeyLocator - 42, // 66: lnrpc.ChanPointShim.chan_point:type_name -> lnrpc.ChannelPoint - 103, // 67: lnrpc.ChanPointShim.local_key:type_name -> lnrpc.KeyDescriptor - 104, // 68: lnrpc.FundingShim.chan_point_shim:type_name -> lnrpc.ChanPointShim - 105, // 69: lnrpc.FundingShim.psbt_shim:type_name -> lnrpc.PsbtShim - 106, // 70: lnrpc.FundingTransitionMsg.shim_register:type_name -> lnrpc.FundingShim - 107, // 71: lnrpc.FundingTransitionMsg.shim_cancel:type_name -> lnrpc.FundingShimCancel - 108, // 72: lnrpc.FundingTransitionMsg.psbt_verify:type_name -> lnrpc.FundingPsbtVerify - 109, // 73: lnrpc.FundingTransitionMsg.psbt_finalize:type_name -> lnrpc.FundingPsbtFinalize - 238, // 74: lnrpc.PendingChannelsResponse.pending_open_channels:type_name -> lnrpc.PendingChannelsResponse.PendingOpenChannel - 241, // 75: lnrpc.PendingChannelsResponse.pending_closing_channels:type_name -> lnrpc.PendingChannelsResponse.ClosedChannel - 242, // 76: lnrpc.PendingChannelsResponse.pending_force_closing_channels:type_name -> lnrpc.PendingChannelsResponse.ForceClosedChannel - 239, // 77: lnrpc.PendingChannelsResponse.waiting_close_channels:type_name -> lnrpc.PendingChannelsResponse.WaitingCloseChannel - 66, // 78: lnrpc.ChannelCommitUpdate.channel:type_name -> lnrpc.Channel - 66, // 79: lnrpc.ChannelEventUpdate.open_channel:type_name -> lnrpc.Channel - 72, // 80: lnrpc.ChannelEventUpdate.closed_channel:type_name -> lnrpc.ChannelCloseSummary - 42, // 81: lnrpc.ChannelEventUpdate.active_channel:type_name -> lnrpc.ChannelPoint - 42, // 82: lnrpc.ChannelEventUpdate.inactive_channel:type_name -> lnrpc.ChannelPoint - 94, // 83: lnrpc.ChannelEventUpdate.pending_open_channel:type_name -> lnrpc.PendingUpdate - 42, // 84: lnrpc.ChannelEventUpdate.fully_resolved_channel:type_name -> lnrpc.ChannelPoint - 42, // 85: lnrpc.ChannelEventUpdate.channel_funding_timeout:type_name -> lnrpc.ChannelPoint - 116, // 86: lnrpc.ChannelEventUpdate.updated_channel:type_name -> lnrpc.ChannelCommitUpdate - 16, // 87: lnrpc.ChannelEventUpdate.type:type_name -> lnrpc.ChannelEventUpdate.UpdateType - 243, // 88: lnrpc.WalletBalanceResponse.account_balance:type_name -> lnrpc.WalletBalanceResponse.AccountBalanceEntry - 121, // 89: lnrpc.ChannelBalanceResponse.local_balance:type_name -> lnrpc.Amount - 121, // 90: lnrpc.ChannelBalanceResponse.remote_balance:type_name -> lnrpc.Amount - 121, // 91: lnrpc.ChannelBalanceResponse.unsettled_local_balance:type_name -> lnrpc.Amount - 121, // 92: lnrpc.ChannelBalanceResponse.unsettled_remote_balance:type_name -> lnrpc.Amount - 121, // 93: lnrpc.ChannelBalanceResponse.pending_open_local_balance:type_name -> lnrpc.Amount - 121, // 94: lnrpc.ChannelBalanceResponse.pending_open_remote_balance:type_name -> lnrpc.Amount - 36, // 95: lnrpc.QueryRoutesRequest.fee_limit:type_name -> lnrpc.FeeLimit - 126, // 96: lnrpc.QueryRoutesRequest.ignored_edges:type_name -> lnrpc.EdgeLocator - 125, // 97: lnrpc.QueryRoutesRequest.ignored_pairs:type_name -> lnrpc.NodePair - 244, // 98: lnrpc.QueryRoutesRequest.dest_custom_records:type_name -> lnrpc.QueryRoutesRequest.DestCustomRecordsEntry - 156, // 99: lnrpc.QueryRoutesRequest.route_hints:type_name -> lnrpc.RouteHint - 157, // 100: lnrpc.QueryRoutesRequest.blinded_payment_paths:type_name -> lnrpc.BlindedPaymentPath - 10, // 101: lnrpc.QueryRoutesRequest.dest_features:type_name -> lnrpc.FeatureBit - 131, // 102: lnrpc.QueryRoutesResponse.routes:type_name -> lnrpc.Route - 129, // 103: lnrpc.Hop.mpp_record:type_name -> lnrpc.MPPRecord - 130, // 104: lnrpc.Hop.amp_record:type_name -> lnrpc.AMPRecord - 245, // 105: lnrpc.Hop.custom_records:type_name -> lnrpc.Hop.CustomRecordsEntry - 128, // 106: lnrpc.Route.hops:type_name -> lnrpc.Hop - 134, // 107: lnrpc.NodeInfo.node:type_name -> lnrpc.LightningNode - 138, // 108: lnrpc.NodeInfo.channels:type_name -> lnrpc.ChannelEdge - 135, // 109: lnrpc.LightningNode.addresses:type_name -> lnrpc.NodeAddress - 246, // 110: lnrpc.LightningNode.features:type_name -> lnrpc.LightningNode.FeaturesEntry - 247, // 111: lnrpc.LightningNode.custom_records:type_name -> lnrpc.LightningNode.CustomRecordsEntry - 248, // 112: lnrpc.RoutingPolicy.custom_records:type_name -> lnrpc.RoutingPolicy.CustomRecordsEntry - 136, // 113: lnrpc.ChannelEdge.node1_policy:type_name -> lnrpc.RoutingPolicy - 136, // 114: lnrpc.ChannelEdge.node2_policy:type_name -> lnrpc.RoutingPolicy - 249, // 115: lnrpc.ChannelEdge.custom_records:type_name -> lnrpc.ChannelEdge.CustomRecordsEntry - 137, // 116: lnrpc.ChannelEdge.auth_proof:type_name -> lnrpc.ChannelAuthProof - 134, // 117: lnrpc.ChannelGraph.nodes:type_name -> lnrpc.LightningNode - 138, // 118: lnrpc.ChannelGraph.edges:type_name -> lnrpc.ChannelEdge - 7, // 119: lnrpc.NodeMetricsRequest.types:type_name -> lnrpc.NodeMetricType - 250, // 120: lnrpc.NodeMetricsResponse.betweenness_centrality:type_name -> lnrpc.NodeMetricsResponse.BetweennessCentralityEntry - 151, // 121: lnrpc.GraphTopologyUpdate.node_updates:type_name -> lnrpc.NodeUpdate - 152, // 122: lnrpc.GraphTopologyUpdate.channel_updates:type_name -> lnrpc.ChannelEdgeUpdate - 153, // 123: lnrpc.GraphTopologyUpdate.closed_chans:type_name -> lnrpc.ClosedChannelUpdate - 135, // 124: lnrpc.NodeUpdate.node_addresses:type_name -> lnrpc.NodeAddress - 251, // 125: lnrpc.NodeUpdate.features:type_name -> lnrpc.NodeUpdate.FeaturesEntry - 42, // 126: lnrpc.ChannelEdgeUpdate.chan_point:type_name -> lnrpc.ChannelPoint - 136, // 127: lnrpc.ChannelEdgeUpdate.routing_policy:type_name -> lnrpc.RoutingPolicy - 42, // 128: lnrpc.ClosedChannelUpdate.chan_point:type_name -> lnrpc.ChannelPoint - 154, // 129: lnrpc.RouteHint.hop_hints:type_name -> lnrpc.HopHint - 158, // 130: lnrpc.BlindedPaymentPath.blinded_path:type_name -> lnrpc.BlindedPath - 10, // 131: lnrpc.BlindedPaymentPath.features:type_name -> lnrpc.FeatureBit - 159, // 132: lnrpc.BlindedPath.blinded_hops:type_name -> lnrpc.BlindedHop - 8, // 133: lnrpc.AMPInvoiceState.state:type_name -> lnrpc.InvoiceHTLCState - 156, // 134: lnrpc.Invoice.route_hints:type_name -> lnrpc.RouteHint - 17, // 135: lnrpc.Invoice.state:type_name -> lnrpc.Invoice.InvoiceState - 163, // 136: lnrpc.Invoice.htlcs:type_name -> lnrpc.InvoiceHTLC - 252, // 137: lnrpc.Invoice.features:type_name -> lnrpc.Invoice.FeaturesEntry - 253, // 138: lnrpc.Invoice.amp_invoice_state:type_name -> lnrpc.Invoice.AmpInvoiceStateEntry - 162, // 139: lnrpc.Invoice.blinded_path_config:type_name -> lnrpc.BlindedPathConfig - 8, // 140: lnrpc.InvoiceHTLC.state:type_name -> lnrpc.InvoiceHTLCState - 254, // 141: lnrpc.InvoiceHTLC.custom_records:type_name -> lnrpc.InvoiceHTLC.CustomRecordsEntry - 164, // 142: lnrpc.InvoiceHTLC.amp:type_name -> lnrpc.AMP - 161, // 143: lnrpc.ListInvoiceResponse.invoices:type_name -> lnrpc.Invoice - 18, // 144: lnrpc.Payment.status:type_name -> lnrpc.Payment.PaymentStatus - 173, // 145: lnrpc.Payment.htlcs:type_name -> lnrpc.HTLCAttempt - 9, // 146: lnrpc.Payment.failure_reason:type_name -> lnrpc.PaymentFailureReason - 255, // 147: lnrpc.Payment.first_hop_custom_records:type_name -> lnrpc.Payment.FirstHopCustomRecordsEntry - 19, // 148: lnrpc.HTLCAttempt.status:type_name -> lnrpc.HTLCAttempt.HTLCStatus - 131, // 149: lnrpc.HTLCAttempt.route:type_name -> lnrpc.Route - 217, // 150: lnrpc.HTLCAttempt.failure:type_name -> lnrpc.Failure - 172, // 151: lnrpc.ListPaymentsResponse.payments:type_name -> lnrpc.Payment - 42, // 152: lnrpc.AbandonChannelRequest.channel_point:type_name -> lnrpc.ChannelPoint - 156, // 153: lnrpc.PayReq.route_hints:type_name -> lnrpc.RouteHint - 256, // 154: lnrpc.PayReq.features:type_name -> lnrpc.PayReq.FeaturesEntry - 157, // 155: lnrpc.PayReq.blinded_paths:type_name -> lnrpc.BlindedPaymentPath - 188, // 156: lnrpc.FeeReportResponse.channel_fees:type_name -> lnrpc.ChannelFeeReport - 42, // 157: lnrpc.PolicyUpdateRequest.chan_point:type_name -> lnrpc.ChannelPoint - 190, // 158: lnrpc.PolicyUpdateRequest.inbound_fee:type_name -> lnrpc.InboundFee - 43, // 159: lnrpc.FailedUpdate.outpoint:type_name -> lnrpc.OutPoint - 11, // 160: lnrpc.FailedUpdate.reason:type_name -> lnrpc.UpdateFailure - 192, // 161: lnrpc.PolicyUpdateResponse.failed_updates:type_name -> lnrpc.FailedUpdate - 195, // 162: lnrpc.ForwardingHistoryResponse.forwarding_events:type_name -> lnrpc.ForwardingEvent - 42, // 163: lnrpc.ExportChannelBackupRequest.chan_point:type_name -> lnrpc.ChannelPoint - 42, // 164: lnrpc.ChannelBackup.chan_point:type_name -> lnrpc.ChannelPoint - 42, // 165: lnrpc.MultiChanBackup.chan_points:type_name -> lnrpc.ChannelPoint - 202, // 166: lnrpc.ChanBackupSnapshot.single_chan_backups:type_name -> lnrpc.ChannelBackups - 199, // 167: lnrpc.ChanBackupSnapshot.multi_chan_backup:type_name -> lnrpc.MultiChanBackup - 198, // 168: lnrpc.ChannelBackups.chan_backups:type_name -> lnrpc.ChannelBackup - 202, // 169: lnrpc.RestoreChanBackupRequest.chan_backups:type_name -> lnrpc.ChannelBackups - 207, // 170: lnrpc.BakeMacaroonRequest.permissions:type_name -> lnrpc.MacaroonPermission - 207, // 171: lnrpc.MacaroonPermissionList.permissions:type_name -> lnrpc.MacaroonPermission - 257, // 172: lnrpc.ListPermissionsResponse.method_permissions:type_name -> lnrpc.ListPermissionsResponse.MethodPermissionsEntry - 20, // 173: lnrpc.Failure.code:type_name -> lnrpc.Failure.FailureCode - 218, // 174: lnrpc.Failure.channel_update:type_name -> lnrpc.ChannelUpdate - 220, // 175: lnrpc.MacaroonId.ops:type_name -> lnrpc.Op - 207, // 176: lnrpc.CheckMacPermRequest.permissions:type_name -> lnrpc.MacaroonPermission - 225, // 177: lnrpc.RPCMiddlewareRequest.stream_auth:type_name -> lnrpc.StreamAuth - 226, // 178: lnrpc.RPCMiddlewareRequest.request:type_name -> lnrpc.RPCMessage - 226, // 179: lnrpc.RPCMiddlewareRequest.response:type_name -> lnrpc.RPCMessage - 258, // 180: lnrpc.RPCMiddlewareRequest.metadata_pairs:type_name -> lnrpc.RPCMiddlewareRequest.MetadataPairsEntry - 228, // 181: lnrpc.RPCMiddlewareResponse.register:type_name -> lnrpc.MiddlewareRegistration - 229, // 182: lnrpc.RPCMiddlewareResponse.feedback:type_name -> lnrpc.InterceptFeedback - 186, // 183: lnrpc.Peer.FeaturesEntry.value:type_name -> lnrpc.Feature - 186, // 184: lnrpc.GetInfoResponse.FeaturesEntry.value:type_name -> lnrpc.Feature - 4, // 185: lnrpc.PendingChannelsResponse.PendingChannel.initiator:type_name -> lnrpc.Initiator - 3, // 186: lnrpc.PendingChannelsResponse.PendingChannel.commitment_type:type_name -> lnrpc.CommitmentType - 237, // 187: lnrpc.PendingChannelsResponse.PendingOpenChannel.channel:type_name -> lnrpc.PendingChannelsResponse.PendingChannel - 237, // 188: lnrpc.PendingChannelsResponse.WaitingCloseChannel.channel:type_name -> lnrpc.PendingChannelsResponse.PendingChannel - 240, // 189: lnrpc.PendingChannelsResponse.WaitingCloseChannel.commitments:type_name -> lnrpc.PendingChannelsResponse.Commitments - 237, // 190: lnrpc.PendingChannelsResponse.ClosedChannel.channel:type_name -> lnrpc.PendingChannelsResponse.PendingChannel - 237, // 191: lnrpc.PendingChannelsResponse.ForceClosedChannel.channel:type_name -> lnrpc.PendingChannelsResponse.PendingChannel - 112, // 192: lnrpc.PendingChannelsResponse.ForceClosedChannel.pending_htlcs:type_name -> lnrpc.PendingHTLC - 15, // 193: lnrpc.PendingChannelsResponse.ForceClosedChannel.anchor:type_name -> lnrpc.PendingChannelsResponse.ForceClosedChannel.AnchorState - 118, // 194: lnrpc.WalletBalanceResponse.AccountBalanceEntry.value:type_name -> lnrpc.WalletAccountBalance - 186, // 195: lnrpc.LightningNode.FeaturesEntry.value:type_name -> lnrpc.Feature - 143, // 196: lnrpc.NodeMetricsResponse.BetweennessCentralityEntry.value:type_name -> lnrpc.FloatMetric - 186, // 197: lnrpc.NodeUpdate.FeaturesEntry.value:type_name -> lnrpc.Feature - 186, // 198: lnrpc.Invoice.FeaturesEntry.value:type_name -> lnrpc.Feature - 160, // 199: lnrpc.Invoice.AmpInvoiceStateEntry.value:type_name -> lnrpc.AMPInvoiceState - 186, // 200: lnrpc.PayReq.FeaturesEntry.value:type_name -> lnrpc.Feature - 214, // 201: lnrpc.ListPermissionsResponse.MethodPermissionsEntry.value:type_name -> lnrpc.MacaroonPermissionList - 224, // 202: lnrpc.RPCMiddlewareRequest.MetadataPairsEntry.value:type_name -> lnrpc.MetadataValues - 119, // 203: lnrpc.Lightning.WalletBalance:input_type -> lnrpc.WalletBalanceRequest - 122, // 204: lnrpc.Lightning.ChannelBalance:input_type -> lnrpc.ChannelBalanceRequest - 34, // 205: lnrpc.Lightning.GetTransactions:input_type -> lnrpc.GetTransactionsRequest - 46, // 206: lnrpc.Lightning.EstimateFee:input_type -> lnrpc.EstimateFeeRequest - 50, // 207: lnrpc.Lightning.SendCoins:input_type -> lnrpc.SendCoinsRequest - 52, // 208: lnrpc.Lightning.ListUnspent:input_type -> lnrpc.ListUnspentRequest - 34, // 209: lnrpc.Lightning.SubscribeTransactions:input_type -> lnrpc.GetTransactionsRequest - 48, // 210: lnrpc.Lightning.SendMany:input_type -> lnrpc.SendManyRequest - 54, // 211: lnrpc.Lightning.NewAddress:input_type -> lnrpc.NewAddressRequest - 56, // 212: lnrpc.Lightning.SignMessage:input_type -> lnrpc.SignMessageRequest - 58, // 213: lnrpc.Lightning.VerifyMessage:input_type -> lnrpc.VerifyMessageRequest - 60, // 214: lnrpc.Lightning.ConnectPeer:input_type -> lnrpc.ConnectPeerRequest - 62, // 215: lnrpc.Lightning.DisconnectPeer:input_type -> lnrpc.DisconnectPeerRequest - 78, // 216: lnrpc.Lightning.ListPeers:input_type -> lnrpc.ListPeersRequest - 80, // 217: lnrpc.Lightning.SubscribePeerEvents:input_type -> lnrpc.PeerEventSubscription - 82, // 218: lnrpc.Lightning.GetInfo:input_type -> lnrpc.GetInfoRequest - 84, // 219: lnrpc.Lightning.GetDebugInfo:input_type -> lnrpc.GetDebugInfoRequest - 86, // 220: lnrpc.Lightning.GetRecoveryInfo:input_type -> lnrpc.GetRecoveryInfoRequest - 113, // 221: lnrpc.Lightning.PendingChannels:input_type -> lnrpc.PendingChannelsRequest - 67, // 222: lnrpc.Lightning.ListChannels:input_type -> lnrpc.ListChannelsRequest - 115, // 223: lnrpc.Lightning.SubscribeChannelEvents:input_type -> lnrpc.ChannelEventSubscription - 74, // 224: lnrpc.Lightning.ClosedChannels:input_type -> lnrpc.ClosedChannelsRequest - 100, // 225: lnrpc.Lightning.OpenChannelSync:input_type -> lnrpc.OpenChannelRequest - 100, // 226: lnrpc.Lightning.OpenChannel:input_type -> lnrpc.OpenChannelRequest - 97, // 227: lnrpc.Lightning.BatchOpenChannel:input_type -> lnrpc.BatchOpenChannelRequest - 110, // 228: lnrpc.Lightning.FundingStateStep:input_type -> lnrpc.FundingTransitionMsg - 41, // 229: lnrpc.Lightning.ChannelAcceptor:input_type -> lnrpc.ChannelAcceptResponse - 92, // 230: lnrpc.Lightning.CloseChannel:input_type -> lnrpc.CloseChannelRequest - 180, // 231: lnrpc.Lightning.AbandonChannel:input_type -> lnrpc.AbandonChannelRequest - 37, // 232: lnrpc.Lightning.SendPayment:input_type -> lnrpc.SendRequest - 37, // 233: lnrpc.Lightning.SendPaymentSync:input_type -> lnrpc.SendRequest - 39, // 234: lnrpc.Lightning.SendToRoute:input_type -> lnrpc.SendToRouteRequest - 39, // 235: lnrpc.Lightning.SendToRouteSync:input_type -> lnrpc.SendToRouteRequest - 161, // 236: lnrpc.Lightning.AddInvoice:input_type -> lnrpc.Invoice - 167, // 237: lnrpc.Lightning.ListInvoices:input_type -> lnrpc.ListInvoiceRequest - 166, // 238: lnrpc.Lightning.LookupInvoice:input_type -> lnrpc.PaymentHash - 169, // 239: lnrpc.Lightning.SubscribeInvoices:input_type -> lnrpc.InvoiceSubscription - 170, // 240: lnrpc.Lightning.DeleteCanceledInvoice:input_type -> lnrpc.DelCanceledInvoiceReq - 184, // 241: lnrpc.Lightning.DecodePayReq:input_type -> lnrpc.PayReqString - 174, // 242: lnrpc.Lightning.ListPayments:input_type -> lnrpc.ListPaymentsRequest - 176, // 243: lnrpc.Lightning.DeletePayment:input_type -> lnrpc.DeletePaymentRequest - 177, // 244: lnrpc.Lightning.DeleteAllPayments:input_type -> lnrpc.DeleteAllPaymentsRequest - 139, // 245: lnrpc.Lightning.DescribeGraph:input_type -> lnrpc.ChannelGraphRequest - 141, // 246: lnrpc.Lightning.GetNodeMetrics:input_type -> lnrpc.NodeMetricsRequest - 144, // 247: lnrpc.Lightning.GetChanInfo:input_type -> lnrpc.ChanInfoRequest - 132, // 248: lnrpc.Lightning.GetNodeInfo:input_type -> lnrpc.NodeInfoRequest - 124, // 249: lnrpc.Lightning.QueryRoutes:input_type -> lnrpc.QueryRoutesRequest - 145, // 250: lnrpc.Lightning.GetNetworkInfo:input_type -> lnrpc.NetworkInfoRequest - 147, // 251: lnrpc.Lightning.StopDaemon:input_type -> lnrpc.StopRequest - 149, // 252: lnrpc.Lightning.SubscribeChannelGraph:input_type -> lnrpc.GraphTopologySubscription - 182, // 253: lnrpc.Lightning.DebugLevel:input_type -> lnrpc.DebugLevelRequest - 187, // 254: lnrpc.Lightning.FeeReport:input_type -> lnrpc.FeeReportRequest - 191, // 255: lnrpc.Lightning.UpdateChannelPolicy:input_type -> lnrpc.PolicyUpdateRequest - 194, // 256: lnrpc.Lightning.ForwardingHistory:input_type -> lnrpc.ForwardingHistoryRequest - 197, // 257: lnrpc.Lightning.ExportChannelBackup:input_type -> lnrpc.ExportChannelBackupRequest - 200, // 258: lnrpc.Lightning.ExportAllChannelBackups:input_type -> lnrpc.ChanBackupExportRequest - 201, // 259: lnrpc.Lightning.VerifyChanBackup:input_type -> lnrpc.ChanBackupSnapshot - 203, // 260: lnrpc.Lightning.RestoreChannelBackups:input_type -> lnrpc.RestoreChanBackupRequest - 205, // 261: lnrpc.Lightning.SubscribeChannelBackups:input_type -> lnrpc.ChannelBackupSubscription - 208, // 262: lnrpc.Lightning.BakeMacaroon:input_type -> lnrpc.BakeMacaroonRequest - 210, // 263: lnrpc.Lightning.ListMacaroonIDs:input_type -> lnrpc.ListMacaroonIDsRequest - 212, // 264: lnrpc.Lightning.DeleteMacaroonID:input_type -> lnrpc.DeleteMacaroonIDRequest - 215, // 265: lnrpc.Lightning.ListPermissions:input_type -> lnrpc.ListPermissionsRequest - 221, // 266: lnrpc.Lightning.CheckMacaroonPermissions:input_type -> lnrpc.CheckMacPermRequest - 227, // 267: lnrpc.Lightning.RegisterRPCMiddleware:input_type -> lnrpc.RPCMiddlewareResponse - 25, // 268: lnrpc.Lightning.SendCustomMessage:input_type -> lnrpc.SendCustomMessageRequest - 23, // 269: lnrpc.Lightning.SubscribeCustomMessages:input_type -> lnrpc.SubscribeCustomMessagesRequest - 29, // 270: lnrpc.Lightning.SendOnionMessage:input_type -> lnrpc.SendOnionMessageRequest - 27, // 271: lnrpc.Lightning.SubscribeOnionMessages:input_type -> lnrpc.SubscribeOnionMessagesRequest - 70, // 272: lnrpc.Lightning.ListAliases:input_type -> lnrpc.ListAliasesRequest - 21, // 273: lnrpc.Lightning.LookupHtlcResolution:input_type -> lnrpc.LookupHtlcResolutionRequest - 120, // 274: lnrpc.Lightning.WalletBalance:output_type -> lnrpc.WalletBalanceResponse - 123, // 275: lnrpc.Lightning.ChannelBalance:output_type -> lnrpc.ChannelBalanceResponse - 35, // 276: lnrpc.Lightning.GetTransactions:output_type -> lnrpc.TransactionDetails - 47, // 277: lnrpc.Lightning.EstimateFee:output_type -> lnrpc.EstimateFeeResponse - 51, // 278: lnrpc.Lightning.SendCoins:output_type -> lnrpc.SendCoinsResponse - 53, // 279: lnrpc.Lightning.ListUnspent:output_type -> lnrpc.ListUnspentResponse - 33, // 280: lnrpc.Lightning.SubscribeTransactions:output_type -> lnrpc.Transaction - 49, // 281: lnrpc.Lightning.SendMany:output_type -> lnrpc.SendManyResponse - 55, // 282: lnrpc.Lightning.NewAddress:output_type -> lnrpc.NewAddressResponse - 57, // 283: lnrpc.Lightning.SignMessage:output_type -> lnrpc.SignMessageResponse - 59, // 284: lnrpc.Lightning.VerifyMessage:output_type -> lnrpc.VerifyMessageResponse - 61, // 285: lnrpc.Lightning.ConnectPeer:output_type -> lnrpc.ConnectPeerResponse - 63, // 286: lnrpc.Lightning.DisconnectPeer:output_type -> lnrpc.DisconnectPeerResponse - 79, // 287: lnrpc.Lightning.ListPeers:output_type -> lnrpc.ListPeersResponse - 81, // 288: lnrpc.Lightning.SubscribePeerEvents:output_type -> lnrpc.PeerEvent - 83, // 289: lnrpc.Lightning.GetInfo:output_type -> lnrpc.GetInfoResponse - 85, // 290: lnrpc.Lightning.GetDebugInfo:output_type -> lnrpc.GetDebugInfoResponse - 87, // 291: lnrpc.Lightning.GetRecoveryInfo:output_type -> lnrpc.GetRecoveryInfoResponse - 114, // 292: lnrpc.Lightning.PendingChannels:output_type -> lnrpc.PendingChannelsResponse - 68, // 293: lnrpc.Lightning.ListChannels:output_type -> lnrpc.ListChannelsResponse - 117, // 294: lnrpc.Lightning.SubscribeChannelEvents:output_type -> lnrpc.ChannelEventUpdate - 75, // 295: lnrpc.Lightning.ClosedChannels:output_type -> lnrpc.ClosedChannelsResponse - 42, // 296: lnrpc.Lightning.OpenChannelSync:output_type -> lnrpc.ChannelPoint - 101, // 297: lnrpc.Lightning.OpenChannel:output_type -> lnrpc.OpenStatusUpdate - 99, // 298: lnrpc.Lightning.BatchOpenChannel:output_type -> lnrpc.BatchOpenChannelResponse - 111, // 299: lnrpc.Lightning.FundingStateStep:output_type -> lnrpc.FundingStateStepResp - 40, // 300: lnrpc.Lightning.ChannelAcceptor:output_type -> lnrpc.ChannelAcceptRequest - 93, // 301: lnrpc.Lightning.CloseChannel:output_type -> lnrpc.CloseStatusUpdate - 181, // 302: lnrpc.Lightning.AbandonChannel:output_type -> lnrpc.AbandonChannelResponse - 38, // 303: lnrpc.Lightning.SendPayment:output_type -> lnrpc.SendResponse - 38, // 304: lnrpc.Lightning.SendPaymentSync:output_type -> lnrpc.SendResponse - 38, // 305: lnrpc.Lightning.SendToRoute:output_type -> lnrpc.SendResponse - 38, // 306: lnrpc.Lightning.SendToRouteSync:output_type -> lnrpc.SendResponse - 165, // 307: lnrpc.Lightning.AddInvoice:output_type -> lnrpc.AddInvoiceResponse - 168, // 308: lnrpc.Lightning.ListInvoices:output_type -> lnrpc.ListInvoiceResponse - 161, // 309: lnrpc.Lightning.LookupInvoice:output_type -> lnrpc.Invoice - 161, // 310: lnrpc.Lightning.SubscribeInvoices:output_type -> lnrpc.Invoice - 171, // 311: lnrpc.Lightning.DeleteCanceledInvoice:output_type -> lnrpc.DelCanceledInvoiceResp - 185, // 312: lnrpc.Lightning.DecodePayReq:output_type -> lnrpc.PayReq - 175, // 313: lnrpc.Lightning.ListPayments:output_type -> lnrpc.ListPaymentsResponse - 178, // 314: lnrpc.Lightning.DeletePayment:output_type -> lnrpc.DeletePaymentResponse - 179, // 315: lnrpc.Lightning.DeleteAllPayments:output_type -> lnrpc.DeleteAllPaymentsResponse - 140, // 316: lnrpc.Lightning.DescribeGraph:output_type -> lnrpc.ChannelGraph - 142, // 317: lnrpc.Lightning.GetNodeMetrics:output_type -> lnrpc.NodeMetricsResponse - 138, // 318: lnrpc.Lightning.GetChanInfo:output_type -> lnrpc.ChannelEdge - 133, // 319: lnrpc.Lightning.GetNodeInfo:output_type -> lnrpc.NodeInfo - 127, // 320: lnrpc.Lightning.QueryRoutes:output_type -> lnrpc.QueryRoutesResponse - 146, // 321: lnrpc.Lightning.GetNetworkInfo:output_type -> lnrpc.NetworkInfo - 148, // 322: lnrpc.Lightning.StopDaemon:output_type -> lnrpc.StopResponse - 150, // 323: lnrpc.Lightning.SubscribeChannelGraph:output_type -> lnrpc.GraphTopologyUpdate - 183, // 324: lnrpc.Lightning.DebugLevel:output_type -> lnrpc.DebugLevelResponse - 189, // 325: lnrpc.Lightning.FeeReport:output_type -> lnrpc.FeeReportResponse - 193, // 326: lnrpc.Lightning.UpdateChannelPolicy:output_type -> lnrpc.PolicyUpdateResponse - 196, // 327: lnrpc.Lightning.ForwardingHistory:output_type -> lnrpc.ForwardingHistoryResponse - 198, // 328: lnrpc.Lightning.ExportChannelBackup:output_type -> lnrpc.ChannelBackup - 201, // 329: lnrpc.Lightning.ExportAllChannelBackups:output_type -> lnrpc.ChanBackupSnapshot - 206, // 330: lnrpc.Lightning.VerifyChanBackup:output_type -> lnrpc.VerifyChanBackupResponse - 204, // 331: lnrpc.Lightning.RestoreChannelBackups:output_type -> lnrpc.RestoreBackupResponse - 201, // 332: lnrpc.Lightning.SubscribeChannelBackups:output_type -> lnrpc.ChanBackupSnapshot - 209, // 333: lnrpc.Lightning.BakeMacaroon:output_type -> lnrpc.BakeMacaroonResponse - 211, // 334: lnrpc.Lightning.ListMacaroonIDs:output_type -> lnrpc.ListMacaroonIDsResponse - 213, // 335: lnrpc.Lightning.DeleteMacaroonID:output_type -> lnrpc.DeleteMacaroonIDResponse - 216, // 336: lnrpc.Lightning.ListPermissions:output_type -> lnrpc.ListPermissionsResponse - 222, // 337: lnrpc.Lightning.CheckMacaroonPermissions:output_type -> lnrpc.CheckMacPermResponse - 223, // 338: lnrpc.Lightning.RegisterRPCMiddleware:output_type -> lnrpc.RPCMiddlewareRequest - 26, // 339: lnrpc.Lightning.SendCustomMessage:output_type -> lnrpc.SendCustomMessageResponse - 24, // 340: lnrpc.Lightning.SubscribeCustomMessages:output_type -> lnrpc.CustomMessage - 30, // 341: lnrpc.Lightning.SendOnionMessage:output_type -> lnrpc.SendOnionMessageResponse - 28, // 342: lnrpc.Lightning.SubscribeOnionMessages:output_type -> lnrpc.OnionMessageUpdate - 71, // 343: lnrpc.Lightning.ListAliases:output_type -> lnrpc.ListAliasesResponse - 22, // 344: lnrpc.Lightning.LookupHtlcResolution:output_type -> lnrpc.LookupHtlcResolutionResponse - 274, // [274:345] is the sub-list for method output_type - 203, // [203:274] is the sub-list for method input_type - 203, // [203:203] is the sub-list for extension type_name - 203, // [203:203] is the sub-list for extension extendee - 0, // [0:203] is the sub-list for field type_name + 44, // 37: lnrpc.Resolution.outpoint:type_name -> lnrpc.OutPoint + 73, // 38: lnrpc.ClosedChannelsResponse.channels:type_name -> lnrpc.ChannelCloseSummary + 14, // 39: lnrpc.Peer.sync_type:type_name -> lnrpc.Peer.SyncType + 235, // 40: lnrpc.Peer.features:type_name -> lnrpc.Peer.FeaturesEntry + 78, // 41: lnrpc.Peer.errors:type_name -> lnrpc.TimestampedError + 77, // 42: lnrpc.ListPeersResponse.peers:type_name -> lnrpc.Peer + 15, // 43: lnrpc.PeerEvent.type:type_name -> lnrpc.PeerEvent.EventType + 89, // 44: lnrpc.GetInfoResponse.chains:type_name -> lnrpc.Chain + 236, // 45: lnrpc.GetInfoResponse.features:type_name -> lnrpc.GetInfoResponse.FeaturesEntry + 7, // 46: lnrpc.GetInfoResponse.graph_cache_status:type_name -> lnrpc.GraphCacheStatus + 237, // 47: lnrpc.GetDebugInfoResponse.config:type_name -> lnrpc.GetDebugInfoResponse.ConfigEntry + 43, // 48: lnrpc.ChannelOpenUpdate.channel_point:type_name -> lnrpc.ChannelPoint + 91, // 49: lnrpc.ChannelCloseUpdate.local_close_output:type_name -> lnrpc.CloseOutput + 91, // 50: lnrpc.ChannelCloseUpdate.remote_close_output:type_name -> lnrpc.CloseOutput + 91, // 51: lnrpc.ChannelCloseUpdate.additional_outputs:type_name -> lnrpc.CloseOutput + 43, // 52: lnrpc.CloseChannelRequest.channel_point:type_name -> lnrpc.ChannelPoint + 95, // 53: lnrpc.CloseStatusUpdate.close_pending:type_name -> lnrpc.PendingUpdate + 92, // 54: lnrpc.CloseStatusUpdate.chan_close:type_name -> lnrpc.ChannelCloseUpdate + 96, // 55: lnrpc.CloseStatusUpdate.close_instant:type_name -> lnrpc.InstantUpdate + 99, // 56: lnrpc.BatchOpenChannelRequest.channels:type_name -> lnrpc.BatchOpenChannel + 1, // 57: lnrpc.BatchOpenChannelRequest.coin_selection_strategy:type_name -> lnrpc.CoinSelectionStrategy + 3, // 58: lnrpc.BatchOpenChannel.commitment_type:type_name -> lnrpc.CommitmentType + 95, // 59: lnrpc.BatchOpenChannelResponse.pending_channels:type_name -> lnrpc.PendingUpdate + 107, // 60: lnrpc.OpenChannelRequest.funding_shim:type_name -> lnrpc.FundingShim + 3, // 61: lnrpc.OpenChannelRequest.commitment_type:type_name -> lnrpc.CommitmentType + 44, // 62: lnrpc.OpenChannelRequest.outpoints:type_name -> lnrpc.OutPoint + 95, // 63: lnrpc.OpenStatusUpdate.chan_pending:type_name -> lnrpc.PendingUpdate + 90, // 64: lnrpc.OpenStatusUpdate.chan_open:type_name -> lnrpc.ChannelOpenUpdate + 97, // 65: lnrpc.OpenStatusUpdate.psbt_fund:type_name -> lnrpc.ReadyForPsbtFunding + 103, // 66: lnrpc.KeyDescriptor.key_loc:type_name -> lnrpc.KeyLocator + 43, // 67: lnrpc.ChanPointShim.chan_point:type_name -> lnrpc.ChannelPoint + 104, // 68: lnrpc.ChanPointShim.local_key:type_name -> lnrpc.KeyDescriptor + 105, // 69: lnrpc.FundingShim.chan_point_shim:type_name -> lnrpc.ChanPointShim + 106, // 70: lnrpc.FundingShim.psbt_shim:type_name -> lnrpc.PsbtShim + 107, // 71: lnrpc.FundingTransitionMsg.shim_register:type_name -> lnrpc.FundingShim + 108, // 72: lnrpc.FundingTransitionMsg.shim_cancel:type_name -> lnrpc.FundingShimCancel + 109, // 73: lnrpc.FundingTransitionMsg.psbt_verify:type_name -> lnrpc.FundingPsbtVerify + 110, // 74: lnrpc.FundingTransitionMsg.psbt_finalize:type_name -> lnrpc.FundingPsbtFinalize + 239, // 75: lnrpc.PendingChannelsResponse.pending_open_channels:type_name -> lnrpc.PendingChannelsResponse.PendingOpenChannel + 242, // 76: lnrpc.PendingChannelsResponse.pending_closing_channels:type_name -> lnrpc.PendingChannelsResponse.ClosedChannel + 243, // 77: lnrpc.PendingChannelsResponse.pending_force_closing_channels:type_name -> lnrpc.PendingChannelsResponse.ForceClosedChannel + 240, // 78: lnrpc.PendingChannelsResponse.waiting_close_channels:type_name -> lnrpc.PendingChannelsResponse.WaitingCloseChannel + 67, // 79: lnrpc.ChannelCommitUpdate.channel:type_name -> lnrpc.Channel + 67, // 80: lnrpc.ChannelEventUpdate.open_channel:type_name -> lnrpc.Channel + 73, // 81: lnrpc.ChannelEventUpdate.closed_channel:type_name -> lnrpc.ChannelCloseSummary + 43, // 82: lnrpc.ChannelEventUpdate.active_channel:type_name -> lnrpc.ChannelPoint + 43, // 83: lnrpc.ChannelEventUpdate.inactive_channel:type_name -> lnrpc.ChannelPoint + 95, // 84: lnrpc.ChannelEventUpdate.pending_open_channel:type_name -> lnrpc.PendingUpdate + 43, // 85: lnrpc.ChannelEventUpdate.fully_resolved_channel:type_name -> lnrpc.ChannelPoint + 43, // 86: lnrpc.ChannelEventUpdate.channel_funding_timeout:type_name -> lnrpc.ChannelPoint + 117, // 87: lnrpc.ChannelEventUpdate.updated_channel:type_name -> lnrpc.ChannelCommitUpdate + 17, // 88: lnrpc.ChannelEventUpdate.type:type_name -> lnrpc.ChannelEventUpdate.UpdateType + 244, // 89: lnrpc.WalletBalanceResponse.account_balance:type_name -> lnrpc.WalletBalanceResponse.AccountBalanceEntry + 122, // 90: lnrpc.ChannelBalanceResponse.local_balance:type_name -> lnrpc.Amount + 122, // 91: lnrpc.ChannelBalanceResponse.remote_balance:type_name -> lnrpc.Amount + 122, // 92: lnrpc.ChannelBalanceResponse.unsettled_local_balance:type_name -> lnrpc.Amount + 122, // 93: lnrpc.ChannelBalanceResponse.unsettled_remote_balance:type_name -> lnrpc.Amount + 122, // 94: lnrpc.ChannelBalanceResponse.pending_open_local_balance:type_name -> lnrpc.Amount + 122, // 95: lnrpc.ChannelBalanceResponse.pending_open_remote_balance:type_name -> lnrpc.Amount + 37, // 96: lnrpc.QueryRoutesRequest.fee_limit:type_name -> lnrpc.FeeLimit + 127, // 97: lnrpc.QueryRoutesRequest.ignored_edges:type_name -> lnrpc.EdgeLocator + 126, // 98: lnrpc.QueryRoutesRequest.ignored_pairs:type_name -> lnrpc.NodePair + 245, // 99: lnrpc.QueryRoutesRequest.dest_custom_records:type_name -> lnrpc.QueryRoutesRequest.DestCustomRecordsEntry + 157, // 100: lnrpc.QueryRoutesRequest.route_hints:type_name -> lnrpc.RouteHint + 158, // 101: lnrpc.QueryRoutesRequest.blinded_payment_paths:type_name -> lnrpc.BlindedPaymentPath + 11, // 102: lnrpc.QueryRoutesRequest.dest_features:type_name -> lnrpc.FeatureBit + 132, // 103: lnrpc.QueryRoutesResponse.routes:type_name -> lnrpc.Route + 130, // 104: lnrpc.Hop.mpp_record:type_name -> lnrpc.MPPRecord + 131, // 105: lnrpc.Hop.amp_record:type_name -> lnrpc.AMPRecord + 246, // 106: lnrpc.Hop.custom_records:type_name -> lnrpc.Hop.CustomRecordsEntry + 129, // 107: lnrpc.Route.hops:type_name -> lnrpc.Hop + 135, // 108: lnrpc.NodeInfo.node:type_name -> lnrpc.LightningNode + 139, // 109: lnrpc.NodeInfo.channels:type_name -> lnrpc.ChannelEdge + 136, // 110: lnrpc.LightningNode.addresses:type_name -> lnrpc.NodeAddress + 247, // 111: lnrpc.LightningNode.features:type_name -> lnrpc.LightningNode.FeaturesEntry + 248, // 112: lnrpc.LightningNode.custom_records:type_name -> lnrpc.LightningNode.CustomRecordsEntry + 249, // 113: lnrpc.RoutingPolicy.custom_records:type_name -> lnrpc.RoutingPolicy.CustomRecordsEntry + 137, // 114: lnrpc.ChannelEdge.node1_policy:type_name -> lnrpc.RoutingPolicy + 137, // 115: lnrpc.ChannelEdge.node2_policy:type_name -> lnrpc.RoutingPolicy + 250, // 116: lnrpc.ChannelEdge.custom_records:type_name -> lnrpc.ChannelEdge.CustomRecordsEntry + 138, // 117: lnrpc.ChannelEdge.auth_proof:type_name -> lnrpc.ChannelAuthProof + 135, // 118: lnrpc.ChannelGraph.nodes:type_name -> lnrpc.LightningNode + 139, // 119: lnrpc.ChannelGraph.edges:type_name -> lnrpc.ChannelEdge + 8, // 120: lnrpc.NodeMetricsRequest.types:type_name -> lnrpc.NodeMetricType + 251, // 121: lnrpc.NodeMetricsResponse.betweenness_centrality:type_name -> lnrpc.NodeMetricsResponse.BetweennessCentralityEntry + 152, // 122: lnrpc.GraphTopologyUpdate.node_updates:type_name -> lnrpc.NodeUpdate + 153, // 123: lnrpc.GraphTopologyUpdate.channel_updates:type_name -> lnrpc.ChannelEdgeUpdate + 154, // 124: lnrpc.GraphTopologyUpdate.closed_chans:type_name -> lnrpc.ClosedChannelUpdate + 136, // 125: lnrpc.NodeUpdate.node_addresses:type_name -> lnrpc.NodeAddress + 252, // 126: lnrpc.NodeUpdate.features:type_name -> lnrpc.NodeUpdate.FeaturesEntry + 43, // 127: lnrpc.ChannelEdgeUpdate.chan_point:type_name -> lnrpc.ChannelPoint + 137, // 128: lnrpc.ChannelEdgeUpdate.routing_policy:type_name -> lnrpc.RoutingPolicy + 43, // 129: lnrpc.ClosedChannelUpdate.chan_point:type_name -> lnrpc.ChannelPoint + 155, // 130: lnrpc.RouteHint.hop_hints:type_name -> lnrpc.HopHint + 159, // 131: lnrpc.BlindedPaymentPath.blinded_path:type_name -> lnrpc.BlindedPath + 11, // 132: lnrpc.BlindedPaymentPath.features:type_name -> lnrpc.FeatureBit + 160, // 133: lnrpc.BlindedPath.blinded_hops:type_name -> lnrpc.BlindedHop + 9, // 134: lnrpc.AMPInvoiceState.state:type_name -> lnrpc.InvoiceHTLCState + 157, // 135: lnrpc.Invoice.route_hints:type_name -> lnrpc.RouteHint + 18, // 136: lnrpc.Invoice.state:type_name -> lnrpc.Invoice.InvoiceState + 164, // 137: lnrpc.Invoice.htlcs:type_name -> lnrpc.InvoiceHTLC + 253, // 138: lnrpc.Invoice.features:type_name -> lnrpc.Invoice.FeaturesEntry + 254, // 139: lnrpc.Invoice.amp_invoice_state:type_name -> lnrpc.Invoice.AmpInvoiceStateEntry + 163, // 140: lnrpc.Invoice.blinded_path_config:type_name -> lnrpc.BlindedPathConfig + 9, // 141: lnrpc.InvoiceHTLC.state:type_name -> lnrpc.InvoiceHTLCState + 255, // 142: lnrpc.InvoiceHTLC.custom_records:type_name -> lnrpc.InvoiceHTLC.CustomRecordsEntry + 165, // 143: lnrpc.InvoiceHTLC.amp:type_name -> lnrpc.AMP + 162, // 144: lnrpc.ListInvoiceResponse.invoices:type_name -> lnrpc.Invoice + 19, // 145: lnrpc.Payment.status:type_name -> lnrpc.Payment.PaymentStatus + 174, // 146: lnrpc.Payment.htlcs:type_name -> lnrpc.HTLCAttempt + 10, // 147: lnrpc.Payment.failure_reason:type_name -> lnrpc.PaymentFailureReason + 256, // 148: lnrpc.Payment.first_hop_custom_records:type_name -> lnrpc.Payment.FirstHopCustomRecordsEntry + 20, // 149: lnrpc.HTLCAttempt.status:type_name -> lnrpc.HTLCAttempt.HTLCStatus + 132, // 150: lnrpc.HTLCAttempt.route:type_name -> lnrpc.Route + 218, // 151: lnrpc.HTLCAttempt.failure:type_name -> lnrpc.Failure + 173, // 152: lnrpc.ListPaymentsResponse.payments:type_name -> lnrpc.Payment + 43, // 153: lnrpc.AbandonChannelRequest.channel_point:type_name -> lnrpc.ChannelPoint + 157, // 154: lnrpc.PayReq.route_hints:type_name -> lnrpc.RouteHint + 257, // 155: lnrpc.PayReq.features:type_name -> lnrpc.PayReq.FeaturesEntry + 158, // 156: lnrpc.PayReq.blinded_paths:type_name -> lnrpc.BlindedPaymentPath + 189, // 157: lnrpc.FeeReportResponse.channel_fees:type_name -> lnrpc.ChannelFeeReport + 43, // 158: lnrpc.PolicyUpdateRequest.chan_point:type_name -> lnrpc.ChannelPoint + 191, // 159: lnrpc.PolicyUpdateRequest.inbound_fee:type_name -> lnrpc.InboundFee + 44, // 160: lnrpc.FailedUpdate.outpoint:type_name -> lnrpc.OutPoint + 12, // 161: lnrpc.FailedUpdate.reason:type_name -> lnrpc.UpdateFailure + 193, // 162: lnrpc.PolicyUpdateResponse.failed_updates:type_name -> lnrpc.FailedUpdate + 196, // 163: lnrpc.ForwardingHistoryResponse.forwarding_events:type_name -> lnrpc.ForwardingEvent + 43, // 164: lnrpc.ExportChannelBackupRequest.chan_point:type_name -> lnrpc.ChannelPoint + 43, // 165: lnrpc.ChannelBackup.chan_point:type_name -> lnrpc.ChannelPoint + 43, // 166: lnrpc.MultiChanBackup.chan_points:type_name -> lnrpc.ChannelPoint + 203, // 167: lnrpc.ChanBackupSnapshot.single_chan_backups:type_name -> lnrpc.ChannelBackups + 200, // 168: lnrpc.ChanBackupSnapshot.multi_chan_backup:type_name -> lnrpc.MultiChanBackup + 199, // 169: lnrpc.ChannelBackups.chan_backups:type_name -> lnrpc.ChannelBackup + 203, // 170: lnrpc.RestoreChanBackupRequest.chan_backups:type_name -> lnrpc.ChannelBackups + 208, // 171: lnrpc.BakeMacaroonRequest.permissions:type_name -> lnrpc.MacaroonPermission + 208, // 172: lnrpc.MacaroonPermissionList.permissions:type_name -> lnrpc.MacaroonPermission + 258, // 173: lnrpc.ListPermissionsResponse.method_permissions:type_name -> lnrpc.ListPermissionsResponse.MethodPermissionsEntry + 21, // 174: lnrpc.Failure.code:type_name -> lnrpc.Failure.FailureCode + 219, // 175: lnrpc.Failure.channel_update:type_name -> lnrpc.ChannelUpdate + 221, // 176: lnrpc.MacaroonId.ops:type_name -> lnrpc.Op + 208, // 177: lnrpc.CheckMacPermRequest.permissions:type_name -> lnrpc.MacaroonPermission + 226, // 178: lnrpc.RPCMiddlewareRequest.stream_auth:type_name -> lnrpc.StreamAuth + 227, // 179: lnrpc.RPCMiddlewareRequest.request:type_name -> lnrpc.RPCMessage + 227, // 180: lnrpc.RPCMiddlewareRequest.response:type_name -> lnrpc.RPCMessage + 259, // 181: lnrpc.RPCMiddlewareRequest.metadata_pairs:type_name -> lnrpc.RPCMiddlewareRequest.MetadataPairsEntry + 229, // 182: lnrpc.RPCMiddlewareResponse.register:type_name -> lnrpc.MiddlewareRegistration + 230, // 183: lnrpc.RPCMiddlewareResponse.feedback:type_name -> lnrpc.InterceptFeedback + 187, // 184: lnrpc.Peer.FeaturesEntry.value:type_name -> lnrpc.Feature + 187, // 185: lnrpc.GetInfoResponse.FeaturesEntry.value:type_name -> lnrpc.Feature + 4, // 186: lnrpc.PendingChannelsResponse.PendingChannel.initiator:type_name -> lnrpc.Initiator + 3, // 187: lnrpc.PendingChannelsResponse.PendingChannel.commitment_type:type_name -> lnrpc.CommitmentType + 238, // 188: lnrpc.PendingChannelsResponse.PendingOpenChannel.channel:type_name -> lnrpc.PendingChannelsResponse.PendingChannel + 238, // 189: lnrpc.PendingChannelsResponse.WaitingCloseChannel.channel:type_name -> lnrpc.PendingChannelsResponse.PendingChannel + 241, // 190: lnrpc.PendingChannelsResponse.WaitingCloseChannel.commitments:type_name -> lnrpc.PendingChannelsResponse.Commitments + 238, // 191: lnrpc.PendingChannelsResponse.ClosedChannel.channel:type_name -> lnrpc.PendingChannelsResponse.PendingChannel + 238, // 192: lnrpc.PendingChannelsResponse.ForceClosedChannel.channel:type_name -> lnrpc.PendingChannelsResponse.PendingChannel + 113, // 193: lnrpc.PendingChannelsResponse.ForceClosedChannel.pending_htlcs:type_name -> lnrpc.PendingHTLC + 16, // 194: lnrpc.PendingChannelsResponse.ForceClosedChannel.anchor:type_name -> lnrpc.PendingChannelsResponse.ForceClosedChannel.AnchorState + 119, // 195: lnrpc.WalletBalanceResponse.AccountBalanceEntry.value:type_name -> lnrpc.WalletAccountBalance + 187, // 196: lnrpc.LightningNode.FeaturesEntry.value:type_name -> lnrpc.Feature + 144, // 197: lnrpc.NodeMetricsResponse.BetweennessCentralityEntry.value:type_name -> lnrpc.FloatMetric + 187, // 198: lnrpc.NodeUpdate.FeaturesEntry.value:type_name -> lnrpc.Feature + 187, // 199: lnrpc.Invoice.FeaturesEntry.value:type_name -> lnrpc.Feature + 161, // 200: lnrpc.Invoice.AmpInvoiceStateEntry.value:type_name -> lnrpc.AMPInvoiceState + 187, // 201: lnrpc.PayReq.FeaturesEntry.value:type_name -> lnrpc.Feature + 215, // 202: lnrpc.ListPermissionsResponse.MethodPermissionsEntry.value:type_name -> lnrpc.MacaroonPermissionList + 225, // 203: lnrpc.RPCMiddlewareRequest.MetadataPairsEntry.value:type_name -> lnrpc.MetadataValues + 120, // 204: lnrpc.Lightning.WalletBalance:input_type -> lnrpc.WalletBalanceRequest + 123, // 205: lnrpc.Lightning.ChannelBalance:input_type -> lnrpc.ChannelBalanceRequest + 35, // 206: lnrpc.Lightning.GetTransactions:input_type -> lnrpc.GetTransactionsRequest + 47, // 207: lnrpc.Lightning.EstimateFee:input_type -> lnrpc.EstimateFeeRequest + 51, // 208: lnrpc.Lightning.SendCoins:input_type -> lnrpc.SendCoinsRequest + 53, // 209: lnrpc.Lightning.ListUnspent:input_type -> lnrpc.ListUnspentRequest + 35, // 210: lnrpc.Lightning.SubscribeTransactions:input_type -> lnrpc.GetTransactionsRequest + 49, // 211: lnrpc.Lightning.SendMany:input_type -> lnrpc.SendManyRequest + 55, // 212: lnrpc.Lightning.NewAddress:input_type -> lnrpc.NewAddressRequest + 57, // 213: lnrpc.Lightning.SignMessage:input_type -> lnrpc.SignMessageRequest + 59, // 214: lnrpc.Lightning.VerifyMessage:input_type -> lnrpc.VerifyMessageRequest + 61, // 215: lnrpc.Lightning.ConnectPeer:input_type -> lnrpc.ConnectPeerRequest + 63, // 216: lnrpc.Lightning.DisconnectPeer:input_type -> lnrpc.DisconnectPeerRequest + 79, // 217: lnrpc.Lightning.ListPeers:input_type -> lnrpc.ListPeersRequest + 81, // 218: lnrpc.Lightning.SubscribePeerEvents:input_type -> lnrpc.PeerEventSubscription + 83, // 219: lnrpc.Lightning.GetInfo:input_type -> lnrpc.GetInfoRequest + 85, // 220: lnrpc.Lightning.GetDebugInfo:input_type -> lnrpc.GetDebugInfoRequest + 87, // 221: lnrpc.Lightning.GetRecoveryInfo:input_type -> lnrpc.GetRecoveryInfoRequest + 114, // 222: lnrpc.Lightning.PendingChannels:input_type -> lnrpc.PendingChannelsRequest + 68, // 223: lnrpc.Lightning.ListChannels:input_type -> lnrpc.ListChannelsRequest + 116, // 224: lnrpc.Lightning.SubscribeChannelEvents:input_type -> lnrpc.ChannelEventSubscription + 75, // 225: lnrpc.Lightning.ClosedChannels:input_type -> lnrpc.ClosedChannelsRequest + 101, // 226: lnrpc.Lightning.OpenChannelSync:input_type -> lnrpc.OpenChannelRequest + 101, // 227: lnrpc.Lightning.OpenChannel:input_type -> lnrpc.OpenChannelRequest + 98, // 228: lnrpc.Lightning.BatchOpenChannel:input_type -> lnrpc.BatchOpenChannelRequest + 111, // 229: lnrpc.Lightning.FundingStateStep:input_type -> lnrpc.FundingTransitionMsg + 42, // 230: lnrpc.Lightning.ChannelAcceptor:input_type -> lnrpc.ChannelAcceptResponse + 93, // 231: lnrpc.Lightning.CloseChannel:input_type -> lnrpc.CloseChannelRequest + 181, // 232: lnrpc.Lightning.AbandonChannel:input_type -> lnrpc.AbandonChannelRequest + 38, // 233: lnrpc.Lightning.SendPayment:input_type -> lnrpc.SendRequest + 38, // 234: lnrpc.Lightning.SendPaymentSync:input_type -> lnrpc.SendRequest + 40, // 235: lnrpc.Lightning.SendToRoute:input_type -> lnrpc.SendToRouteRequest + 40, // 236: lnrpc.Lightning.SendToRouteSync:input_type -> lnrpc.SendToRouteRequest + 162, // 237: lnrpc.Lightning.AddInvoice:input_type -> lnrpc.Invoice + 168, // 238: lnrpc.Lightning.ListInvoices:input_type -> lnrpc.ListInvoiceRequest + 167, // 239: lnrpc.Lightning.LookupInvoice:input_type -> lnrpc.PaymentHash + 170, // 240: lnrpc.Lightning.SubscribeInvoices:input_type -> lnrpc.InvoiceSubscription + 171, // 241: lnrpc.Lightning.DeleteCanceledInvoice:input_type -> lnrpc.DelCanceledInvoiceReq + 185, // 242: lnrpc.Lightning.DecodePayReq:input_type -> lnrpc.PayReqString + 175, // 243: lnrpc.Lightning.ListPayments:input_type -> lnrpc.ListPaymentsRequest + 177, // 244: lnrpc.Lightning.DeletePayment:input_type -> lnrpc.DeletePaymentRequest + 178, // 245: lnrpc.Lightning.DeleteAllPayments:input_type -> lnrpc.DeleteAllPaymentsRequest + 140, // 246: lnrpc.Lightning.DescribeGraph:input_type -> lnrpc.ChannelGraphRequest + 142, // 247: lnrpc.Lightning.GetNodeMetrics:input_type -> lnrpc.NodeMetricsRequest + 145, // 248: lnrpc.Lightning.GetChanInfo:input_type -> lnrpc.ChanInfoRequest + 133, // 249: lnrpc.Lightning.GetNodeInfo:input_type -> lnrpc.NodeInfoRequest + 125, // 250: lnrpc.Lightning.QueryRoutes:input_type -> lnrpc.QueryRoutesRequest + 146, // 251: lnrpc.Lightning.GetNetworkInfo:input_type -> lnrpc.NetworkInfoRequest + 148, // 252: lnrpc.Lightning.StopDaemon:input_type -> lnrpc.StopRequest + 150, // 253: lnrpc.Lightning.SubscribeChannelGraph:input_type -> lnrpc.GraphTopologySubscription + 183, // 254: lnrpc.Lightning.DebugLevel:input_type -> lnrpc.DebugLevelRequest + 188, // 255: lnrpc.Lightning.FeeReport:input_type -> lnrpc.FeeReportRequest + 192, // 256: lnrpc.Lightning.UpdateChannelPolicy:input_type -> lnrpc.PolicyUpdateRequest + 195, // 257: lnrpc.Lightning.ForwardingHistory:input_type -> lnrpc.ForwardingHistoryRequest + 198, // 258: lnrpc.Lightning.ExportChannelBackup:input_type -> lnrpc.ExportChannelBackupRequest + 201, // 259: lnrpc.Lightning.ExportAllChannelBackups:input_type -> lnrpc.ChanBackupExportRequest + 202, // 260: lnrpc.Lightning.VerifyChanBackup:input_type -> lnrpc.ChanBackupSnapshot + 204, // 261: lnrpc.Lightning.RestoreChannelBackups:input_type -> lnrpc.RestoreChanBackupRequest + 206, // 262: lnrpc.Lightning.SubscribeChannelBackups:input_type -> lnrpc.ChannelBackupSubscription + 209, // 263: lnrpc.Lightning.BakeMacaroon:input_type -> lnrpc.BakeMacaroonRequest + 211, // 264: lnrpc.Lightning.ListMacaroonIDs:input_type -> lnrpc.ListMacaroonIDsRequest + 213, // 265: lnrpc.Lightning.DeleteMacaroonID:input_type -> lnrpc.DeleteMacaroonIDRequest + 216, // 266: lnrpc.Lightning.ListPermissions:input_type -> lnrpc.ListPermissionsRequest + 222, // 267: lnrpc.Lightning.CheckMacaroonPermissions:input_type -> lnrpc.CheckMacPermRequest + 228, // 268: lnrpc.Lightning.RegisterRPCMiddleware:input_type -> lnrpc.RPCMiddlewareResponse + 26, // 269: lnrpc.Lightning.SendCustomMessage:input_type -> lnrpc.SendCustomMessageRequest + 24, // 270: lnrpc.Lightning.SubscribeCustomMessages:input_type -> lnrpc.SubscribeCustomMessagesRequest + 30, // 271: lnrpc.Lightning.SendOnionMessage:input_type -> lnrpc.SendOnionMessageRequest + 28, // 272: lnrpc.Lightning.SubscribeOnionMessages:input_type -> lnrpc.SubscribeOnionMessagesRequest + 71, // 273: lnrpc.Lightning.ListAliases:input_type -> lnrpc.ListAliasesRequest + 22, // 274: lnrpc.Lightning.LookupHtlcResolution:input_type -> lnrpc.LookupHtlcResolutionRequest + 121, // 275: lnrpc.Lightning.WalletBalance:output_type -> lnrpc.WalletBalanceResponse + 124, // 276: lnrpc.Lightning.ChannelBalance:output_type -> lnrpc.ChannelBalanceResponse + 36, // 277: lnrpc.Lightning.GetTransactions:output_type -> lnrpc.TransactionDetails + 48, // 278: lnrpc.Lightning.EstimateFee:output_type -> lnrpc.EstimateFeeResponse + 52, // 279: lnrpc.Lightning.SendCoins:output_type -> lnrpc.SendCoinsResponse + 54, // 280: lnrpc.Lightning.ListUnspent:output_type -> lnrpc.ListUnspentResponse + 34, // 281: lnrpc.Lightning.SubscribeTransactions:output_type -> lnrpc.Transaction + 50, // 282: lnrpc.Lightning.SendMany:output_type -> lnrpc.SendManyResponse + 56, // 283: lnrpc.Lightning.NewAddress:output_type -> lnrpc.NewAddressResponse + 58, // 284: lnrpc.Lightning.SignMessage:output_type -> lnrpc.SignMessageResponse + 60, // 285: lnrpc.Lightning.VerifyMessage:output_type -> lnrpc.VerifyMessageResponse + 62, // 286: lnrpc.Lightning.ConnectPeer:output_type -> lnrpc.ConnectPeerResponse + 64, // 287: lnrpc.Lightning.DisconnectPeer:output_type -> lnrpc.DisconnectPeerResponse + 80, // 288: lnrpc.Lightning.ListPeers:output_type -> lnrpc.ListPeersResponse + 82, // 289: lnrpc.Lightning.SubscribePeerEvents:output_type -> lnrpc.PeerEvent + 84, // 290: lnrpc.Lightning.GetInfo:output_type -> lnrpc.GetInfoResponse + 86, // 291: lnrpc.Lightning.GetDebugInfo:output_type -> lnrpc.GetDebugInfoResponse + 88, // 292: lnrpc.Lightning.GetRecoveryInfo:output_type -> lnrpc.GetRecoveryInfoResponse + 115, // 293: lnrpc.Lightning.PendingChannels:output_type -> lnrpc.PendingChannelsResponse + 69, // 294: lnrpc.Lightning.ListChannels:output_type -> lnrpc.ListChannelsResponse + 118, // 295: lnrpc.Lightning.SubscribeChannelEvents:output_type -> lnrpc.ChannelEventUpdate + 76, // 296: lnrpc.Lightning.ClosedChannels:output_type -> lnrpc.ClosedChannelsResponse + 43, // 297: lnrpc.Lightning.OpenChannelSync:output_type -> lnrpc.ChannelPoint + 102, // 298: lnrpc.Lightning.OpenChannel:output_type -> lnrpc.OpenStatusUpdate + 100, // 299: lnrpc.Lightning.BatchOpenChannel:output_type -> lnrpc.BatchOpenChannelResponse + 112, // 300: lnrpc.Lightning.FundingStateStep:output_type -> lnrpc.FundingStateStepResp + 41, // 301: lnrpc.Lightning.ChannelAcceptor:output_type -> lnrpc.ChannelAcceptRequest + 94, // 302: lnrpc.Lightning.CloseChannel:output_type -> lnrpc.CloseStatusUpdate + 182, // 303: lnrpc.Lightning.AbandonChannel:output_type -> lnrpc.AbandonChannelResponse + 39, // 304: lnrpc.Lightning.SendPayment:output_type -> lnrpc.SendResponse + 39, // 305: lnrpc.Lightning.SendPaymentSync:output_type -> lnrpc.SendResponse + 39, // 306: lnrpc.Lightning.SendToRoute:output_type -> lnrpc.SendResponse + 39, // 307: lnrpc.Lightning.SendToRouteSync:output_type -> lnrpc.SendResponse + 166, // 308: lnrpc.Lightning.AddInvoice:output_type -> lnrpc.AddInvoiceResponse + 169, // 309: lnrpc.Lightning.ListInvoices:output_type -> lnrpc.ListInvoiceResponse + 162, // 310: lnrpc.Lightning.LookupInvoice:output_type -> lnrpc.Invoice + 162, // 311: lnrpc.Lightning.SubscribeInvoices:output_type -> lnrpc.Invoice + 172, // 312: lnrpc.Lightning.DeleteCanceledInvoice:output_type -> lnrpc.DelCanceledInvoiceResp + 186, // 313: lnrpc.Lightning.DecodePayReq:output_type -> lnrpc.PayReq + 176, // 314: lnrpc.Lightning.ListPayments:output_type -> lnrpc.ListPaymentsResponse + 179, // 315: lnrpc.Lightning.DeletePayment:output_type -> lnrpc.DeletePaymentResponse + 180, // 316: lnrpc.Lightning.DeleteAllPayments:output_type -> lnrpc.DeleteAllPaymentsResponse + 141, // 317: lnrpc.Lightning.DescribeGraph:output_type -> lnrpc.ChannelGraph + 143, // 318: lnrpc.Lightning.GetNodeMetrics:output_type -> lnrpc.NodeMetricsResponse + 139, // 319: lnrpc.Lightning.GetChanInfo:output_type -> lnrpc.ChannelEdge + 134, // 320: lnrpc.Lightning.GetNodeInfo:output_type -> lnrpc.NodeInfo + 128, // 321: lnrpc.Lightning.QueryRoutes:output_type -> lnrpc.QueryRoutesResponse + 147, // 322: lnrpc.Lightning.GetNetworkInfo:output_type -> lnrpc.NetworkInfo + 149, // 323: lnrpc.Lightning.StopDaemon:output_type -> lnrpc.StopResponse + 151, // 324: lnrpc.Lightning.SubscribeChannelGraph:output_type -> lnrpc.GraphTopologyUpdate + 184, // 325: lnrpc.Lightning.DebugLevel:output_type -> lnrpc.DebugLevelResponse + 190, // 326: lnrpc.Lightning.FeeReport:output_type -> lnrpc.FeeReportResponse + 194, // 327: lnrpc.Lightning.UpdateChannelPolicy:output_type -> lnrpc.PolicyUpdateResponse + 197, // 328: lnrpc.Lightning.ForwardingHistory:output_type -> lnrpc.ForwardingHistoryResponse + 199, // 329: lnrpc.Lightning.ExportChannelBackup:output_type -> lnrpc.ChannelBackup + 202, // 330: lnrpc.Lightning.ExportAllChannelBackups:output_type -> lnrpc.ChanBackupSnapshot + 207, // 331: lnrpc.Lightning.VerifyChanBackup:output_type -> lnrpc.VerifyChanBackupResponse + 205, // 332: lnrpc.Lightning.RestoreChannelBackups:output_type -> lnrpc.RestoreBackupResponse + 202, // 333: lnrpc.Lightning.SubscribeChannelBackups:output_type -> lnrpc.ChanBackupSnapshot + 210, // 334: lnrpc.Lightning.BakeMacaroon:output_type -> lnrpc.BakeMacaroonResponse + 212, // 335: lnrpc.Lightning.ListMacaroonIDs:output_type -> lnrpc.ListMacaroonIDsResponse + 214, // 336: lnrpc.Lightning.DeleteMacaroonID:output_type -> lnrpc.DeleteMacaroonIDResponse + 217, // 337: lnrpc.Lightning.ListPermissions:output_type -> lnrpc.ListPermissionsResponse + 223, // 338: lnrpc.Lightning.CheckMacaroonPermissions:output_type -> lnrpc.CheckMacPermResponse + 224, // 339: lnrpc.Lightning.RegisterRPCMiddleware:output_type -> lnrpc.RPCMiddlewareRequest + 27, // 340: lnrpc.Lightning.SendCustomMessage:output_type -> lnrpc.SendCustomMessageResponse + 25, // 341: lnrpc.Lightning.SubscribeCustomMessages:output_type -> lnrpc.CustomMessage + 31, // 342: lnrpc.Lightning.SendOnionMessage:output_type -> lnrpc.SendOnionMessageResponse + 29, // 343: lnrpc.Lightning.SubscribeOnionMessages:output_type -> lnrpc.OnionMessageUpdate + 72, // 344: lnrpc.Lightning.ListAliases:output_type -> lnrpc.ListAliasesResponse + 23, // 345: lnrpc.Lightning.LookupHtlcResolution:output_type -> lnrpc.LookupHtlcResolutionResponse + 275, // [275:346] is the sub-list for method output_type + 204, // [204:275] is the sub-list for method input_type + 204, // [204:204] is the sub-list for extension type_name + 204, // [204:204] is the sub-list for extension extendee + 0, // [0:204] is the sub-list for field type_name } func init() { file_lightning_proto_init() } @@ -21121,7 +21190,7 @@ func file_lightning_proto_init() { File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_lightning_proto_rawDesc), len(file_lightning_proto_rawDesc)), - NumEnums: 21, + NumEnums: 22, NumMessages: 238, NumExtensions: 0, NumServices: 1, diff --git a/lnrpc/lightning.proto b/lnrpc/lightning.proto index b1323db45..170b12744 100644 --- a/lnrpc/lightning.proto +++ b/lnrpc/lightning.proto @@ -2058,6 +2058,13 @@ message PeerEvent { message GetInfoRequest { } +enum GraphCacheStatus { + GRAPH_CACHE_STATUS_DISABLED = 0; + GRAPH_CACHE_STATUS_LOADING = 1; + GRAPH_CACHE_STATUS_LOADED = 2; + GRAPH_CACHE_STATUS_FAILED = 3; +} + message GetInfoResponse { // The version of the LND software that the node is running. string version = 14; @@ -2136,6 +2143,9 @@ message GetInfoResponse { // Whether the wallet is fully synced to the best chain. This indicates the // wallet's internal sync state with the backing chain source. bool wallet_synced = 23; + + // The current status of the in-memory graph cache. + GraphCacheStatus graph_cache_status = 24; } message GetDebugInfoRequest { diff --git a/lnrpc/lightning.swagger.json b/lnrpc/lightning.swagger.json index 96ded8645..f7140cd47 100644 --- a/lnrpc/lightning.swagger.json +++ b/lnrpc/lightning.swagger.json @@ -5588,6 +5588,10 @@ "wallet_synced": { "type": "boolean", "description": "Whether the wallet is fully synced to the best chain. This indicates the\nwallet's internal sync state with the backing chain source." + }, + "graph_cache_status": { + "$ref": "#/definitions/lnrpcGraphCacheStatus", + "description": "The current status of the in-memory graph cache." } } }, @@ -5609,6 +5613,16 @@ } } }, + "lnrpcGraphCacheStatus": { + "type": "string", + "enum": [ + "GRAPH_CACHE_STATUS_DISABLED", + "GRAPH_CACHE_STATUS_LOADING", + "GRAPH_CACHE_STATUS_LOADED", + "GRAPH_CACHE_STATUS_FAILED" + ], + "default": "GRAPH_CACHE_STATUS_DISABLED" + }, "lnrpcGraphTopologyUpdate": { "type": "object", "properties": { diff --git a/rpcserver.go b/rpcserver.go index de28c47ce..bea5d7597 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -3431,6 +3431,8 @@ func (r *rpcServer) GetInfo(_ context.Context, isTestNet := chainreg.IsTestnet(&r.cfg.ActiveNetParams) nodeColor := graphdb.EncodeHexColor(nodeAnn.RGBColor) version := build.Version() + " commit=" + build.Commit + cacheStatus := r.server.graphDB.GraphCacheStatus() + graphCacheStatus := rpcGraphCacheStatus(cacheStatus) return &lnrpc.GetInfoResponse{ IdentityPubkey: encodedIDPub, @@ -3454,9 +3456,30 @@ func (r *rpcServer) GetInfo(_ context.Context, RequireHtlcInterceptor: r.cfg.RequireInterceptor, StoreFinalHtlcResolutions: r.cfg.StoreFinalHtlcResolutions, WalletSynced: syncInfo.isWalletSynced, + GraphCacheStatus: graphCacheStatus, }, nil } +// rpcGraphCacheStatus maps the graph DB cache status to the lnrpc enum used by +// GetInfo. +func rpcGraphCacheStatus( + status graphdb.GraphCacheStatus) lnrpc.GraphCacheStatus { + + switch status { + case graphdb.GraphCacheStatusDisabled: + return lnrpc.GraphCacheStatus_GRAPH_CACHE_STATUS_DISABLED + + case graphdb.GraphCacheStatusLoaded: + return lnrpc.GraphCacheStatus_GRAPH_CACHE_STATUS_LOADED + + case graphdb.GraphCacheStatusFailed: + return lnrpc.GraphCacheStatus_GRAPH_CACHE_STATUS_FAILED + + default: + return lnrpc.GraphCacheStatus_GRAPH_CACHE_STATUS_LOADING + } +} + // GetDebugInfo returns debug information concerning the state of the daemon // and its subsystems. By default, this returns only the configuration. If the // `include_log` flag is set in the request, the latest log entries from the From f733eed26ee5fdac9de1945361b0460ed5d58d07 Mon Sep 17 00:00:00 2001 From: Elle Mouton Date: Mon, 24 Nov 2025 13:33:38 +0200 Subject: [PATCH 9/9] docs: add release notes --- docs/release-notes/release-notes-0.21.0.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/docs/release-notes/release-notes-0.21.0.md b/docs/release-notes/release-notes-0.21.0.md index c9d458d18..87309d0dc 100644 --- a/docs/release-notes/release-notes-0.21.0.md +++ b/docs/release-notes/release-notes-0.21.0.md @@ -166,6 +166,13 @@ ## Performance Improvements +* Let the [channel graph cache be populated + asynchronously](https://github.com/lightningnetwork/lnd/pull/10065) on + startup. While the cache is being populated, the graph is still available for + queries, but all read queries will be served from the database until the cache + is fully populated. This new behaviour can be opted out of via the new + `--db.sync-graph-cache-load` option. + * [Replace the catch-all `FilterInvoices` SQL query with five focused, index-friendly queries](https://github.com/lightningnetwork/lnd/pull/10601) (`FetchPendingInvoices`, `FilterInvoicesBySettleIndex`, @@ -176,11 +183,11 @@ only the parameters it actually needs and uses a direct `ORDER BY`, allowing the planner to perform efficient index range scans on the invoice table. -* [Fix full table scans on the HTLC settlement +* [Fix full table scans on the HTLC settlement hot path](https://github.com/lightningnetwork/lnd/pull/10619). Replace the catch-all `GetInvoice` query (which used `OR $1 IS NULL` predicates that forced full table scans) with three dedicated queries - targeting uniquely-constrained columns. Also drop four redundant indexes + targeting uniquely-constrained columns. Also drop four redundant indexes that duplicated UNIQUE constraints or were never used as query filters. ## Deprecations