mirror of
https://github.com/lightninglabs/faraday.git
synced 2026-08-13 12:33:35 +02:00
chanevents+db: add latest-event-before lookup
Add GetLatestChannelUpdateBefore, which fetches the most recent EventTypeUpdate strictly before a given instant. Forwarding-ability analyses that summarise behaviour over a window must seed their state from the channel's balance at the window's lower bound; without the ability to look back past that bound, the first events in the window have no baseline to compare against. The lookup tolerates missing predecessors by returning (nil, nil), letting callers distinguish "no prior update" from a genuine error. Coverage exercises both the present and absent cases against the existing TestStore fixture.
This commit is contained in:
parent
a568dfedf0
commit
7431bb5d67
5 changed files with 83 additions and 0 deletions
|
|
@ -43,6 +43,12 @@ type Queries interface {
|
|||
|
||||
GetChannelEvents(ctx context.Context,
|
||||
arg sqlc.GetChannelEventsParams) ([]sqlc.ChannelEvent, error)
|
||||
|
||||
GetLatestChannelEventBefore(ctx context.Context,
|
||||
arg sqlc.GetLatestChannelEventBeforeParams) (
|
||||
sqlc.ChannelEvent,
|
||||
error,
|
||||
)
|
||||
}
|
||||
|
||||
// Store provides access to the db for channel events.
|
||||
|
|
@ -257,6 +263,31 @@ func (s *Store) GetChannelEvents(ctx context.Context, channelID, afterID int64,
|
|||
return events, 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,
|
||||
channelID int64, before time.Time) (*ChannelEvent, error) {
|
||||
|
||||
dbEvent, err := s.db.GetLatestChannelEventBefore(
|
||||
ctx, sqlc.GetLatestChannelEventBeforeParams{
|
||||
ChannelID: channelID,
|
||||
Timestamp: before.UTC(),
|
||||
EventType: int16(EventTypeUpdate),
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
// If there are no events before the start time, we return (nil,
|
||||
// nil).
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return marshalChannelEvent(dbEvent), nil
|
||||
}
|
||||
|
||||
// marshalChannelEvent converts a db channel event into our internal type.
|
||||
func marshalChannelEvent(dbEvent sqlc.ChannelEvent) *ChannelEvent {
|
||||
var localBalance fn.Option[btcutil.Amount]
|
||||
|
|
|
|||
|
|
@ -134,6 +134,23 @@ func TestStore(t *testing.T) {
|
|||
requireEqualEvent(
|
||||
t, updateEvent, testTime.Add(time.Second), events[1],
|
||||
)
|
||||
updateEvent = events[1]
|
||||
|
||||
// If we query a time after the update event, we'll obtain the update
|
||||
// event as the latest event.
|
||||
initEvent, err := store.GetLatestChannelUpdateBefore(
|
||||
ctx, channelID, updateEvent.Timestamp.Add(500*time.Millisecond),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
requireEqualEvent(t, updateEvent, testTime.Add(time.Second), initEvent)
|
||||
|
||||
// If we query at the update event's timestamp, the only event before
|
||||
// that is left is the online event, which is not an update.
|
||||
initEvent, err = store.GetLatestChannelUpdateBefore(
|
||||
ctx, channelID, updateEvent.Timestamp,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
require.Nil(t, initEvent)
|
||||
|
||||
// Advance the clock and add a sync event to verify the IsSync flag
|
||||
// round-trips correctly.
|
||||
|
|
|
|||
|
|
@ -98,6 +98,34 @@ func (q *Queries) GetChannelEvents(ctx context.Context, arg GetChannelEventsPara
|
|||
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
|
||||
ORDER BY timestamp DESC, id DESC
|
||||
LIMIT 1
|
||||
`
|
||||
|
||||
type GetLatestChannelEventBeforeParams struct {
|
||||
ChannelID int64
|
||||
EventType int16
|
||||
Timestamp time.Time
|
||||
}
|
||||
|
||||
func (q *Queries) GetLatestChannelEventBefore(ctx context.Context, arg GetLatestChannelEventBeforeParams) (ChannelEvent, error) {
|
||||
row := q.db.QueryRowContext(ctx, getLatestChannelEventBefore, arg.ChannelID, arg.EventType, arg.Timestamp)
|
||||
var i ChannelEvent
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.ChannelID,
|
||||
&i.EventType,
|
||||
&i.Timestamp,
|
||||
&i.LocalBalanceSat,
|
||||
&i.RemoteBalanceSat,
|
||||
&i.IsSync,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const getPeerByPubKey = `-- name: GetPeerByPubKey :one
|
||||
SELECT id, pubkey FROM peers WHERE pubkey = $1
|
||||
`
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
GetLatestChannelEventBefore(ctx context.Context, arg GetLatestChannelEventBeforeParams) (ChannelEvent, error)
|
||||
GetPeerByPubKey(ctx context.Context, pubkey string) (Peer, error)
|
||||
InsertChannel(ctx context.Context, arg InsertChannelParams) (int64, error)
|
||||
InsertChannelEvent(ctx context.Context, arg InsertChannelEventParams) error
|
||||
|
|
|
|||
|
|
@ -27,3 +27,9 @@ WHERE channel_id = $1
|
|||
AND timestamp < $4
|
||||
ORDER BY id ASC
|
||||
LIMIT $5;
|
||||
|
||||
-- name: GetLatestChannelEventBefore :one
|
||||
SELECT * FROM channel_events
|
||||
WHERE channel_id = $1 AND event_type = $2 AND timestamp < $3
|
||||
ORDER BY timestamp DESC, id DESC
|
||||
LIMIT 1;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue