channeldb/graph: skip unknown edges in FetchChanInfos
This commit modifies FetchChanInfos to skip any channels that are not in the graph at the time of the call. Currently the entire call will fail if the edge is not found, which stalls a gossip sync in the following scenario: 1. Remote peer queries for a channel range 2. We return the set of channel ids in that range 3. A channel from that set is removed from the graph, e.g. via close. 4. Remote peer queries for removed edge, causing the query to fail. To remedy this, we will now skip any edges that are not known in the database at the time of the query. This prevents the syncer state machines from halting, which otherwise could only be resolved by disconnecting and reconnecting.
This commit is contained in:
parent
a2aeb646e7
commit
4a755435e6
@ -1636,9 +1636,11 @@ func (c *ChannelGraph) FilterChannelRange(startHeight, endHeight uint32) ([]uint
|
||||
return chanIDs, nil
|
||||
}
|
||||
|
||||
// FetchChanInfos returns the set of channel edges that correspond to the
|
||||
// passed channel ID's. This can be used to respond to peer queries that are
|
||||
// seeking to fill in gaps in their view of the channel graph.
|
||||
// FetchChanInfos returns the set of channel edges that correspond to the passed
|
||||
// channel ID's. If an edge is the query is unknown to the database, it will
|
||||
// skipped and the result will contain only those edges that exist at the time
|
||||
// of the query. This can be used to respond to peer queries that are seeking to
|
||||
// fill in gaps in their view of the channel graph.
|
||||
func (c *ChannelGraph) FetchChanInfos(chanIDs []uint64) ([]ChannelEdge, error) {
|
||||
// TODO(roasbeef): sort cids?
|
||||
|
||||
@ -1664,11 +1666,16 @@ func (c *ChannelGraph) FetchChanInfos(chanIDs []uint64) ([]ChannelEdge, error) {
|
||||
for _, cid := range chanIDs {
|
||||
byteOrder.PutUint64(cidBytes[:], cid)
|
||||
|
||||
// First, we'll fetch the static edge information.
|
||||
// First, we'll fetch the static edge information. If
|
||||
// the edge is unknown, we will skip the edge and
|
||||
// continue gathering all known edges.
|
||||
edgeInfo, err := fetchChanEdgeInfo(
|
||||
edgeIndex, cidBytes[:],
|
||||
)
|
||||
if err != nil {
|
||||
switch {
|
||||
case err == ErrEdgeNotFound:
|
||||
continue
|
||||
case err != nil:
|
||||
return err
|
||||
}
|
||||
edgeInfo.db = c.db
|
||||
|
@ -2006,6 +2006,24 @@ func TestFetchChanInfos(t *testing.T) {
|
||||
edgeQuery = append(edgeQuery, chanID.ToUint64())
|
||||
}
|
||||
|
||||
// Add an additional edge that does not exist. The query should skip
|
||||
// this channel and return only infos for the edges that exist.
|
||||
edgeQuery = append(edgeQuery, 500)
|
||||
|
||||
// Add an another edge to the query that has been marked as a zombie
|
||||
// edge. The query should also skip this channel.
|
||||
zombieChan, zombieChanID := createEdge(
|
||||
666, 0, 0, 0, node1, node2,
|
||||
)
|
||||
if err := graph.AddChannelEdge(&zombieChan); err != nil {
|
||||
t.Fatalf("unable to create channel edge: %v", err)
|
||||
}
|
||||
err = graph.DeleteChannelEdge(&zombieChan.ChannelPoint)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to delete and mark edge zombie: %v", err)
|
||||
}
|
||||
edgeQuery = append(edgeQuery, zombieChanID.ToUint64())
|
||||
|
||||
// We'll now attempt to query for the range of channel ID's we just
|
||||
// inserted into the database. We should get the exact same set of
|
||||
// edges back.
|
||||
|
Loading…
Reference in New Issue
Block a user