-
Notifications
You must be signed in to change notification settings - Fork 33
chanevents: implement GetChannelEvents rpc #239
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
26bdf91
629047f
c1ada7a
9e10faa
44bb231
dc9b638
b0e07dc
f118640
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,97 @@ | ||
| package main | ||
|
|
||
| import ( | ||
| "context" | ||
| "fmt" | ||
|
|
||
| "github.com/lightninglabs/faraday/frdrpc" | ||
| "github.com/urfave/cli" | ||
| ) | ||
|
|
||
| var chanEventsCommand = cli.Command{ | ||
| Name: "chanevents", | ||
| Category: "reporting", | ||
| Usage: "Get a report of channel events.", | ||
| Description: ` | ||
| Get a report for a channel which provides a detailed account of its | ||
| lifecycle events. The server caps each response; if has_more is true, | ||
| fetch the next page by re-running with --last_id set to the previous | ||
| response's last_id. Stop when has_more is false. --start_time and | ||
| --end_time are independent filters and do not need to advance between | ||
| paginated calls.`, | ||
| ArgsUsage: "funding_txid [output_index]", | ||
| Flags: []cli.Flag{ | ||
| cli.StringFlag{ | ||
| Name: "funding_txid", | ||
| Usage: "the txid of the channel's funding transaction", | ||
| }, | ||
| cli.IntFlag{ | ||
| Name: "output_index", | ||
| Usage: "the output index for the funding output of " + | ||
| "the funding transaction", | ||
| }, | ||
| cli.Int64Flag{ | ||
| Name: "start_time", | ||
| Usage: "start time of the query range as a unix timestamp", | ||
| }, | ||
| cli.Int64Flag{ | ||
| Name: "end_time", | ||
| Usage: "end time of the query range as a unix " + | ||
| "timestamp; zero defaults to the server's " + | ||
| "current time", | ||
| }, | ||
| cli.UintFlag{ | ||
| Name: "max_events", | ||
| Usage: "maximum number of events to return; zero " + | ||
| "uses the server default (capped server-side)", | ||
| }, | ||
| cli.Int64Flag{ | ||
| Name: "last_id", | ||
| Usage: "pagination cursor; pass the previous " + | ||
| "response's last_id to continue, or zero " + | ||
| "for the first page", | ||
| }, | ||
| }, | ||
| Action: queryChanEvents, | ||
| } | ||
|
|
||
| func queryChanEvents(ctx *cli.Context) error { | ||
| client, cleanup := getClient(ctx) | ||
| defer cleanup() | ||
|
|
||
| // Show command help if the channel point was not provided. | ||
| if ctx.NArg() == 0 && ctx.String("funding_txid") == "" { | ||
| return cli.ShowCommandHelp(ctx, "chanevents") | ||
| } | ||
|
|
||
| outpoint, err := parseChannelPoint(ctx) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| startTime := ctx.Int64("start_time") | ||
| endTime := ctx.Int64("end_time") | ||
| if startTime < 0 || endTime < 0 { | ||
| return fmt.Errorf("start_time and end_time must be >= 0") | ||
| } | ||
| if endTime != 0 && startTime > endTime { | ||
| return fmt.Errorf("start_time must be <= end_time") | ||
| } | ||
|
|
||
| req := &frdrpc.ChannelEventsRequest{ | ||
| ChanPoint: outpoint.String(), | ||
| StartTime: startTime, | ||
| EndTime: endTime, | ||
| MaxEvents: uint32(ctx.Uint("max_events")), | ||
| LastId: ctx.Int64("last_id"), | ||
| } | ||
|
|
||
| rpcCtx := context.Background() | ||
| report, err := client.GetChannelEvents(rpcCtx, req) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| printRespJSON(report) | ||
| return nil | ||
| } |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -21,5 +21,9 @@ INSERT INTO channel_events ( | |
|
|
||
| -- name: GetChannelEvents :many | ||
| SELECT * FROM channel_events | ||
| WHERE channel_id = $1 AND timestamp >= $2 AND timestamp < $3 | ||
| ORDER BY timestamp ASC, id ASC; | ||
| WHERE channel_id = $1 | ||
| AND id > $2 | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In general this PR looks great, so I think this is my main comment for the PR: I think the offset approach is much more common, and is what we use in Would therefore be interesting to hear your motivation behind this approach, which I do see some pros with as well!
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good point. Previously I had time-based pagination, but that didn't work well because of timestamp precision. I didn't really consider offset pagination, but a good point that this would be more consistent with other projects and doesn't expose internal state. However, I see that in the future we may want to delete older events, because I expect a constant stream of updates. In a new terminal web feature I think we also want to sync balances. With deletion I guess that it's easier to maintain the sync state by using the id. Let me know if you prefer the offset way, though I think the id approach has also speed advantages.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, ultimately I'll let you decide on which approach you'd want to use! Personally I have no strong preference. I do think the But ultimately I think there are pros with the current approach as well, so I'll let you decide :)
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, I thought about it a bit more, I'd accept the small implementation leak for the performance and for incremental sync that survives head deletions (which I think isn't possible in a straightforward manner with an offset unless one introduces an additional absolute sync watermark value like a timestamp). Thanks for the input here! |
||
| AND timestamp >= $3 | ||
| AND timestamp < $4 | ||
| ORDER BY id ASC | ||
| LIMIT $5; | ||
Uh oh!
There was an error while loading. Please reload this page.