cmd/lncli: add fwdinghistory support for relative times
- introduces new parser in `cmd/lncli/arg_parse.go` - converts start_time and end_time flags to strings - adds default value for end_time
This commit is contained in:
parent
03b20cabd2
commit
20b42ce261
40
cmd/lncli/arg_parse.go
Normal file
40
cmd/lncli/arg_parse.go
Normal file
@ -0,0 +1,40 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
// reTimeRange matches systemd.time-like short negative timeranges, e.g. "-200s".
|
||||
var reTimeRange = regexp.MustCompile(`^-\d{1,18}[s|m|h|d|w|M|y]$`)
|
||||
|
||||
// secondsPer allows translating s(seconds), m(minutes), h(ours), d(ays),
|
||||
// w(eeks), M(onths) and y(ears) into corresponding seconds.
|
||||
var secondsPer = map[string]int64{
|
||||
"s": 1,
|
||||
"m": 60,
|
||||
"h": 3600,
|
||||
"d": 86400,
|
||||
"w": 604800,
|
||||
"M": 2630016, // 30.44 days
|
||||
"y": 31557600, // 365.25 days
|
||||
}
|
||||
|
||||
// parseTime parses UNIX timestamps or short timeranges inspired by sytemd (when starting with "-"),
|
||||
// e.g. "-1M" for one month (30.44 days) ago.
|
||||
func parseTime(s string, base time.Time) (uint64, error) {
|
||||
if reTimeRange.MatchString(s) {
|
||||
last := len(s) - 1
|
||||
|
||||
d, err := strconv.ParseInt(s[1:last], 10, 64)
|
||||
if err != nil {
|
||||
return uint64(0), err
|
||||
}
|
||||
|
||||
mul := secondsPer[string(s[last])]
|
||||
return uint64(base.Unix() - d*mul), nil
|
||||
}
|
||||
|
||||
return strconv.ParseUint(s, 10, 64)
|
||||
}
|
88
cmd/lncli/arg_parse_test.go
Normal file
88
cmd/lncli/arg_parse_test.go
Normal file
@ -0,0 +1,88 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
var now = time.Date(2017, 11, 10, 7, 8, 9, 1234, time.UTC)
|
||||
|
||||
var partTimeTests = []struct {
|
||||
in string
|
||||
expected uint64
|
||||
errExpected bool
|
||||
}{
|
||||
{
|
||||
"12345",
|
||||
uint64(12345),
|
||||
false,
|
||||
},
|
||||
{
|
||||
"-0s",
|
||||
uint64(now.Unix()),
|
||||
false,
|
||||
},
|
||||
{
|
||||
"-1s",
|
||||
uint64(time.Date(2017, 11, 10, 7, 8, 8, 1234, time.UTC).Unix()),
|
||||
false,
|
||||
},
|
||||
{
|
||||
"-2h",
|
||||
uint64(time.Date(2017, 11, 10, 5, 8, 9, 1234, time.UTC).Unix()),
|
||||
false,
|
||||
},
|
||||
{
|
||||
"-3d",
|
||||
uint64(time.Date(2017, 11, 7, 7, 8, 9, 1234, time.UTC).Unix()),
|
||||
false,
|
||||
},
|
||||
{
|
||||
"-4w",
|
||||
uint64(time.Date(2017, 10, 13, 7, 8, 9, 1234, time.UTC).Unix()),
|
||||
false,
|
||||
},
|
||||
{
|
||||
"-5M",
|
||||
uint64(now.Unix() - 30.44*5*24*60*60),
|
||||
false,
|
||||
},
|
||||
{
|
||||
"-6y",
|
||||
uint64(now.Unix() - 365.25*6*24*60*60),
|
||||
false,
|
||||
},
|
||||
{
|
||||
"-999999999999999999s",
|
||||
uint64(now.Unix() - 999999999999999999),
|
||||
false,
|
||||
},
|
||||
{
|
||||
"-9999999999999999991s",
|
||||
0,
|
||||
true,
|
||||
},
|
||||
{
|
||||
"-7z",
|
||||
0,
|
||||
true,
|
||||
},
|
||||
}
|
||||
|
||||
// Test that parsing absolute and relative times works.
|
||||
func TestParseTime(t *testing.T) {
|
||||
for _, test := range partTimeTests {
|
||||
actual, err := parseTime(test.in, now)
|
||||
if test.errExpected == (err == nil) {
|
||||
t.Fatalf("unexpected error for %s:\n%v\n", test.in, err)
|
||||
}
|
||||
if actual != test.expected {
|
||||
t.Fatalf(
|
||||
"for %s actual and expected do not match:\n%d\n%d\n",
|
||||
test.in,
|
||||
actual,
|
||||
test.expected,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
@ -2708,9 +2708,12 @@ var forwardingHistoryCommand = cli.Command{
|
||||
Query the HTLC switch's internal forwarding log for all completed
|
||||
payment circuits (HTLCs) over a particular time range (--start_time and
|
||||
--end_time). The start and end times are meant to be expressed in
|
||||
seconds since the Unix epoch. If --start_time isn't provided,
|
||||
then 24 hours ago is used. If --end_time isn't provided,
|
||||
then the current time is used.
|
||||
seconds since the Unix epoch.
|
||||
Alternatively negative time ranges can be used, e.g. "-3d". Supports
|
||||
s(seconds), m(minutes), h(ours), d(ays), w(eeks), M(onths), y(ears).
|
||||
Month equals 30.44 days, year equals 365.25 days.
|
||||
If --start_time isn't provided, then 24 hours ago is used. If
|
||||
--end_time isn't provided, then the current time is used.
|
||||
|
||||
The max number of events returned is 50k. The default number is 100,
|
||||
callers can use the --max_events param to modify this value.
|
||||
@ -2720,15 +2723,15 @@ var forwardingHistoryCommand = cli.Command{
|
||||
entry. Using this callers can manually paginate within a time slice.
|
||||
`,
|
||||
Flags: []cli.Flag{
|
||||
cli.Int64Flag{
|
||||
cli.StringFlag{
|
||||
Name: "start_time",
|
||||
Usage: "the starting time for the query, expressed in " +
|
||||
"seconds since the unix epoch",
|
||||
Usage: "the starting time for the query " +
|
||||
`as unix timestamp or relative e.g. "-1w"`,
|
||||
},
|
||||
cli.Int64Flag{
|
||||
cli.StringFlag{
|
||||
Name: "end_time",
|
||||
Usage: "the end time for the query, expressed in " +
|
||||
"seconds since the unix epoch",
|
||||
Usage: "the end time for the query " +
|
||||
`as unix timestamp or relative e.g. "-1w"`,
|
||||
},
|
||||
cli.Int64Flag{
|
||||
Name: "index_offset",
|
||||
@ -2753,30 +2756,33 @@ func forwardingHistory(ctx *cli.Context) error {
|
||||
err error
|
||||
)
|
||||
args := ctx.Args()
|
||||
now := time.Now()
|
||||
|
||||
switch {
|
||||
case ctx.IsSet("start_time"):
|
||||
startTime = ctx.Uint64("start_time")
|
||||
startTime, err = parseTime(ctx.String("start_time"), now)
|
||||
case args.Present():
|
||||
startTime, err = strconv.ParseUint(args.First(), 10, 64)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to decode start_time %v", err)
|
||||
}
|
||||
startTime, err = parseTime(args.First(), now)
|
||||
args = args.Tail()
|
||||
default:
|
||||
now := time.Now()
|
||||
startTime = uint64(now.Add(-time.Hour * 24).Unix())
|
||||
}
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to decode start_time: %v", err)
|
||||
}
|
||||
|
||||
switch {
|
||||
case ctx.IsSet("end_time"):
|
||||
endTime = ctx.Uint64("end_time")
|
||||
endTime, err = parseTime(ctx.String("end_time"), now)
|
||||
case args.Present():
|
||||
endTime, err = strconv.ParseUint(args.First(), 10, 64)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to decode end_time: %v", err)
|
||||
}
|
||||
endTime, err = parseTime(args.First(), now)
|
||||
args = args.Tail()
|
||||
default:
|
||||
endTime = uint64(now.Unix())
|
||||
}
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to decode end_time: %v", err)
|
||||
}
|
||||
|
||||
switch {
|
||||
|
Loading…
Reference in New Issue
Block a user