diff --git a/chanevents/store.go b/chanevents/store.go index 78a7a7e..0cbe442 100644 --- a/chanevents/store.go +++ b/chanevents/store.go @@ -49,6 +49,8 @@ type Queries interface { sqlc.ChannelEvent, error, ) + + GetChannels(ctx context.Context) ([]sqlc.GetChannelsRow, error) } // Store provides access to the db for channel events. @@ -263,6 +265,29 @@ func (s *Store) GetChannelEvents(ctx context.Context, channelID, afterID int64, return events, nil } +// ScidToPeerMap returns the historic scid→peer index, including channels that +// have since closed. Unconfirmed channels (scid still zero) are not part of +// the contract. +func (s *Store) ScidToPeerMap(ctx context.Context) (map[uint64]string, error) { + dbChannels, err := s.db.GetChannels(ctx) + if err != nil { + return nil, err + } + + scidToPeer := make(map[uint64]string, len(dbChannels)) + for _, dbChannel := range dbChannels { + // The short channel ID can be zero if it's not known yet. We + // should just ignore those. + if dbChannel.ShortChannelID == 0 { + continue + } + + scidToPeer[uint64(dbChannel.ShortChannelID)] = dbChannel.Pubkey + } + + return scidToPeer, nil +} + // GetLatestChannelUpdateBefore returns the latest channel event before a given // time (exclusive). If no event is found, it returns (nil, nil). func (s *Store) GetLatestChannelUpdateBefore(ctx context.Context, diff --git a/chanevents/store_test.go b/chanevents/store_test.go index 7cb91c1..b2cbae6 100644 --- a/chanevents/store_test.go +++ b/chanevents/store_test.go @@ -100,6 +100,13 @@ func TestStore(t *testing.T) { require.NoError(t, err) require.NotZero(t, channel2ID) + // Get the historic channel to peer map. + chanToPeer, err := store.ScidToPeerMap(ctx) + require.NoError(t, err) + require.Len(t, chanToPeer, 2) + require.Equal(t, testPubKey, chanToPeer[testShortChanID1]) + require.Equal(t, testPubKey, chanToPeer[testShortChanID2]) + // Add an online event for the channel. onlineEvent := &ChannelEvent{ ChannelID: channelID, diff --git a/db/sqlc/chanevents.sql.go b/db/sqlc/chanevents.sql.go index 82441f6..ba1dee2 100644 --- a/db/sqlc/chanevents.sql.go +++ b/db/sqlc/chanevents.sql.go @@ -98,6 +98,41 @@ func (q *Queries) GetChannelEvents(ctx context.Context, arg GetChannelEventsPara return items, nil } +const getChannels = `-- name: GetChannels :many +SELECT c.id, c.short_channel_id, p.pubkey +FROM channels c +JOIN peers p ON c.peer_id = p.id +` + +type GetChannelsRow struct { + ID int64 + ShortChannelID int64 + Pubkey string +} + +func (q *Queries) GetChannels(ctx context.Context) ([]GetChannelsRow, error) { + rows, err := q.db.QueryContext(ctx, getChannels) + if err != nil { + return nil, err + } + defer rows.Close() + var items []GetChannelsRow + for rows.Next() { + var i GetChannelsRow + if err := rows.Scan(&i.ID, &i.ShortChannelID, &i.Pubkey); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + const getLatestChannelEventBefore = `-- name: GetLatestChannelEventBefore :one SELECT id, channel_id, event_type, timestamp, local_balance_sat, remote_balance_sat, is_sync FROM channel_events WHERE channel_id = $1 AND event_type = $2 AND timestamp < $3 diff --git a/db/sqlc/querier.go b/db/sqlc/querier.go index 661f75c..b62ec68 100644 --- a/db/sqlc/querier.go +++ b/db/sqlc/querier.go @@ -12,6 +12,7 @@ type Querier interface { GetChannelByChanPoint(ctx context.Context, channelPoint string) (Channel, error) GetChannelByShortChanID(ctx context.Context, shortChannelID int64) (Channel, error) GetChannelEvents(ctx context.Context, arg GetChannelEventsParams) ([]ChannelEvent, error) + GetChannels(ctx context.Context) ([]GetChannelsRow, error) GetLatestChannelEventBefore(ctx context.Context, arg GetLatestChannelEventBeforeParams) (ChannelEvent, error) GetPeerByPubKey(ctx context.Context, pubkey string) (Peer, error) InsertChannel(ctx context.Context, arg InsertChannelParams) (int64, error) diff --git a/db/sqlc/queries/chanevents.sql b/db/sqlc/queries/chanevents.sql index 9f567f3..d9d1629 100644 --- a/db/sqlc/queries/chanevents.sql +++ b/db/sqlc/queries/chanevents.sql @@ -33,3 +33,8 @@ SELECT * FROM channel_events WHERE channel_id = $1 AND event_type = $2 AND timestamp < $3 ORDER BY timestamp DESC, id DESC LIMIT 1; + +-- name: GetChannels :many +SELECT c.id, c.short_channel_id, p.pubkey +FROM channels c +JOIN peers p ON c.peer_id = p.id;