Skip to content

Commit 64110cf

Browse files
committed
graph/db: let FetchChannelEdgesByID behave as promised
The comment of FetchChannelEdgesByID says that if the ErrZombieEdge error is returned, then the ChannelEdgeInfo return parameter will also still be populated and returned (ie, wont be nil). This commit updates the SQLStore implementation of FetchChannelEdgesByID to do this. This is needed to prevent nil dereference panics at any call-sites that depend on the method working as it describes.
1 parent 5f961e4 commit 64110cf

File tree

2 files changed

+26
-8
lines changed

2 files changed

+26
-8
lines changed

graph/db/graph_test.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -451,8 +451,14 @@ func TestEdgeInsertionDeletion(t *testing.T) {
451451
// properly deleted.
452452
_, _, _, err = graph.FetchChannelEdgesByOutpoint(&outpoint)
453453
require.ErrorIs(t, err, ErrEdgeNotFound)
454-
_, _, _, err = graph.FetchChannelEdgesByID(chanID)
454+
455+
// Assert that if the edge is a zombie, then FetchChannelEdgesByID
456+
// still returns a populated models.ChannelEdgeInfo as its comment
457+
// description promises.
458+
edge, _, _, err := graph.FetchChannelEdgesByID(chanID)
455459
require.ErrorIs(t, err, ErrZombieEdge)
460+
require.NotNil(t, edge)
461+
456462
isZombie, _, _, err := graph.IsZombieEdge(chanID)
457463
require.NoError(t, err)
458464
require.True(t, isZombie)

graph/db/sql_store.go

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1852,20 +1852,29 @@ func (s *SQLStore) FetchChannelEdgesByID(chanID uint64) (
18521852
if errors.Is(err, sql.ErrNoRows) {
18531853
// First check if this edge is perhaps in the zombie
18541854
// index.
1855-
isZombie, err := db.IsZombieChannel(
1856-
ctx, sqlc.IsZombieChannelParams{
1855+
zombie, err := db.GetZombieChannel(
1856+
ctx, sqlc.GetZombieChannelParams{
18571857
Scid: chanIDB[:],
18581858
Version: int16(ProtocolV1),
18591859
},
18601860
)
1861-
if err != nil {
1861+
if errors.Is(err, sql.ErrNoRows) {
1862+
return ErrEdgeNotFound
1863+
} else if err != nil {
18621864
return fmt.Errorf("unable to check if "+
18631865
"channel is zombie: %w", err)
1864-
} else if isZombie {
1865-
return ErrZombieEdge
18661866
}
18671867

1868-
return ErrEdgeNotFound
1868+
// At this point, we know the channel is a zombie, so
1869+
// we'll return an error indicating this, and we will
1870+
// populate the edge info with the public keys of each
1871+
// party as this is the only information we have about
1872+
// it.
1873+
edge = &models.ChannelEdgeInfo{}
1874+
copy(edge.NodeKey1Bytes[:], zombie.NodeKey1)
1875+
copy(edge.NodeKey2Bytes[:], zombie.NodeKey2)
1876+
1877+
return ErrZombieEdge
18691878
} else if err != nil {
18701879
return fmt.Errorf("unable to fetch channel: %w", err)
18711880
}
@@ -1903,7 +1912,10 @@ func (s *SQLStore) FetchChannelEdgesByID(chanID uint64) (
19031912
return nil
19041913
}, sqldb.NoOpReset)
19051914
if err != nil {
1906-
return nil, nil, nil, fmt.Errorf("could not fetch channel: %w",
1915+
// If we are returning the ErrZombieEdge, then we also need to
1916+
// return the edge info as the method comment indicates that
1917+
// this will be populated when the edge is a zombie.
1918+
return edge, nil, nil, fmt.Errorf("could not fetch channel: %w",
19071919
err)
19081920
}
19091921

0 commit comments

Comments
 (0)